From 1d06821736e6b70d997154d3ce71620523897eec Mon Sep 17 00:00:00 2001 From: Nitwel Date: Sun, 26 Nov 2023 02:01:27 +0100 Subject: [PATCH] add media player --- content/entities/media_player/media_player.gd | 74 +++++++++++++++++++ .../entities/media_player/media_player.tscn | 55 ++++++++++++-- content/ui/menu/edit/entity_creator.gd | 3 + content/ui/menu/room/room_menu.gd | 2 + export_presets.cfg | 2 +- export_presets_prod.cfg | 2 +- lib/home_apis/hass_ws/hass.gd | 9 +++ 7 files changed, 139 insertions(+), 8 deletions(-) create mode 100644 content/entities/media_player/media_player.gd diff --git a/content/entities/media_player/media_player.gd b/content/entities/media_player/media_player.gd new file mode 100644 index 0000000..4defe33 --- /dev/null +++ b/content/entities/media_player/media_player.gd @@ -0,0 +1,74 @@ +extends StaticBody3D + +@export var entity_id = "media_player.bedroomspeaker" + +@onready var previous = $Previous +@onready var next = $Next +@onready var play = $Play +@onready var logo = $PlayingInfo/Logo +@onready var title = $PlayingInfo/Title +@onready var artist = $PlayingInfo/Artist +@onready var http_request = $PlayingInfo/HTTPRequest + +var playing = false + +# Called when the node enters the scene tree for the first time. +func _ready(): + var stateInfo = await HomeApi.get_state(entity_id) + set_state(stateInfo) + + await HomeApi.watch_state(entity_id, func(new_state): + set_state(new_state) + ) + + previous.on_button_down.connect(func(): + HomeApi.set_state(entity_id, "previous") + ) + + play.on_button_down.connect(func(): + if playing: + HomeApi.set_state(entity_id, "pause") + else: + HomeApi.set_state(entity_id, "play") + ) + + next.on_button_down.connect(func(): + HomeApi.set_state(entity_id, "next") + ) + + +func set_state(stateInfo): + var state = stateInfo["state"] + + print("State changed to ", stateInfo) + + if state == "playing": + if stateInfo["attributes"].has("entity_picture_local"): + load_image(stateInfo["attributes"]["entity_picture_local"]) + title.text = stateInfo["attributes"]["media_title"] + artist.text = stateInfo["attributes"]["media_artist"] + + playing = true + play.label = "pause" + else: + playing = false + play.label = "play_arrow" + +func load_image(url: String): + http_request.request("http://192.168.33.33:8123" + url) + + var result = await http_request.request_completed + + if result[0] != HTTPRequest.RESULT_SUCCESS: + print("Error loading image: ", result[0], " ", result[1]) + return + + var image = Image.new() + var error = image.load_jpg_from_buffer(result[3]) + + if error != OK: + print("Error loading image: ", error) + return + + var texture = ImageTexture.create_from_image(image) + logo.texture = texture diff --git a/content/entities/media_player/media_player.tscn b/content/entities/media_player/media_player.tscn index 9acf581..a3683e9 100644 --- a/content/entities/media_player/media_player.tscn +++ b/content/entities/media_player/media_player.tscn @@ -1,14 +1,57 @@ -[gd_scene load_steps=2 format=3 uid="uid://dyktdg7ggiwl4"] +[gd_scene load_steps=5 format=3 uid="uid://dyktdg7ggiwl4"] [ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="1_8opk3"] +[ext_resource type="Script" path="res://content/entities/media_player/media_player.gd" id="1_ame17"] +[ext_resource type="Script" path="res://content/functions/movable.gd" id="3_bguto"] -[node name="Node3D" type="Node3D"] +[sub_resource type="BoxShape3D" id="BoxShape3D_vi3eg"] +size = Vector3(0.23, 0.07, 0.01) -[node name="Button" parent="." instance=ExtResource("1_8opk3")] -transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, -4.65661e-08, 0, 0) +[node name="MediaPlayer" type="StaticBody3D"] +script = ExtResource("1_ame17") -[node name="Button2" parent="." instance=ExtResource("1_8opk3")] +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.01) +shape = SubResource("BoxShape3D_vi3eg") + +[node name="Previous" parent="." instance=ExtResource("1_8opk3")] transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, -0.07, 0, 0) +label = "skip_previous" +icon = true -[node name="Button3" parent="." instance=ExtResource("1_8opk3")] +[node name="Play" parent="." instance=ExtResource("1_8opk3")] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, -4.65661e-08, 0, 0) +label = "pause" +icon = true + +[node name="Next" parent="." instance=ExtResource("1_8opk3")] transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0.07, 0, 0) +label = "skip_next" +icon = true + +[node name="PlayingInfo" type="Node3D" parent="."] + +[node name="Title" type="Label3D" parent="PlayingInfo"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.09, 0.07, 0) +pixel_size = 0.001 +text = "All Falls Down" +font_size = 24 +outline_size = 4 +horizontal_alignment = 0 + +[node name="Artist" type="Label3D" parent="PlayingInfo"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.09, 0.05, 0) +pixel_size = 0.001 +text = "Alan Walker" +font_size = 16 +outline_size = 4 +horizontal_alignment = 0 + +[node name="Logo" type="Sprite3D" parent="PlayingInfo"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.15, 0) +pixel_size = 0.001 + +[node name="HTTPRequest" type="HTTPRequest" parent="PlayingInfo"] + +[node name="Movable" type="Node" parent="."] +script = ExtResource("3_bguto") diff --git a/content/ui/menu/edit/entity_creator.gd b/content/ui/menu/edit/entity_creator.gd index 94d57ab..61093a6 100644 --- a/content/ui/menu/edit/entity_creator.gd +++ b/content/ui/menu/edit/entity_creator.gd @@ -3,6 +3,7 @@ extends Object const Switch = preload("res://content/entities/switch/switch.tscn") const Light = preload("res://content/entities/light/light.tscn") const Sensor = preload("res://content/entities/sensor/sensor.tscn") +const MediaPlayer = preload("res://content/entities/media_player/media_player.tscn") static func create_entity(type: String, id: String): var entity = null @@ -14,6 +15,8 @@ static func create_entity(type: String, id: String): entity = Light.instantiate() "sensor": entity = Sensor.instantiate() + "media_player": + entity = MediaPlayer.instantiate() _: return null diff --git a/content/ui/menu/room/room_menu.gd b/content/ui/menu/room/room_menu.gd index 4afbfb6..9e1eddd 100644 --- a/content/ui/menu/room/room_menu.gd +++ b/content/ui/menu/room/room_menu.gd @@ -4,6 +4,7 @@ const wall_corner_scene = preload("./wall_corner.tscn") const wall_edge_scene = preload("./wall_edge.tscn") @onready var teleport_root = $TeleportRoot +@onready var background = $Background @onready var wall_corners = $TeleportRoot/WallCorners @onready var wall_edges = $TeleportRoot/WallEdges @onready var wall_mesh = $TeleportRoot/WallMesh @@ -16,6 +17,7 @@ var edit_enabled = false func _ready(): remove_child(teleport_root) + background.visible = false get_tree().get_root().get_node("Main").add_child.call_deferred(teleport_root) teleport_root.get_node("Ground/Clickable").on_click.connect(func(event): diff --git a/export_presets.cfg b/export_presets.cfg index b664e50..079a9ed 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -6,7 +6,7 @@ runnable=true dedicated_server=false custom_features="" export_filter="all_resources" -include_filter="*.j2" +include_filter="*.j2,*.woff2" exclude_filter="" export_path="builds/android/immersive-home.apk" encryption_include_filters="" diff --git a/export_presets_prod.cfg b/export_presets_prod.cfg index c12f50f..925ce4e 100644 --- a/export_presets_prod.cfg +++ b/export_presets_prod.cfg @@ -6,7 +6,7 @@ runnable=false dedicated_server=false custom_features="" export_filter="all_resources" -include_filter="*.j2" +include_filter="*.j2,*.woff2" exclude_filter="" export_path="builds/android/immersive-home.apk" encryption_include_filters="" diff --git a/lib/home_apis/hass_ws/hass.gd b/lib/home_apis/hass_ws/hass.gd index b163183..16cd3a1 100644 --- a/lib/home_apis/hass_ws/hass.gd +++ b/lib/home_apis/hass_ws/hass.gd @@ -245,6 +245,15 @@ func set_state(entity: String, state: String, attributes: Dictionary = {}): service = 'turn_on' elif state == 'off': service = 'turn_off' + elif domain == 'media_player': + if state == 'play': + service = 'media_play' + elif state == "pause": + service = "media_pause" + elif state == "next": + service = "media_next_track" + elif state == "previous": + service = "media_previous_track" if service == null: return null