From 3f3f435d2ea00a01bfd0b2aee13eb11a207b239a Mon Sep 17 00:00:00 2001 From: Gustl22 Date: Fri, 18 Aug 2023 13:13:09 +0200 Subject: [PATCH] feat: Release source for Web, Linux, Windows (#1517) # Description Release sources in `Release` mode, when source is `completed`. ## Related Issues Closes #1537 (cherry picked from commit 09496dcbf478af330e37be833184439b43b5ac44) --- feature_parity_table.md | 2 +- .../audioplayers_linux/linux/audio_player.cc | 20 +++++++++++------ .../audioplayers_linux/linux/audio_player.h | 2 ++ .../linux/audioplayers_linux_plugin.cc | 3 +-- .../audioplayers_web/lib/wrapped_player.dart | 22 ++++++++----------- .../windows/MediaEngineExtension.cpp | 2 +- .../windows/MediaEngineWrapper.cpp | 5 +++++ .../windows/MediaEngineWrapper.h | 3 +++ .../windows/audio_player.cpp | 10 +++++++-- .../windows/audio_player.h | 2 ++ .../windows/audioplayers_windows_plugin.cpp | 3 +-- 11 files changed, 46 insertions(+), 28 deletions(-) diff --git a/feature_parity_table.md b/feature_parity_table.md index cd1e4281c..0f55fdd71 100644 --- a/feature_parity_table.md +++ b/feature_parity_table.md @@ -38,7 +38,7 @@ Note: LLM means Low Latency Mode. low latency modeSDK >=21nonononono Audio Control Commands resume / pause / stopyesyesyesyesyesyes - releaseyesyes (no mode)yes (no mode)yes (no mode)not yetnot yet + releaseyesyes (no mode)yes (no mode)yes (no mode)yes (no mode)yes (no mode) loopyesyesyesyesyesyes volumeyesyesyesyesyesyes seekyesyesyesyesyesyes diff --git a/packages/audioplayers_linux/linux/audio_player.cc b/packages/audioplayers_linux/linux/audio_player.cc index 7c4b07918..19e79b782 100644 --- a/packages/audioplayers_linux/linux/audio_player.cc +++ b/packages/audioplayers_linux/linux/audio_player.cc @@ -77,6 +77,18 @@ void AudioPlayer::SetSourceUrl(std::string url) { } } +void AudioPlayer::ReleaseMediaSource() { + if(_isPlaying) _isPlaying = false; + if(_isInitialized) _isInitialized = false; + _url.clear(); + + GstState playbinState; + gst_element_get_state(playbin, &playbinState, NULL, GST_CLOCK_TIME_NONE); + if(playbinState > GST_STATE_NULL) { + gst_element_set_state(playbin, GST_STATE_NULL); + } +} + gboolean AudioPlayer::OnBusMessage(GstBus *bus, GstMessage *message, AudioPlayer *data) { switch (GST_MESSAGE_TYPE(message)) { @@ -413,8 +425,7 @@ void AudioPlayer::Resume() { void AudioPlayer::Dispose() { if(!playbin) throw "Player was already disposed (Dispose)"; - if(_isPlaying) _isPlaying = false; - if(_isInitialized) _isInitialized = false; + ReleaseMediaSource(); g_source_remove(_refreshId); @@ -440,11 +451,6 @@ void AudioPlayer::Dispose() { panorama = nullptr; } - GstState playbinState; - gst_element_get_state(playbin, &playbinState, NULL, GST_CLOCK_TIME_NONE); - if(playbinState > GST_STATE_NULL) { - gst_element_set_state(playbin, GST_STATE_NULL); - } gst_object_unref(GST_OBJECT(playbin)); // Do not dispose method channel as it is used by multiple players! g_clear_object(&_eventChannel); diff --git a/packages/audioplayers_linux/linux/audio_player.h b/packages/audioplayers_linux/linux/audio_player.h index 3a81aa2f6..312d2efeb 100644 --- a/packages/audioplayers_linux/linux/audio_player.h +++ b/packages/audioplayers_linux/linux/audio_player.h @@ -51,6 +51,8 @@ class AudioPlayer { void SetSourceUrl(std::string url); + void ReleaseMediaSource(); + void OnError(const gchar *code, const gchar *message, FlValue *details, GError **error); diff --git a/packages/audioplayers_linux/linux/audioplayers_linux_plugin.cc b/packages/audioplayers_linux/linux/audioplayers_linux_plugin.cc index 5f42282f3..c478bd0bb 100644 --- a/packages/audioplayers_linux/linux/audioplayers_linux_plugin.cc +++ b/packages/audioplayers_linux/linux/audioplayers_linux_plugin.cc @@ -139,8 +139,7 @@ static void audioplayers_linux_plugin_handle_method_call( player->Pause(); player->SetPosition(0); } else if (strcmp(method, "release") == 0) { - player->Pause(); - player->SetPosition(0); + player->ReleaseMediaSource(); } else if (strcmp(method, "seek") == 0) { auto flPosition = fl_value_lookup_string(args, "position"); int position = flPosition == nullptr ? (int)(player->GetPosition().value_or(0)) diff --git a/packages/audioplayers_web/lib/wrapped_player.dart b/packages/audioplayers_web/lib/wrapped_player.dart index 17fe2d69e..ba58964d9 100644 --- a/packages/audioplayers_web/lib/wrapped_player.dart +++ b/packages/audioplayers_web/lib/wrapped_player.dart @@ -40,7 +40,7 @@ class WrappedPlayer { } _currentUrl = url; - stop(); + release(); recreateNode(); if (_isPlaying) { await resume(); @@ -138,8 +138,11 @@ class WrappedPlayer { ); _playerEndedSubscription = p.onEnded.listen( (_) { - _pausedAt = 0; - p.currentTime = 0; + if (_currentReleaseMode == ReleaseMode.release) { + release(); + } else { + stop(); + } eventStreamController.add( const AudioEvent(eventType: AudioEventType.complete), ); @@ -167,10 +170,10 @@ class WrappedPlayer { } void release() { + stop(); // Release `AudioElement` correctly (#966) player?.src = ''; player?.remove(); - _cancel(); player = null; _stereoPanner = null; @@ -211,7 +214,7 @@ class WrappedPlayer { } void stop() { - _cancel(); + pause(); _pausedAt = 0; player?.currentTime = 0; } @@ -225,14 +228,6 @@ class WrappedPlayer { } } - void _cancel() { - _isPlaying = false; - player?.pause(); - if (_currentReleaseMode == ReleaseMode.release) { - player = null; - } - } - void log(String message) { eventStreamController.add( AudioEvent(eventType: AudioEventType.log, logMessage: message), @@ -240,6 +235,7 @@ class WrappedPlayer { } Future dispose() async { + release(); eventStreamController.close(); } } diff --git a/packages/audioplayers_windows/windows/MediaEngineExtension.cpp b/packages/audioplayers_windows/windows/MediaEngineExtension.cpp index 040a264f8..d0131cd91 100644 --- a/packages/audioplayers_windows/windows/MediaEngineExtension.cpp +++ b/packages/audioplayers_windows/windows/MediaEngineExtension.cpp @@ -106,4 +106,4 @@ void MediaEngineExtension::Shutdown() } } -} // namespace media \ No newline at end of file +} // namespace media diff --git a/packages/audioplayers_windows/windows/MediaEngineWrapper.cpp b/packages/audioplayers_windows/windows/MediaEngineWrapper.cpp index 333ea939f..eceed4f74 100644 --- a/packages/audioplayers_windows/windows/MediaEngineWrapper.cpp +++ b/packages/audioplayers_windows/windows/MediaEngineWrapper.cpp @@ -339,6 +339,11 @@ void MediaEngineWrapper::SetMediaSource(IMFMediaSource* mediaSource) { THROW_IF_FAILED(mediaEngineEx->SetSource(source.get())); } +void MediaEngineWrapper::ReleaseMediaSource() { + m_mediaEngineExtension->SetMediaSource(nullptr); + m_mediaEngine->SetSource(nullptr); +} + // Callback methods void MediaEngineWrapper::OnLoaded() diff --git a/packages/audioplayers_windows/windows/MediaEngineWrapper.h b/packages/audioplayers_windows/windows/MediaEngineWrapper.h index 8d85369e0..7a5bf0228 100644 --- a/packages/audioplayers_windows/windows/MediaEngineWrapper.h +++ b/packages/audioplayers_windows/windows/MediaEngineWrapper.h @@ -38,6 +38,9 @@ class MediaEngineWrapper : public winrt::implementsPause(); } + m_mediaEngineWrapper->ReleaseMediaSource(); + _isInitialized = false; +} + +void AudioPlayer::Dispose() { + ReleaseMediaSource(); + m_mediaEngineWrapper->Shutdown(); _methodChannel = nullptr; _eventHandler = nullptr; - _isInitialized = false; } void AudioPlayer::SetLooping(bool isLooping) { diff --git a/packages/audioplayers_windows/windows/audio_player.h b/packages/audioplayers_windows/windows/audio_player.h index 53396e505..27575353c 100644 --- a/packages/audioplayers_windows/windows/audio_player.h +++ b/packages/audioplayers_windows/windows/audio_player.h @@ -53,6 +53,8 @@ class AudioPlayer { void Dispose(); + void ReleaseMediaSource(); + void SetLooping(bool isLooping); void SetVolume(double volume); diff --git a/packages/audioplayers_windows/windows/audioplayers_windows_plugin.cpp b/packages/audioplayers_windows/windows/audioplayers_windows_plugin.cpp index 7fb098369..ebf81c443 100644 --- a/packages/audioplayers_windows/windows/audioplayers_windows_plugin.cpp +++ b/packages/audioplayers_windows/windows/audioplayers_windows_plugin.cpp @@ -164,8 +164,7 @@ void AudioplayersWindowsPlugin::HandleMethodCall( player->Pause(); player->SeekTo(0); } else if (method_call.method_name().compare("release") == 0) { - player->Pause(); - player->SeekTo(0); + player->ReleaseMediaSource(); } else if (method_call.method_name().compare("seek") == 0) { auto positionInMs = GetArgument("position", args, (int)ConvertSecondsToMs(player->GetPosition()));