I am using Webview
for playing audio and when I navigate to a new page the audio stops playing. I want to play the audio in background when navigating to new pages, or switching app or locking device.
My Code:
<WebView
x:Name="audio_webview"
BackgroundColor="Transparent"
Navigated="OnWebViewNavigated"
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand" >
<WebView.HeightRequest>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Phone>80</OnIdiom.Phone>
<OnIdiom.Tablet>120</OnIdiom.Tablet>
<OnIdiom.Desktop>80</OnIdiom.Desktop>
</OnIdiom>
</WebView.HeightRequest>
<WebView.WidthRequest>
<OnIdiom x:TypeArguments="x:Double">
<OnIdiom.Phone>420</OnIdiom.Phone>
<OnIdiom.Tablet>630</OnIdiom.Tablet>
<OnIdiom.Desktop>420</OnIdiom.Desktop>
</OnIdiom>
</WebView.WidthRequest>
</WebView>
audio_webview.Source = audioUrl;
When I navigate to a new page I am getting below messages in the output box:
11:04:37:012 [AAudio] AAudioStream_requestStop(s#1) called
11:04:37:012 [AAudio] AAudioStream_close(s#1) called ---------------
11:04:37:012 [AAudioStream] setState(s#1) from 10 to 11
11:04:37:012 [AudioTrack] stop(portId:2774, sessionId:48889): 0xb400006eb01c3f40, prior state:STATE_STOPPED
11:04:37:012 [AudioTrackShared] this(0xb400006e500b8550), mCblk(0x6d7fcdc000), front(311736), mIsOut 1, interrupt() FUTEX_WAKE
11:04:37:012 [AudioTrack] requestExitAndWait start
11:04:37:012 [AudioTrack] requestExitAndWait end
11:04:37:012 [AudioTrack] stopAndJoinCallbacks(2774) done
11:04:37:012 [AudioTrack] ~AudioTrack(2774): 0xb400006eb01c3f40
11:04:37:072 [AudioTrack] getpackName client name com.companyname.appname(24146)
11:04:37:072 [AudioTrack] stop(portId:2774, sessionId:48889): 0xb400006eb01c3f40, prior state:STATE_STOPPED
11:04:37:072 [AudioTrack] stopAndJoinCallbacks(2774) done
11:04:37:072 [AAudioStream] setState(s#1) from 11 to 12
11:04:37:072 [AAudioStream] ~AudioStream(s#1) mPlayerBase strongCount = 2
11:04:37:072 [AAudio] AAudioStream_close(s#1) returned 0 ---------
I want to play the audio in background without pausing when opening new pages. This feature is working fine on iOS platform, but in android only the audio is pausing.
Update:
I am playing the audio on a pop-up window and on that I am setting the background color to transparent. So I did some custom logic to make transparent background. When I close the pop up audio is playing, but when navigating to another content page audio stops.
My Code:
public DailyAudioPopUpPage(string audioUrl)
{
InitializeComponent();
LoadAudio(audioUrl);
}
private void LoadAudio(string audioUrl)
{
var html = $@"
<html>
<body style='margin:0; background-color: transparent; display:flex; justify-content:center; align-items:center; height:100%;'>
<audio controls autoplay style='width:90%;'>
<source src='{audioUrl}' type='audio/mpeg'>
Your browser does not support the audio element.
</audio>
</body>
</html>";
audio_webview.Source = new HtmlWebViewSource { Html = html };
}
You can use the MediaElement to display the audio instead of the webview And avoid using the popup to display the UI control.
I created a sample and show the the play pause controls and progress bar.
<Grid RowDefinitions="5*,1*,0.2*" ColumnDefinitions="*,*,*">
<toolkit:MediaElement x:Name="media" HeightRequest="50" Grid.Row="0" Grid.ColumnSpan="3" Source="https://s3.amazonaws.com/catholicbrain/prod/dc/cbrain-app/files/doc-lib/2025/02/07/11/47/33/584/head/feb25_saint.mp3"/>
<Slider Grid.Row="1" DragCompleted="Slider_DragCompleted" Grid.ColumnSpan="3" Value="{Binding Source={x:Reference media},Path=Position.TotalSeconds}" Maximum="{Binding Source={x:Reference media}, Path=Duration.TotalSeconds}"/>
<Image Source="preview.png" Grid.Row="2" Grid.Column="0" HorizontalOptions="End"/>
<Image Source="play.png" Grid.Row="2" Grid.Column="1" HorizontalOptions="Center"/>
<Image Source="next.png" Grid.Row="2" Grid.Column="2" HorizontalOptions="Start"/>
</Grid>
And the Slider_DragCompleted method:
private async void Slider_DragCompleted(object? sender, EventArgs e)
{
var newValue = ((Slider)sender).Value;
await MediaElement.SeekTo(TimeSpan.FromSeconds(newValue), CancellationToken.None);
}
I used the Slider as the progress bar. I bind the max value to the audio's total seconds and bind the current value to the audio's current position. When user slids the slider, I call the SeekTo
method to change the position of the MediaElement.
In addition, you can check the official sample and it provided many custom functions.