diff --git a/addons/gde_gozen/README.md b/addons/gde_gozen/README.md index 7cb66875..8910044d 100644 --- a/addons/gde_gozen/README.md +++ b/addons/gde_gozen/README.md @@ -9,6 +9,9 @@ To see video files in your projects file tree, you need to add `mp4` and any oth 1. When exporting, you'll have your executable and the GDE GoZen library file, these do need to be both shared for the application to work. 2. Also, you will have to add `*.mp4` and other extension names of your video files to the resources which need to get exported for each platform you want to export for, otherwise your video files will not be included in your final export. +## Android (SAF) +Due to the way SAF works (Godot 4.6+), accessing files through the browser might give invalid paths. You need to be certain you get the absolute path instead. Inside of the `test_room` you can find an example of how this is done for Android, by basically copying the videos to a temporary folder which will give an absolute path. Only thing to be careful of is to also remove the data afterwards out of the temporary folder. + ## Help needed? You can go to the [GitHub repo](https://github.com/VoylinsGamedevJourney/gde_gozen/issues) to report problems, or visit out [Discord server](discord.gg/BdbUf7VKYC) for help/advice. diff --git a/addons/gde_gozen/bin/libgozen.android.template_debug.arm32.so b/addons/gde_gozen/bin/libgozen.android.template_debug.arm32.so index 29b73292..14d5d2ea 100644 Binary files a/addons/gde_gozen/bin/libgozen.android.template_debug.arm32.so and b/addons/gde_gozen/bin/libgozen.android.template_debug.arm32.so differ diff --git a/addons/gde_gozen/bin/libgozen.android.template_debug.arm64.so b/addons/gde_gozen/bin/libgozen.android.template_debug.arm64.so index eb0da7fb..32f38fb1 100644 Binary files a/addons/gde_gozen/bin/libgozen.android.template_debug.arm64.so and b/addons/gde_gozen/bin/libgozen.android.template_debug.arm64.so differ diff --git a/addons/gde_gozen/bin/libgozen.android.template_release.arm32.so b/addons/gde_gozen/bin/libgozen.android.template_release.arm32.so index 2828a082..9ac39376 100644 Binary files a/addons/gde_gozen/bin/libgozen.android.template_release.arm32.so and b/addons/gde_gozen/bin/libgozen.android.template_release.arm32.so differ diff --git a/addons/gde_gozen/bin/libgozen.android.template_release.arm64.so b/addons/gde_gozen/bin/libgozen.android.template_release.arm64.so index 5282fe15..59a1c94d 100644 Binary files a/addons/gde_gozen/bin/libgozen.android.template_release.arm64.so and b/addons/gde_gozen/bin/libgozen.android.template_release.arm64.so differ diff --git a/addons/gde_gozen/bin/libgozen.linux.template_debug.arm64.so b/addons/gde_gozen/bin/libgozen.linux.template_debug.arm64.so index 428399bc..81e0069d 100644 Binary files a/addons/gde_gozen/bin/libgozen.linux.template_debug.arm64.so and b/addons/gde_gozen/bin/libgozen.linux.template_debug.arm64.so differ diff --git a/addons/gde_gozen/bin/libgozen.linux.template_debug.x86_64.so b/addons/gde_gozen/bin/libgozen.linux.template_debug.x86_64.so index ff4477ad..2cc0c680 100644 Binary files a/addons/gde_gozen/bin/libgozen.linux.template_debug.x86_64.so and b/addons/gde_gozen/bin/libgozen.linux.template_debug.x86_64.so differ diff --git a/addons/gde_gozen/bin/libgozen.linux.template_release.arm64.so b/addons/gde_gozen/bin/libgozen.linux.template_release.arm64.so index c0dc2273..8afad0bd 100644 Binary files a/addons/gde_gozen/bin/libgozen.linux.template_release.arm64.so and b/addons/gde_gozen/bin/libgozen.linux.template_release.arm64.so differ diff --git a/addons/gde_gozen/bin/libgozen.linux.template_release.x86_64.so b/addons/gde_gozen/bin/libgozen.linux.template_release.x86_64.so index d7c47f81..e654ab1d 100644 Binary files a/addons/gde_gozen/bin/libgozen.linux.template_release.x86_64.so and b/addons/gde_gozen/bin/libgozen.linux.template_release.x86_64.so differ diff --git a/addons/gde_gozen/bin/libgozen.windows.template_debug.x86_64.dll b/addons/gde_gozen/bin/libgozen.windows.template_debug.x86_64.dll index f8a291a4..e5c6fefa 100644 Binary files a/addons/gde_gozen/bin/libgozen.windows.template_debug.x86_64.dll and b/addons/gde_gozen/bin/libgozen.windows.template_debug.x86_64.dll differ diff --git a/addons/gde_gozen/bin/libgozen.windows.template_release.x86_64.dll b/addons/gde_gozen/bin/libgozen.windows.template_release.x86_64.dll index afeb74da..18e39e55 100644 Binary files a/addons/gde_gozen/bin/libgozen.windows.template_release.x86_64.dll and b/addons/gde_gozen/bin/libgozen.windows.template_release.x86_64.dll differ diff --git a/addons/gde_gozen/icon.svg.import b/addons/gde_gozen/icon.svg.import index 6b4a127a..7cf320f7 100644 --- a/addons/gde_gozen/icon.svg.import +++ b/addons/gde_gozen/icon.svg.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://bijjjb1qmqf7f" +uid="uid://dcpha8teexb00" path="res://.godot/imported/icon.svg-ac53c9c419a88eda808214a4d44243c3.ctex" metadata={ "vram_texture": false diff --git a/addons/gde_gozen/icon.webp.import b/addons/gde_gozen/icon.webp.import index 075b07c1..b6d1f905 100644 --- a/addons/gde_gozen/icon.webp.import +++ b/addons/gde_gozen/icon.webp.import @@ -2,7 +2,7 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dbk4jierdjfrf" +uid="uid://bndqydg778xif" path="res://.godot/imported/icon.webp-a5a23a9a73b8ba8140cf260e6bfffac7.ctex" metadata={ "vram_texture": false diff --git a/addons/gde_gozen/plugin.cfg b/addons/gde_gozen/plugin.cfg index 59c444d1..d8237a49 100644 --- a/addons/gde_gozen/plugin.cfg +++ b/addons/gde_gozen/plugin.cfg @@ -3,5 +3,5 @@ name="gde_gozen" description="Providing performant video playback." author="Voylin's Gamedev Journey" -version="v9.1" +version="v9.2" script="plugin.gd" diff --git a/addons/gde_gozen/video_playback.gd b/addons/gde_gozen/video_playback.gd index 5bb93944..68e38949 100644 --- a/addons/gde_gozen/video_playback.gd +++ b/addons/gde_gozen/video_playback.gd @@ -107,14 +107,12 @@ func _exit_tree() -> void: # Making certain no remaining tasks are running in separate threads. if _video_thread != -1: var error: int = WorkerThreadPool.wait_for_task_completion(_video_thread) - if error != OK: printerr("Something went wrong waiting for task completion! %s" % error) _video_thread = -1 - if video != null: close() - + AudioServer.remove_bus(AudioServer.get_bus_index(audio_player.bus)) @@ -129,7 +127,6 @@ func _ready() -> void: func set_video_path(new_path: String) -> void: if video != null: close() - if !is_node_ready(): await ready if !get_tree().root.is_node_ready(): @@ -144,28 +141,29 @@ func set_video_path(new_path: String) -> void: path = new_path video = GoZenVideo.new() - if debug: video.enable_debug() else: video.disable_debug() _video_thread = WorkerThreadPool.add_task(_open_video) - if enable_audio: _open_audio() ## Update the video manually by providing a GoZenVideo instance and an optional AudioStreamWAV. -func update_video(video_instance: GoZenVideo) -> void: +func update_video(video_instance: GoZenVideo, audio_stream: AudioStreamWAV = null) -> void: if video != null: close() - + path = video_instance.get_path() _update_video(video_instance) - _open_audio() + if audio_stream: + audio_player.stream = audio_stream + else: + _open_audio() -## Only run this function after manually having added a Video object to the `video` variable. A good reason for doing this is to load your video's at startup time to prevent your program for freezing for a second when loading in big video files. Some video formats load faster then others so if you are experiencing issues with long loading times, try to use this function and create the video object on startup, or try switching the video format which you are using. +## Only run this function after manually having added a Video object to the `video` variable. A good reason for doing this is to load your video's at startup time to prevent your program for freezing for a second when loading in big video files. Some video formats load faster then others so if you are experiencing issues with long loading times, try to use this function and create the video object on startup, or try switching the video format which you are using. func _update_video(new_video: GoZenVideo) -> void: video = new_video if !is_open(): @@ -189,7 +187,7 @@ func _update_video(new_video: GoZenVideo) -> void: video_streams = video.get_streams(STREAM_TYPE.VIDEO) audio_streams = video.get_streams(STREAM_TYPE.AUDIO) subtitle_streams = video.get_streams(STREAM_TYPE.SUBTITLE) - + chapters.clear() for i: int in range(video.get_chapter_count()): @warning_ignore("UNSAFE_CALL_ARGUMENT") @@ -199,14 +197,13 @@ func _update_video(new_video: GoZenVideo) -> void: video.get_chapter_metadata(i).get("title", "") ) chapters.append(chapter) - + if abs(_rotation) == 90: image = Image.create_empty(_resolution.y, _resolution.x, false, Image.FORMAT_R8) else: image = Image.create_empty(_resolution.x, _resolution.y, false, Image.FORMAT_R8) image.fill(Color.WHITE) - if debug: _print_video_debug() @@ -240,7 +237,6 @@ func _set_color_profile(new_profile: COLOR_PROFILE = color_profile) -> void: var profile_str: String = video.get_color_profile() color_profile = new_profile - if new_profile != COLOR_PROFILE.AUTO: profile_str = str(COLOR_PROFILE.find_key(COLOR_PROFILE.BT2100)).to_lower() @@ -248,7 +244,6 @@ func _set_color_profile(new_profile: COLOR_PROFILE = color_profile) -> void: "bt2020", "bt2100": color_data = Vector4(1.4746, 0.16455, 0.57135, 1.8814) "bt601", "bt470": color_data = Vector4(1.402, 0.344136, 0.714136, 1.772) _: color_data = Vector4(1.5748, 0.1873, 0.4681, 1.8556) # bt709 and unknown - _shader_material.set_shader_parameter("color_profile", color_data) @@ -277,12 +272,11 @@ func next_frame(skip: bool = false) -> void: elif !skip: print("Something went wrong getting next frame!") - + func close() -> void: if video != null: if is_playing: pause() - video = null @@ -291,7 +285,6 @@ func _process(delta: float) -> void: if is_playing: _skips = 0 _time_elapsed += delta - if _time_elapsed < _frame_time: return @@ -302,39 +295,36 @@ func _process(delta: float) -> void: if current_frame >= _frame_count: is_playing = !is_playing - if enable_audio and audio_player.stream != null: audio_player.set_stream_paused(true) video_ended.emit() - if loop: seek_frame(0) play() else: _sync_audio_video() - while _skips != 1: next_frame(true) _skips -= 1 next_frame() elif _video_thread != -1: var error: int = WorkerThreadPool.wait_for_task_completion(_video_thread) - if error != OK: printerr("Something went wrong waiting for task completion! %s" % error) _video_thread = -1 _update_video(video) - if enable_auto_play: play() ## Start the video playback. This will play until reaching the end of the video and then pause and go back to the start. func play() -> void: - if video != null and !is_open() and is_playing: + if not is_open(): + print("The video on '%s' isn't open yet!" % path) return + if is_playing: return is_playing = true if enable_audio and audio_player.stream.get_length() != 0: @@ -348,10 +338,8 @@ func play() -> void: ## Pausing the video. func pause() -> void: is_playing = false - if enable_audio and audio_player.stream != null: audio_player.set_stream_paused(true) - playback_paused.emit() @@ -361,7 +349,6 @@ func _sync_audio_video() -> void: return elif enable_audio and audio_player.stream.get_length() != 0: var audio_offset: float = audio_player.get_playback_position() + AudioServer.get_time_since_last_mix() - (current_frame + 1) / _frame_rate - if abs(audio_player.get_playback_position() + AudioServer.get_time_since_last_mix() - (current_frame + 1) / _frame_rate) > AUDIO_OFFSET_THRESHOLD: if debug: print("Audio Sync: time correction: ", audio_offset) audio_player.seek((current_frame + 1) / _frame_rate) @@ -451,7 +438,6 @@ func _set_frame_image() -> void: RenderingServer.texture_2d_update(y_texture.get_rid(), video.get_y_data(), 0) RenderingServer.texture_2d_update(u_texture.get_rid(), video.get_u_data(), 0) RenderingServer.texture_2d_update(v_texture.get_rid(), video.get_v_data(), 0) - if _has_alpha: RenderingServer.texture_2d_update(a_texture.get_rid(), video.get_a_data(), 0) @@ -463,7 +449,6 @@ func set_playback_speed(new_playback_value: float) -> void: if enable_audio and audio_player.stream != null: audio_player.pitch_scale = playback_speed _set_pitch_adjust() - if is_playing: audio_player.play(current_frame * (1.0 / _frame_rate)) @@ -484,7 +469,7 @@ func set_audio_stream(stream: int) -> void: if not is_open(): printerr("Video is not open!") return - + if not stream in audio_streams: printerr("Invalid audio stream!") return @@ -521,7 +506,7 @@ func _open_audio(stream_id: int = -1) -> void: printerr("Failed to open AudioStreamFFmpeg for: %s" % path) return - audio_player.set_stream.call_deferred(stream) + audio_player.stream = stream func _print_stream_info(streams: PackedInt32Array) -> void: @@ -565,24 +550,21 @@ func _print_video_debug() -> void: print("Using sws: ", video.is_using_sws()) print("Sar: ", video.get_sar()) - if video_streams.size() != 0: - print_rich("Video streams: [i](%s)" % video_streams.size()) - _print_stream_info(video_streams) - else: - print("No video streams found.") + print_rich("Video streams: [i](%s)" % video_streams.size()) + _print_stream_info(video_streams) if audio_streams.size() != 0: print_rich("Audio streams: [i](%s)" % audio_streams.size()) _print_stream_info(audio_streams) - else: + elif debug: print("No audio streams found.") if subtitle_streams.size() != 0: print_rich("Subtitle streams: [i](%s)" % subtitle_streams.size()) _print_stream_info(subtitle_streams) - else: + elif debug: print("No subtitle streams found.") - + if chapters.size() != 0: print_rich("Chapters: [i](%s)" % chapters.size()) for i: int in range(chapters.size()):