0

我正在尝试创建一个 mp3 流媒体,但我失败得很惨:-)

我有以下内容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 { }

它失败了,并收到ProtocolIViolationException以下消息:

[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

该文件的 url 是我在谷歌搜索免费音乐时发现的,如果你打开它,你可以下载一个 mp3 文件......所以来源应该是合法的?

4

1 回答 1

1
  1. 您为数据源使用了错误的流。在完成处理程序调用中替换[Begin/End]GetRequestStream为,以访问正确的流。[Begin/End]GetResponseWebResponse.GetResponseStream
  2. 不要NotifyCompleteOnBeginStreaming. 而是NotifyComplete在曲目播放到结尾时调用。
  3. 之前BeginGetResponse,您应该设置,req.AllowReadStreamBuffering = false;否则您的 MP3 将在播放前完全下载。

更新 - 我的 while() 循环如下所示:

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 );
}
于 2013-07-28T15:27:07.350 回答