Ejemplo n.º 1
0
 /// <summary>
 /// Completely shuts down the AudioTrackStreamer.
 /// </summary>
 public static void ShutdownMediaStreamSource()
 {
     if (AudioTrackStreamer.mss != null)
     {
         lock (AudioTrackStreamer.syncRoot)
         {
             if (AudioTrackStreamer.mss != null)
             {
                 // Because of the NotifyComplete(), we need to set this BEFORE the MSS ends.
                 ShoutcastMediaStreamSource temp = AudioTrackStreamer.mss;
                 AudioTrackStreamer.mss = null;
                 temp.MetadataChanged -= new System.Windows.RoutedEventHandler(AudioTrackStreamer.MetadataChanged);
                 temp.Dispose();
             }
         }
     }
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Called when a new track requires audio decoding
 /// (typically because it is about to start playing)
 /// </summary>
 /// <param name="track">
 /// The track that needs audio streaming
 /// </param>
 /// <param name="streamer">
 /// The AudioStreamer object to which a MediaStreamSource should be
 /// attached to commence playback
 /// </param>
 /// <remarks>
 /// To invoke this method for a track set the Source parameter of the AudioTrack to null
 /// before setting  into the Track property of the BackgroundAudioPlayer instance
 /// property set to true;
 /// otherwise it is assumed that the system will perform all streaming
 /// and decoding
 /// </remarks>
 protected override void OnBeginStreaming(AudioTrack track, AudioStreamer streamer)
 {
     lock (AudioTrackStreamer.syncRoot)
     {
         try
         {
             AudioTrackStreamer.mss = new ShoutcastMediaStreamSource(new Uri(track.Tag));
             AudioTrackStreamer.mss.MetadataChanged += new RoutedEventHandler(AudioTrackStreamer.MetadataChanged);
             AudioTrackStreamer.mss.Closed += (s, e) =>
             {
                 this.NotifyComplete();
             };
             streamer.SetSource(AudioTrackStreamer.mss);
         }
         catch (Exception ex)
         {
             Debug.WriteLine("----------===============");
             Debug.WriteLine("OnBeginStreaming:" + ex);
         }
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Parses the passed in MediaStream to find the first frame and signals
        /// to its parent MediaElement that it is ready to begin playback by calling
        /// ReportOpenMediaCompleted.
        /// </summary>
        protected override void OpenMediaAsync()
        {
            System.Diagnostics.Debug.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ":  OpenMediaAsync()");

            // So, here is why this is a little weird.
            // The Shoutcast server software has the ability to provide web pages.  These pages just happen to be served from the SAME address as the media stream.
            // Putting a "/;" at the end of the Uri will tell the Shoutcast server that we aren't a web browser, so stream the data.  The problem is that not ALL
            // Shoutcast servers are configured that way.  So, we have to do a request to get the content type.  If it is text/html, we append the "/;" and move on.
            // If it is an empty string, 99.9% of the time, this will be the media stream (If it's an ICY stream, the ICY "headers" don't parse properly).  The ShoutcastStream
            // will handle this case, so we let it go through.
            HttpWebRequest contentTypeRequest = ShoutcastMediaStreamSource.CreateHttpWebRequest(this.StreamUri, this.IncludeMetadata);

            contentTypeRequest.BeginGetResponse(
                ia1 =>
            {
                HttpWebRequest req1 = ia1.AsyncState as HttpWebRequest;
                try
                {
                    HttpWebResponse res1 = (HttpWebResponse)req1.EndGetResponse(ia1);
                    string contentType   = res1.ContentType;
                    if ((contentType == string.Empty) || (contentType == "audio/mpeg") || contentType == "audio/x-mpegurl")
                    {
                        try
                        {
                            this.audioStream            = new ShoutcastStream(this, res1);
                            this.audioStreamDescription = this.audioStream.AudioStreamDescription;
                            this.ReportOpenMediaCompleted(this.audioStream.AudioSourceAttributes, new MediaStreamDescription[] { this.audioStream.AudioStreamDescription });
                        }
                        catch (Exception ex)
                        {
                            this.CleanupAudioStream();
                            this.ErrorOccurred(ex.Message);
                        }
                    }
                    else
                    {
                        // Close the original response.  We need another one.
                        res1.Close();
                        res1 = null;
                        if (!this.StreamUri.OriginalString.EndsWith("/", StringComparison.Ordinal))
                        {
                            this.StreamUri = new Uri(this.StreamUri.OriginalString + "/;", UriKind.Absolute);
                        }
                        else
                        {
                            this.StreamUri = new Uri(this.StreamUri.OriginalString + ";", UriKind.Absolute);
                        }

                        HttpWebRequest streamRequest = ShoutcastMediaStreamSource.CreateHttpWebRequest(this.StreamUri, this.IncludeMetadata);
                        streamRequest.BeginGetResponse(
                            ia =>
                        {
                            HttpWebRequest req = ia.AsyncState as HttpWebRequest;
                            try
                            {
                                HttpWebResponse res         = (HttpWebResponse)req.EndGetResponse(ia);
                                this.audioStream            = new ShoutcastStream(this, res);
                                this.audioStreamDescription = this.audioStream.AudioStreamDescription;
                                this.ReportOpenMediaCompleted(this.audioStream.AudioSourceAttributes, new MediaStreamDescription[] { this.audioStream.AudioStreamDescription });
                            }
                            catch (Exception ex)
                            {
                                if (res1 != null)
                                {
                                    res1.Close();
                                }

                                this.CleanupAudioStream();
                                this.ErrorOccurred(ex.Message);
                            }
                        },
                            streamRequest);
                    }
                }
                catch (Exception ex)
                {
                    this.CleanupAudioStream();
                    this.ErrorOccurred(ex.Message);
                }
            },
                contentTypeRequest);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Initializes a new instance of the ShoutcastStream class.
        /// </summary>
        /// <param name="mediaStreamSource">ShoutcastMediaStreamSource containing this ShoutcastStream.</param>
        /// <param name="httpWebResponse">HttpWebResponse for MP3 stream request.</param>
        /// <param name="numberOfSecondsToBuffer">Number of seconds of audio data to buffer.</param>
        /// <param name="metadataEncoding">Text encoding used to decode the Shoutcast metadata.</param>
        public ShoutcastStream(ShoutcastMediaStreamSource mediaStreamSource, HttpWebResponse httpWebResponse, int numberOfSecondsToBuffer, Encoding metadataEncoding)
        {
            System.Diagnostics.Debug.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + ":  ShoutcastStream() ctor");
            if (mediaStreamSource == null)
            {
                throw new ArgumentNullException("mediaStreamSource");
            }

            if (httpWebResponse == null)
            {
                throw new ArgumentNullException("httpWebResponse");
            }

            if (metadataEncoding == null)
            {
                throw new ArgumentNullException("encoding");
            }

            this.mediaStreamSource = mediaStreamSource;
            this.includeMetadata = this.mediaStreamSource.IncludeMetadata;
            this.numberOfSecondsToBuffer = numberOfSecondsToBuffer;
            this.metadataEncoding = metadataEncoding;

            // If the request is bad, this will die first, so we can just not worry about it.
            this.innerStream = httpWebResponse.GetResponseStream();
            try
            {
                // Read a chunk of data, but likely one smaller than the circular buffer size.
                byte[] initialBuffer = new byte[ShoutcastStream.DefaultInitialBufferSize];

                // Make sure we have enough data to work with initially
                int bytesRead = this.ForceReadFromStream(initialBuffer, 0, initialBuffer.Length);

                if (bytesRead == 0)
                {
                    // Should this be -1?
                    // This means there was something wrong with the stream.
                    throw new InvalidOperationException("Zero initial bytes read from stream.");
                }

                this.MediaInformation = this.FindStreamInformation(httpWebResponse, ref initialBuffer);

                if (this.MediaInformation == null)
                {
                    throw new ArgumentException("Invalid MediaInformation");
                }

                this.icyMetadata = this.MediaInformation.MetadataInterval;
                this.ParseInitialBuffer(initialBuffer);
            }
            catch (Exception)
            {
                // No matter what, we need to shut down!
                if (this.innerStream != null)
                {
                    this.innerStream.Dispose();
                    this.innerStream = null;
                }

                // Rethrow
                throw;
            }

            this.backgroundWorker = new BackgroundWorker()
            {
                WorkerReportsProgress = false,
                WorkerSupportsCancellation = true
            };

            this.backgroundWorker.DoWork += new DoWorkEventHandler(this.DoWork);
            this.backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.RunWorkerCompleted);
            this.backgroundWorker.RunWorkerAsync(this.innerStream);
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Initializes a new instance of the ShoutcastStream class.
 /// </summary>
 /// <param name="mediaStreamSource">ShoutcastMediaStreamSource containing this ShoutcastStream.</param>
 /// <param name="httpWebResponse">HttpWebResponse for MP3 stream request.</param>
 /// <param name="numberOfSecondsToBuffer">Number of seconds of audio data to buffer.</param>
 public ShoutcastStream(ShoutcastMediaStreamSource mediaStreamSource, HttpWebResponse httpWebResponse, int numberOfSecondsToBuffer)
     : this(mediaStreamSource, httpWebResponse, numberOfSecondsToBuffer, Encoding.UTF8)
 {
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Initializes a new instance of the ShoutcastStream class.
 /// </summary>
 /// <param name="mediaStreamSource">ShoutcastMediaStreamSource containing this ShoutcastStream.</param>
 /// <param name="httpWebResponse">HttpWebResponse for MP3 stream request.</param>
 public ShoutcastStream(ShoutcastMediaStreamSource mediaStreamSource, HttpWebResponse httpWebResponse)
     : this(mediaStreamSource, httpWebResponse, ShoutcastStream.DefaultSecondsToBuffer)
 {
 }