private async Task HandleMetadataAsync(CancellationToken cancelToken)
        {
            if (!shoutcastStream.serverSettings.RequestSongMetdata)
            {
                return;
            }

            cancelToken.ThrowIfCancellationRequested();

            if (metadataPos == shoutcastStream.metadataInt)
            {
                metadataPos = 0;

                await socket.LoadAsync(1);

                if (socket.UnconsumedBufferLength > 0)
                {
                    uint metaInt = await socket.ReadByteAsync();

                    if (metaInt > 0)
                    {
                        try
                        {
                            uint metaDataInfo = metaInt * 16;

                            cancelToken.ThrowIfCancellationRequested();

                            await socket.LoadAsync((uint)metaDataInfo);

                            var metadata = await socket.ReadStringAsync((uint)metaDataInfo);

                            ParseSongMetadata(metadata);
                        }
                        catch (Exception e)
                        {
                            throw new Exception("Error occurred while parsing metadata.", e);
                            //if (e is System.ArgumentOutOfRangeException || e is NullReferenceException)
                            //{
                            //    //No mapping for the Unicode character exists in the target multi-byte code page.

                            //    shoutcastStream.MediaStreamSource.MusicProperties.Title = "Unknown Song";
                            //    shoutcastStream.MediaStreamSource.MusicProperties.Artist = "Unknown Artist";

                            //    shoutcastStream.RaiseMetadataChangedEvent(new ShoutcastMediaSourceStreamMetadataChangedEventArgs()
                            //    {
                            //        Title = "Unknown Song",
                            //        Artist = "Unknown Artist"
                            //    });
                            //}
                        }
                    }

                    cancelToken.ThrowIfCancellationRequested();

                    //byteOffset = 0;
                }
            }
        }
예제 #2
0
        public async Task <Tuple <MediaStreamSample, uint> > ParseSampleAsync(ShoutcastStreamProcessor processor, SocketWrapper socket, bool partial = false, byte[] partialBytes = null)
        {
            //http://www.mpgedit.org/mpgedit/mpeg_format/MP3Format.html

            IBuffer           buffer = null;
            MediaStreamSample sample = null;
            uint sampleLength        = 0;

            if (partial)
            {
                buffer       = partialBytes.AsBuffer();
                sampleLength = MP3Parser.mp3_sampleSize - (uint)partialBytes.Length;
                //processor.byteOffset += sampleLength;
            }
            else
            {
                var read = await socket.LoadAsync(MP3Parser.mp3_sampleSize);

                if (read == 0 || read < MP3Parser.mp3_sampleSize)
                {
                    //disconnected.
                    throw new ShoutcastDisconnectionException();
                }

                buffer = await socket.ReadBufferAsync(MP3Parser.mp3_sampleSize);

                //processor.byteOffset += MP3Parser.mp3_sampleSize;

                sampleLength = MP3Parser.mp3_sampleSize;
            }

            sample          = MediaStreamSample.CreateFromBuffer(buffer, processor.timeOffSet);
            sample.Duration = MP3Parser.mp3_sampleDuration;
            sample.KeyFrame = true;

            processor.timeOffSet = processor.timeOffSet.Add(MP3Parser.mp3_sampleDuration);


            return(new Tuple <MediaStreamSample, uint>(sample, sampleLength));
        }
예제 #3
0
        private async Task <AudioEncodingProperties> ParseEncodingFromMediaAsync()
        {
            //grab the first frame and strip it for information

            AudioEncodingProperties obtainedProperties = null;
            IBuffer buffer = null;

            if (AudioInfo.AudioFormat == StreamAudioFormat.AAC)
            {
                //obtainedProperties = AudioEncodingProperties.CreateAac(0, 2, 0);
                throw new Exception("Not supported.");
            }

            var provider = AudioProviderFactory.GetAudioProvider(AudioInfo.AudioFormat);

            ServerAudioInfo firstFrame = await provider.GrabFrameInfoAsync(streamProcessor, AudioInfo).ConfigureAwait(false);

            //loop until we receive a few "frames" with identical information.
            while (true)
            {
                cancelTokenSource.Token.ThrowIfCancellationRequested();

                ServerAudioInfo secondFrame = await provider.GrabFrameInfoAsync(streamProcessor, AudioInfo).ConfigureAwait(false);

                if (firstFrame.BitRate == secondFrame.BitRate &&
                    firstFrame.SampleRate == secondFrame.SampleRate)
                {
                    //both frames are identical, use one of them and escape the loop.
                    AudioInfo = firstFrame;
                    break;
                }
                else
                {
                    //frames aren't identical, get rid of the first one using the second frame and loop back.
                    firstFrame = secondFrame;
                    continue;
                }
            }

            cancelTokenSource.Token.ThrowIfCancellationRequested();

            if (AudioInfo.AudioFormat == StreamAudioFormat.MP3)
            {
                //skip the entire first frame/sample to get back on track
                await socket.LoadAsync(MP3Parser.mp3_sampleSize - MP3Parser.HeaderLength);

                buffer = await socket.ReadBufferAsync(MP3Parser.mp3_sampleSize - MP3Parser.HeaderLength);

                //streamProcessor.byteOffset += MP3Parser.mp3_sampleSize - MP3Parser.HeaderLength;


                obtainedProperties = AudioEncodingProperties.CreateMp3((uint)AudioInfo.SampleRate, (uint)AudioInfo.ChannelCount, AudioInfo.BitRate);
            }
            else if (AudioInfo.AudioFormat == StreamAudioFormat.AAC_ADTS)
            {
                //skip the entire first frame/sample to get back on track
                await socket.LoadAsync(AAC_ADTSParser.aac_adts_sampleSize - AAC_ADTSParser.HeaderLength);

                buffer = await socket.ReadBufferAsync(AAC_ADTSParser.aac_adts_sampleSize - AAC_ADTSParser.HeaderLength);

                //streamProcessor.byteOffset += AAC_ADTSParser.aac_adts_sampleSize - AAC_ADTSParser.HeaderLength;

                obtainedProperties = AudioEncodingProperties.CreateAacAdts((uint)AudioInfo.SampleRate, (uint)AudioInfo.ChannelCount, AudioInfo.BitRate);
            }
            else
            {
                throw new Exception("Unsupported format.");
            }

            if (serverSettings.RequestSongMetdata)
            {
                streamProcessor.metadataPos += buffer.Length; //very important or it will throw everything off!
            }
            return(obtainedProperties);
        }