Пример #1
0
        partial void InitializeImpl()
        {
            using (var inputFile = new Java.IO.File(mediaDataUrl))
            {
                if (!inputFile.CanRead())
                {
                    throw new Exception(string.Format("Unable to read: {0} ", inputFile.AbsolutePath));
                }

                using (var inputFileStream = new Java.IO.FileInputStream(inputFile.AbsolutePath))
                {
                    var audioMediaExtractor = new MediaExtractor();
                    audioMediaExtractor.SetDataSource(inputFileStream.FD, startPosition, length);
                    var trackIndexAudio = StreamedBufferSoundSource.FindAudioTrack(audioMediaExtractor);
                    if (trackIndexAudio < 0)
                    {
                        return;
                    }

                    audioMediaExtractor.SelectTrack(trackIndexAudio);
                    var audioFormat = audioMediaExtractor.GetTrackFormat(trackIndexAudio);

                    //Get the audio settings
                    //should we override the settings (channels, sampleRate, ...) from DynamicSoundSource?
                    Channels      = audioFormat.GetInteger(MediaFormat.KeyChannelCount);
                    SampleRate    = audioFormat.GetInteger(MediaFormat.KeySampleRate);
                    MediaDuration = TimeSpanExtensions.FromMicroSeconds(audioFormat.GetLong(MediaFormat.KeyDuration));
                }
            }
        }
        partial void InitializeMediaExtractor(string mediaDataUrl, long startPosition, long length)
        {
            if (mediaDataUrl == null)
            {
                throw new ArgumentNullException(nameof(mediaDataUrl));
            }

            ReleaseMediaInternal();

            InputFile = new Java.IO.File(mediaDataUrl);
            if (!InputFile.CanRead())
            {
                throw new Exception(string.Format("Unable to read: {0} ", InputFile.AbsolutePath));
            }

            InputFileStream = new Java.IO.FileInputStream(InputFile.AbsolutePath);

            audioMediaExtractor = new MediaExtractor();
            audioMediaExtractor.SetDataSource(InputFileStream.FD, startPosition, length);
            trackIndexAudio = FindAudioTrack(audioMediaExtractor);
            if (trackIndexAudio < 0)
            {
                ReleaseMediaInternal();
                Logger.Error($"The input file '{mediaDataUrl}' does not contain any audio track.");
                return;
            }

            audioMediaExtractor.SelectTrack(trackIndexAudio);
            var audioFormat = audioMediaExtractor.GetTrackFormat(trackIndexAudio);

            var mime = audioFormat.GetString(MediaFormat.KeyMime);

            audioMediaDecoder = MediaCodec.CreateDecoderByType(mime);
            audioMediaDecoder.Configure(audioFormat, null, null, 0);

            //Get the audio settings
            //should we override the settings (channels, sampleRate, ...) from DynamicSoundSource?
            Channels      = audioFormat.GetInteger(MediaFormat.KeyChannelCount);
            SampleRate    = audioFormat.GetInteger(MediaFormat.KeySampleRate);
            MediaDuration = TimeSpanExtensions.FromMicroSeconds(audioFormat.GetLong(MediaFormat.KeyDuration));

            audioMediaDecoder.Start();

            extractionOutputDone = false;
            extractionInputDone  = false;
        }
Пример #3
0
        protected override void UpdateInternal()
        {
            base.UpdateInternal();

            // update the media presentation time
            var currentTime = DateTime.Now;
            var elapsedTime = (currentTime - lastLoopTime);

            if (elapsedTime > TimeSpan.Zero)
            {
                if (SpeedFactor != 1)
                {
                    elapsedTime = TimeSpan.FromMilliseconds(elapsedTime.TotalMilliseconds * SpeedFactor);
                }

                var mediaCurrentTime = MediaCurrentTime;
                if (mediaCurrentTime < mediaCurrentTimeMax)
                {
                    MediaCurrentTime = TimeSpanExtensions.Min(mediaCurrentTime + elapsedTime, mediaCurrentTimeMax);
                }
            }
            lastLoopTime = currentTime;
        }
        private bool ExtractSomeAudioData(out bool endOfFile)
        {
            endOfFile = extractionOutputDone;
            if (endOfFile)
            {
                return(false);
            }

            var hasExtractedData = false;

            int TimeoutUs = 20000;

            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();

            if (!extractionInputDone)
            {
                int inputBufIndex = audioMediaDecoder.DequeueInputBuffer(TimeoutUs);
                if (inputBufIndex >= 0)
                {
                    Java.Nio.ByteBuffer inputBuffer = audioMediaDecoder.GetInputBuffer(inputBufIndex);

                    //Read the sample data into the ByteBuffer.  This neither respects nor updates inputBuf's position, limit, etc.
                    int chunkSize = audioMediaExtractor.ReadSampleData(inputBuffer, 0);
                    if (chunkSize < 0)
                    {
                        //End of stream: send empty frame with EOS flag set
                        audioMediaDecoder.QueueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodecBufferFlags.EndOfStream);
                        extractionInputDone = true;
                        //Logger.Verbose("sent input EOS");
                    }
                    else
                    {
                        if (audioMediaExtractor.SampleTrackIndex != trackIndexAudio)
                        {
                            Logger.Warning(string.Format("got audio sample from track {0}, expected {1}", audioMediaExtractor.SampleTrackIndex, trackIndexAudio));
                        }

                        var presentationTimeMicroSeconds = audioMediaExtractor.SampleTime;
                        audioMediaDecoder.QueueInputBuffer(inputBufIndex, 0, chunkSize, presentationTimeMicroSeconds, 0);

                        audioMediaExtractor.Advance();
                    }
                }
                else
                {
                    //do nothing: the input buffer queue is full (we need to output them first)
                    //continue;
                }
            }

            int decoderStatus = audioMediaDecoder.DequeueOutputBuffer(info, TimeoutUs);

            switch (decoderStatus)
            {
            case (int)MediaCodecInfoState.TryAgainLater:
            {
                Logger.Verbose("no output from decoder available");
                break;
            }

            case (int)MediaCodecInfoState.OutputFormatChanged:
            {
                MediaFormat newFormat    = audioMediaDecoder.OutputFormat;
                string      newFormatStr = newFormat.ToString();
                Logger.Verbose("audio decoder output format changed: " + newFormatStr);
                break;
            }

            case (int)MediaCodecInfoState.OutputBuffersChanged:
            {
                //deprecated: we just ignore it
                break;
            }

            default:
            {
                if (decoderStatus < 0)
                {
                    throw new InvalidOperationException(string.Format("unexpected result from audio decoder.DequeueOutputBuffer: {0}", decoderStatus));
                }

                if ((info.Flags & MediaCodecBufferFlags.EndOfStream) != 0)
                {
                    Logger.Verbose("audio: output EOS");
                    extractionOutputDone = true;
                }

                if (info.Size > 0)
                {
                    hasExtractedData = true;
                    var buffer           = audioMediaDecoder.GetOutputBuffer(decoderStatus);
                    var presentationTime = TimeSpanExtensions.FromMicroSeconds(info.PresentationTimeUs);

                    if (StorageBuffer.CountDataBytes + info.Size <= StorageBuffer.Data.Length)
                    {
                        buffer.Get(StorageBuffer.Data, StorageBuffer.CountDataBytes, info.Size); // Read the buffer all at once
                        buffer.Clear();                                                          // MUST DO!!! OTHERWISE THE NEXT TIME YOU GET THIS SAME BUFFER BAD THINGS WILL HAPPEN
                        buffer.Position(0);

                        if (StorageBuffer.CountDataBytes == 0)
                        {
                            StorageBuffer.PresentationTime = presentationTime;
                        }

                        StorageBuffer.CountDataBytes += info.Size;
                    }
                    else
                    {
                        Logger.Error("The storage buffer has reached full capacity. Current data will be dropped");
                    }
                }

                audioMediaDecoder.ReleaseOutputBuffer(decoderStatus, false);
                break;
            }
            }

            endOfFile = extractionOutputDone;
            return(hasExtractedData);
        }