コード例 #1
0
        private void RestartAudio()
        {
            if (aScreamer != null)
            {
                aScreamer.Abort();
            }

            if (decoder.hasAudio)
            {
                Log("[AUDIO SCREAMER] Restarting ...");

                aScreamer = new Thread(() => {
                    decoder.PauseAudio();
                    if (!isPlaying || videoStartTicks == -1)
                    {
                        return;
                    }

                    Thread.Sleep(20);

                    lock (aFrames) aFrames = new ConcurrentQueue <MediaFrame>();
                    AudioResetClbk.Invoke();

                    decoder.SeekAccurate((int)((CurTime - audioExternalDelay) / 10000) - 50, FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_AUDIO);
                    decoder.RunAudio();

                    while (isPlaying && (decoder.hasAudio && aFrames.Count < AUDIO_MIX_QUEUE_SIZE))
                    {
                        Thread.Sleep(20);
                    }

                    try
                    {
                        AudioScreamer();
                    } catch (Exception) { }
                });
                aScreamer.SetApartmentState(ApartmentState.STA);
                aScreamer.Start();
            }
        }
コード例 #2
0
ファイル: MediaRouter.cs プロジェクト: jsliugang/MediaRouter
        private bool ResynchAudio(long syncTimestamp)
        {
            // Give it 1 Second
            if (DateTime.UtcNow.Ticks - audioLastSyncTicks < 10000000)
            {
                return(false);
            }
            audioLastSyncTicks = DateTime.UtcNow.Ticks;

            lock (aFrames)
            {
                Log("[AUDIO] Resynch Request to -> " + syncTimestamp / 10000);

                // Initialize Audio Player / Clear Audio Frames
                AudioResetClbk.BeginInvoke(null, null);
                aFrames = new Queue <MediaFrame>();

                // Seek Audio Decoder (syncTimestamp - 2 Audio Frames) to ensure audioFirstTimeStamp < syncTimestamp (-50ms to make sure will get a previous Frame within QueueSize)
                decoder.SeekAccurate((int)((syncTimestamp / 10000) - 50), FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_AUDIO);
                decoder.RunAudio();

                // Fill Audio Frames
                int escapeInfinity = 0;
                while (aFrames.Count < AUDIO_MIX_QUEUE_SIZE && isPlaying && decoder.isRunning)
                {
                    escapeInfinity++;
                    Thread.Sleep(10);
                    if (escapeInfinity > 50)
                    {
                        Log("[ERROR EI2] Audio Frames Queue will not be filled by decoder"); return(false);
                    }
                }

                // Validate We have AudioTimestamp < syncTimestamp
                MediaFrame aFrame     = aFrames.Peek();
                MediaFrame aFramePrev = new MediaFrame();

                if (aFrame.timestamp > syncTimestamp)
                {
                    Log("[AUDIO] Failed to force aFrame.timestamp < syncTimestamp (" + ", audioTimestamp: " + aFrame.timestamp + ", syncTimestamp: " + syncTimestamp + ")");
                    audioFlowTicks = DateTime.UtcNow.Ticks;
                    audioFlowBytes = 0;
                    SendAudioFrames();
                    return(false);
                }

                // Find Closest Audio Timestamp and Cut It precise
                while (aFrame.timestamp <= syncTimestamp && isPlaying)
                {
                    if (aFrames.Count < 2)
                    {
                        return(false);
                    }
                    aFramePrev = aFrames.Dequeue();
                    aFrame     = aFrames.Peek();
                }
                if (!isPlaying)
                {
                    return(false);
                }

                int removeBytes = (int)Math.Round((syncTimestamp - aFramePrev.timestamp) / ((1.0 / audioBytesPerSecond) * 10000 * 1000));
                if (removeBytes > aFramePrev.data.Length)
                {
                    removeBytes = aFramePrev.data.Length;
                }

                // Reset Timers & Fill Audio Player
                AudioFrameClbk(aFramePrev.data, removeBytes, aFramePrev.data.Length - removeBytes);
                audioFlowTicks = DateTime.UtcNow.Ticks;
                audioFlowBytes = 0;
                SendAudioFrames();

                Log("[AUDIO] Resynch Successfully to -> " + aFramePrev.timestamp / 10000 + " ++");

                return(true);
            }
        }