Xamarin-Plugins
Xamarin-Plugins copied to clipboard
Play audio from an HTTP source
Hello,
Thank you for this perfect tool! It is exactly the simple player I was looking for, and implemented in Xamarin.Forms! This has saved me so much time.
I am very new to Xamarin.Forms. I see how you open a file to get a stream, but how would one get a valid stream from a URL, say from a podcast MP3 hosted in the cloud?
Thank you for your help, Thaine Norris
Thanks @ThaineNorris - I'll add this to my ToDo list.
I'm just testing some Android fixes and adding macOS support - and then I'll add support for web audio sources.
Cheers!
@adrianstevens Thanks for sharing this plugin! Do you know if being able to stream audio from a URL will be an option in the near future? Or do you have any suggestions for how to implement it myself? Thanks!
My "fix" was to convert the URL resource into a stream, and load that stream:
ISimpleAudioPlayer player = CrossSimpleAudioPlayer.Current;
string url = "some-url-string";
WebClient wc = new WebClient();
Stream fileStream = wc.OpenRead(url);
player.Load(fileStream);
player.Play();
My only problem is, I'm not sure how to detect an Http Error (say, if the resource is unavailable, or if there is some server error). I happen to be quite new to C#. Let me know if you guys have any suggestions!
Thanks for the suggestion @markguindi1! That helped us get us on the right track.
This is what we ended up using:
SimpleAudioPlayer player = CrossSimpleAudioPlayer.Current;
string url = "url-audio-string";
HttpClient httpClient = new HttpClient();
Stream fileStream = await httpClient.GetStreamAsync(url);
player.Load(fileStream);
As far as detecting Http Errors, before loading the audio, we do a quick Http request to the audio file to check the status code. If it returns 200, we'll load the audio player. Here's an example:
try
{
var httpClient = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Head, new Uri(audioFile));
var response = await httpClient.SendAsync(request);
request.Dispose();
if (response.StatusCode != HttpStatusCode.OK)
GATracker.DefaultTracker.TrackException($"{(int)response.StatusCode} {response.StatusCode}\n{audioFile}", false);
return (response.StatusCode == HttpStatusCode.OK);
}
catch (Exception e)
{
GATracker.DefaultTracker.TrackException($"{e.Message}\n{e.InnerException.Message}\n{e.StackTrace}", false);
return false;
}
Thank you for this lib, I hope I can contribute sometime soon.
Very interesting approach @markguindi1 and @LyndiLeighWK.
I know that for android and iOS there are native os APIs that can do that for us like MediaPlayer for android and AVFoundation for iOS. maybe this would be the way to go for implementing this on this lib :)
I haven't looked deep into the lib code, you are probably already using them, we would just have to make the streaming apis available.
Thanks @LyndiLeighWK and @DanielCauser. I've looked into those libs that @DanielCauser mentioned, but didn't end up using them as they didn't seem to fit my specific use case (as far as I remember from when I was working on my project).
And @LyndiLeighWK I've thought of your idea, to make a quick HTTP request before loading the audio, but it didn't work for me, as the server I was connecting to was a bit unreliable (don't ask). So making an HTTP request before loading the audio would be of little use to me, as the initial request may succeed but loading the audio (the 2nd request) may fail, or vice versa. I was looking for a way to check the HTTP status of the request that actually produced the stream, but I couldn't find a way to access it.
What is the status of playing audio from an HTTP source ?
Thanks for the suggestion @markguindi1! That helped us get us on the right track.
This is what we ended up using:
SimpleAudioPlayer player = CrossSimpleAudioPlayer.Current; string url = "url-audio-string"; HttpClient httpClient = new HttpClient(); Stream fileStream = await httpClient.GetStreamAsync(url); player.Load(fileStream);
As far as detecting Http Errors, before loading the audio, we do a quick Http request to the audio file to check the status code. If it returns 200, we'll load the audio player. Here's an example:
try { var httpClient = new HttpClient(); var request = new HttpRequestMessage(HttpMethod.Head, new Uri(audioFile)); var response = await httpClient.SendAsync(request); request.Dispose(); if (response.StatusCode != HttpStatusCode.OK) GATracker.DefaultTracker.TrackException($"{(int)response.StatusCode} {response.StatusCode}\n{audioFile}", false); return (response.StatusCode == HttpStatusCode.OK); } catch (Exception e) { GATracker.DefaultTracker.TrackException($"{e.Message}\n{e.InnerException.Message}\n{e.StackTrace}", false); return false; }
This is working for me! Thanks. However, in my case, android was throwing Android.OS.NetworkOnMainThreadException
, which i fixed by using
await Task.Run(async () =>
{
await PlayAudio();
});
async Task PlayAudio()
{
player = CrossSimpleAudioPlayer.Current;
string url = "some audio url here";
using var httpClient = new HttpClient();
var fileStream = await httpClient.GetStreamAsync(url);
player.Load(fileStream);
player.Play();
player.PlaybackEnded += this.Player_PlaybackEnded;
}
Dear Contributors,
Please confirm if there is a way by which we can stream mp3 from internet URL i.e. we should not require the complete download of mp3 prior to starting playback. This is for the use case of large MP3 files and slower internet. Something similar to buffered playback offered by Portals.
Sorry if I am asking for too much.
Regards, Dhiraj.
Hi,
Please suggest me an option to stream url file without downloading everything in the starting itself, Is there any way to implement this case myself using this plugin?