private void FfmpegListener() { _reasonToStop = ReasonToFinishPlaying.StoppedByUser; _afr = null; bool open = false; string errmsg = ""; try { Program.FFMPEGMutex.WaitOne(); _afr = new AudioFileReader(); int i = _source.IndexOf("://", StringComparison.Ordinal); if (i > -1) { _source = _source.Substring(0, i).ToLower() + _source.Substring(i); } _afr.Timeout = Timeout; _afr.AnalyzeDuration = AnalyseDuration; _afr.Open(_source); open = true; } catch (Exception ex) { MainForm.LogExceptionToFile(ex, "FFMPEG"); } finally { try { Program.FFMPEGMutex.ReleaseMutex(); } catch (ObjectDisposedException) { //can happen on shutdown } } if (_afr == null || !_afr.IsOpen || !open) { ShutDown("Could not open audio stream" + ": " + _source); return; } RecordingFormat = new WaveFormat(_afr.SampleRate, 16, _afr.Channels); _waveProvider = new BufferedWaveProvider(RecordingFormat) { DiscardOnBufferOverflow = true, BufferDuration = TimeSpan.FromMilliseconds(500) }; _sampleChannel = new SampleChannel(_waveProvider); _sampleChannel.PreVolumeMeter += SampleChannelPreVolumeMeter; int mult = _afr.BitsPerSample / 8; double btrg = Convert.ToDouble(_afr.SampleRate * mult * _afr.Channels); LastFrame = DateTime.UtcNow; bool realTime = !IsFileSource; try { DateTime req = DateTime.UtcNow; while (!_stopEvent.WaitOne(10, false) && !MainForm.ShuttingDown) { byte[] data = _afr.ReadAudioFrame(); if (data == null || data.Equals(0)) { if (!realTime) { break; } } if (data != null && data.Length > 0) { LastFrame = DateTime.UtcNow; var da = DataAvailable; if (da != null) { //forces processing of volume level without piping it out _waveProvider.AddSamples(data, 0, data.Length); var sampleBuffer = new float[data.Length]; _sampleChannel.Read(sampleBuffer, 0, data.Length); da(this, new DataAvailableEventArgs((byte[])data.Clone())); if (WaveOutProvider != null && Listening) { WaveOutProvider.AddSamples(data, 0, data.Length); } } if (realTime) { if (_stopEvent.WaitOne(30, false)) break; } else { // double f = (data.Length / btrg) * 1000; if (f > 0) { var span = DateTime.UtcNow.Subtract(req); var msec = Convert.ToInt32(f - (int)span.TotalMilliseconds); if ((msec > 0) && (_stopEvent.WaitOne(msec, false))) break; req = DateTime.UtcNow; } } } else { if ((DateTime.UtcNow - LastFrame).TotalMilliseconds > Timeout) { throw new Exception("Audio source timeout"); } if (_stopEvent.WaitOne(30, false)) break; } } } catch (Exception e) { MainForm.LogExceptionToFile(e, "FFMPEG"); errmsg = e.Message; } if (_sampleChannel != null) { _sampleChannel.PreVolumeMeter -= SampleChannelPreVolumeMeter; _sampleChannel = null; } if (_waveProvider != null) { if (_waveProvider.BufferedBytes > 0) _waveProvider.ClearBuffer(); } ShutDown(errmsg); }
private void FfmpegListener() { AudioFileReader afr = null; Program.WriterMutex.WaitOne(); try { afr = new AudioFileReader(); afr.Open(_source); } catch (Exception ex) { Log.Error("",ex);//MainForm.LogExceptionToFile(ex); } Program.WriterMutex.ReleaseMutex(); if (afr == null || !afr.IsOpen) { if (AudioFinished!=null) AudioFinished(this, ReasonToFinishPlaying.AudioSourceError); return; } RecordingFormat = new WaveFormat(afr.SampleRate, 16, afr.Channels); _waveProvider = new BufferedWaveProvider(RecordingFormat) { DiscardOnBufferOverflow = true }; _sampleChannel = new SampleChannel(_waveProvider); _sampleChannel.PreVolumeMeter += SampleChannelPreVolumeMeter; byte[] data; int mult = afr.BitsPerSample/8; double btrg = Convert.ToDouble(afr.SampleRate*mult*afr.Channels); DateTime lastPacket = DateTime.Now; bool realTime = _source.IndexOf("://") != -1; try { DateTime req = DateTime.Now; while (!_stopEvent.WaitOne(0, false)) { data = afr.ReadAudioFrame(); if (data.Length>0) { lastPacket = DateTime.Now; if (DataAvailable != null) { //forces processing of volume level without piping it out _waveProvider.AddSamples(data, 0, data.Length); var sampleBuffer = new float[data.Length]; _sampleChannel.Read(sampleBuffer, 0, data.Length); if (WaveOutProvider!=null && Listening) { WaveOutProvider.AddSamples(data, 0, data.Length); } var da = new DataAvailableEventArgs((byte[]) data.Clone()); DataAvailable(this, da); } if (realTime) { if (_stopEvent.WaitOne(10, false)) break; } else { double f = (data.Length/btrg)*1000; if (f > 0) { var span = DateTime.Now.Subtract(req); var msec = Convert.ToInt32(f - (int) span.TotalMilliseconds); if ((msec > 0) && (_stopEvent.WaitOne(msec, false))) break; req = DateTime.Now; } } } else { if ((DateTime.Now - lastPacket).TotalMilliseconds > 5000) { afr.Close(); Stop(); throw new Exception("Audio source timeout"); } if (_stopEvent.WaitOne(30, false)) break; } } if (AudioFinished != null) AudioFinished(this, ReasonToFinishPlaying.StoppedByUser); } catch (Exception e) { if (AudioSourceError!=null) AudioSourceError(this, new AudioSourceErrorEventArgs(e.Message)); Log.Error("",e);//MainForm.LogExceptionToFile(e); } }
private void FfmpegListener() { _reasonToStop = ReasonToFinishPlaying.StoppedByUser; _afr = null; bool open = false; string errmsg = ""; try { Program.FfmpegMutex.WaitOne(); _afr = new AudioFileReader(); int i = _source.IndexOf("://", StringComparison.Ordinal); if (i>-1) { _source = _source.Substring(0, i).ToLower() + _source.Substring(i); } _afr.Timeout = Timeout; _afr.AnalyzeDuration = AnalyseDuration; _afr.Headers = Headers; _afr.Cookies = Cookies; _afr.UserAgent = UserAgent; _afr.Open(_source); open = true; } catch (Exception ex) { Logger.LogExceptionToFile(ex,"FFMPEG"); } finally { try { Program.FfmpegMutex.ReleaseMutex(); } catch (ObjectDisposedException) { //can happen on shutdown } } if (_afr == null || !_afr.IsOpen || !open) { ShutDown("Could not open audio stream" + ": " + _source); return; } RecordingFormat = new WaveFormat(_afr.SampleRate, 16, _afr.Channels); _waveProvider = new BufferedWaveProvider(RecordingFormat) { DiscardOnBufferOverflow = true, BufferDuration = TimeSpan.FromMilliseconds(500) }; _sampleChannel = new SampleChannel(_waveProvider); _sampleChannel.PreVolumeMeter += SampleChannelPreVolumeMeter; LastFrame = DateTime.UtcNow; try { while (!_stopEvent.WaitOne(10, false) && !MainForm.ShuttingDown) { byte[] data = _afr.ReadAudioFrame(); if (data!=null && data.Length > 0) { LastFrame = DateTime.UtcNow; var da = DataAvailable; if (da != null) { //forces processing of volume level without piping it out _waveProvider.AddSamples(data, 0, data.Length); var sampleBuffer = new float[data.Length]; int read = _sampleChannel.Read(sampleBuffer, 0, data.Length); da(this, new DataAvailableEventArgs((byte[])data.Clone(),read)); if (Listening) { WaveOutProvider?.AddSamples(data, 0, read); } } if (_stopEvent.WaitOne(30, false)) break; } else { if ((DateTime.UtcNow - LastFrame).TotalMilliseconds > Timeout) { throw new Exception("Audio source timeout"); } if (_stopEvent.WaitOne(30, false)) break; } } } catch (Exception e) { Logger.LogExceptionToFile(e,"FFMPEG"); errmsg = e.Message; } if (_sampleChannel != null) { _sampleChannel.PreVolumeMeter -= SampleChannelPreVolumeMeter; _sampleChannel = null; } if (_waveProvider?.BufferedBytes > 0) _waveProvider.ClearBuffer(); if (WaveOutProvider?.BufferedBytes > 0) WaveOutProvider?.ClearBuffer(); ShutDown(errmsg); }