【问题标题】:Use Task or something else?使用任务或其他东西?
【发布时间】:2014-03-24 06:34:47
【问题描述】:

我正在用 C# 编写。

我有一个实时音频播放器,可以播放来自 IP 电话的传入语音。我有一个byte[] Array,当它进入时,它会获取所有的语音字节,当用户按下播放按钮时,我开始播放它。我也有停止和暂停按钮。我为此使用 NAudio,BufferedWaveProvider 和 Waveout 类。

播放器类代码:

public void PlayCall(Call call)
{
         byte[] mixedBuffer = new byte[320];
         while (call.PlayerIndex < call.AudioArray.Length) // The AudioArray keeps getting bigger
         {
             if (_state == PlayerState.PAUSED || _state == PlayerState.STOPPED)
             // either STOP or PAUSE button is clicked
                  break;
             for (int i = 0; i < 320; i++)
             {
                  mixedBuffer[i] = (byte)(call.AudioArray[call.PlayerIndex + i];
             }
             call.PlayerIndex += 320;
             Thread.Sleep(20); // This is in order to synchronize the receiving and playing of the packets. 
             try
             {
                  AddSamples(mixedBuffer);
                  Waveout.Play();
             }
             catch (InvalidOperationException ex)
             {
                  _bufferedWaveProvider.ClearBuffer();

             }
             finally
             {
                  ClearByteArray(ref mixedBuffer);
             }
         }
}

public void StopCall(Call call)
{        
    _state = PalyerState.STOPPED;
    call.PlayerIndex=0;
    Waveout.Stop();
}

public void PauseCall(Call call)
{
    _state = PlayerState.PAUSED;
    Waveout.Pause();
}

_state 表示通话状态(正在播放、已停止、已暂停)。 如您所见,当按下 PLAY 时,它会一直播放,直到按下 STOP/PAUSED,然后才会中断。 (WHILE 循环)。

我的问题是,在我稍微按下按钮后,Waveout.PLAY 有时不再工作,因此BufferedWaveProvider 已满并崩溃。 (有时会在单击两次后发生,有时在 10 次后发生变化)。

我认为这与我调用方法的方式有关。可能与Threads/Tasks有些混淆,或者不确定其中一种方法是否结束……就像这样:

视图模型上的代码:

private void ExecutePlayCallMethod(Call call)
{
    call.Player.State = PlayerState.PLAYING;
    Task.Run(() => call.Player.PlayCall(call)); // 
}

private void ExecutePauseCallMethod(CAll call)
{
    Task.Run(() => call.Player.PauseCall(call));
    call.Player.State = PlayerState.PAUSED;
}

private void ExecuteStopCallMethod(Call call)
{
    call.Player.State = PlayerState.STOPPED;
    Task.Run(() => call.Player.StopCall(call));
}

请帮忙?这个问题我纠结了好久。。

提前致谢!

【问题讨论】:

    标签: c# real-time voip naudio


    【解决方案1】:

    我怀疑多次调用Waveout.Play() 是问题所在。您只需要调用一次Play(),然后将样本输入到源波形提供程序(您的BufferedWaveProvider 实例)中,剩下的就交给库了。当波形提供程序为空时,WaveOut 对象将继续播放静音,直到您提供更多样本。

    顺便说一句,这一切都可以在一个线程中实现。创建WaveOut 实例,创建BufferedWaveProvider 作为样本缓冲区并将其设置为运行。然后当音频数据可用时,您只需将数据添加到BufferedWaveProvider 即可播放。

    BufferedWaveProvider 使用线程安全的内部缓冲区,因此如果您确实需要这样做,可以安全地从其他线程添加。

    【讨论】:

    • 谢谢!在我更改它之后它似乎正在工作,我只是将 Waveout.Play 从 WHILE 循环中取出。还有一个问题 - Waveout.Stop 和 Waveout.Pause 有什么区别?我在某处读到其中一个清除缓冲区而另一个没有?
    猜你喜欢
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 2012-06-16
    • 2011-06-11
    • 1970-01-01
    相关资源
    最近更新 更多