private void RestartSubs() { if (sScreamer != null) { sScreamer.Abort(); } if (decoder.hasSubs) { Log("[SUBS SCREAMER] Restarting ..."); sScreamer = new Thread(() => { decoder.PauseSubs(); if (!isPlaying || videoStartTicks == -1) { return; } Thread.Sleep(20); lock (sFrames) sFrames = new ConcurrentQueue <MediaFrame>(); decoder.SeekAccurate((int)((CurTime - subsExternalDelay) / 10000) - 100, FFmpeg.AutoGen.AVMediaType.AVMEDIA_TYPE_SUBTITLE); decoder.RunSubs(); while (isPlaying && decoder.hasSubs && sFrames.Count < SUBS_MIN_QUEUE_SIZE && !decoder.isSubsFinish) { Thread.Sleep(20); } try { SubsScreamer(); } catch (Exception) { } }); sScreamer.SetApartmentState(ApartmentState.STA); sScreamer.Start(); } }
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); } }