Reputation: 13620
I'm trying to create a mp3 streamer, but I'm failing miserably :-)
I've got the following in my AudioTrackStreamer
:
protected override void OnBeginStreaming(AudioTrack track, AudioStreamer streamer)
{
//TODO: Set the SetSource property of streamer to a MSS source
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://api.soundcloud.com/tracks/85085126/stream?consumer_key=db840ada2477a93d5fdbcc96a46b37c1");
req.ContentType = "application/octet-stream";
try
{
req.BeginGetRequestStream((callback) =>
{
HttpWebRequest request = (HttpWebRequest)callback.AsyncState;
Stream stream = request.EndGetRequestStream(callback);
Mp3MediaStreamSource src = new Mp3MediaStreamSource(stream, 1000);
streamer.SetSource(src);
NotifyComplete();
}, req);
}
catch { }
And it fails, catching ProtocolIViolationException
with the message:
[Arg_InvalidOperationException]
Arguments:
Debugging resource strings are unavailable. Often the key and arguments provide sufficient information to diagnose the problem. See http://go.microsoft.com/fwlink/?linkid=106663&Version=4.0.50829.0&File=mscorlib.dll&Key=Arg_InvalidOperationException
The url to the file is something I found while googling free Music, and if you open it you get to download a mp3 file... so the source should be legit?
Upvotes: 0
Views: 277
Reputation: 21956
[Begin/End]GetRequestStream
with [Begin/End]GetResponse
, in the completion handler call WebResponse.GetResponseStream
to access the correct stream.NotifyComplete
from OnBeginStreaming
. Instead, call NotifyComplete
when the track is played to the end.BeginGetResponse
, you should set req.AllowReadStreamBuffering = false;
otherwise your MP3s will download completely before playback.Update - my while() loop looks like this:
while( true )
{
if( cancel.IsCancellationRequested )
return;
if( buffer.hasFreeSpace() )
{
int cb = await this.downloadAsync().ConfigureAwait( false );
var buffWaiter = m_bufferAwaiter;
if( 0 == cb )
{
Exception ex = new Exception( "runBackgroundAsync: connection dropped" );;
if( null != buffWaiter )
buffWaiter.Fail( ex );
throw ex;
}
if( null != buffWaiter )
{
// The client is waiting for the data to be pre-buffered
if( buffWaiter.haveBuffer( buffer.cbLength ) )
{
// Sufficient data has been downloaded, so playback is going to resume after this haveBuffer() call.
m_bufferAwaiter = null;
}
}
continue; //< Continuing to while(true) without a single sleep.
}
await TaskEx.Delay( this.tsSleepTimeWhenBufferFull, cancel ).ConfigureAwait( false );
}
Upvotes: 1