Java 使用两个音频线程时出现音频故障

Java 使用两个音频线程时出现音频故障,java,audio,xuggler,Java,Audio,Xuggler,我使用一个线程绘制波形,另一个线程播放音频。唯一的问题是,我在播放时会出现音频口吃,这是因为解码音频过程: 音频编码器。解码音频(样本、数据包、偏移量) 以下是我的波形绘制课程: public class DrawWaveform extends Thread{ String f; int n; DrawWaveform(final String file, final int nstream) { this.setPriority(10);

我使用一个线程绘制波形,另一个线程播放音频。唯一的问题是,我在播放时会出现音频口吃,这是因为解码音频过程: 音频编码器。解码音频(样本、数据包、偏移量)

以下是我的波形绘制课程:

public class DrawWaveform extends Thread{
    String f;
    int n;
    DrawWaveform(final String file, final int nstream)
    {
        this.setPriority(10);
        f = file;
        n = nstream;
    }
    public void run() {

        stopThread = false;
        {
            IContainer container = IContainer.make();

            container.open(f, IContainer.Type.READ, null);

            // query how many streams the call to open found
            int numStreams = container.getNumStreams();
            int count = 0;
            IStreamCoder audioCoder = null;
            int audioStreamId = -1;

            for (int i = 0; i < numStreams; i++)
            {
                  // Find the stream object
                  IStream stream = container.getStream(i);
                  // Get the pre-configured decoder that can decode this stream;
                  IStreamCoder coder = stream.getStreamCoder();

                  //si le premier élément est audio alors t = true sinon t = false
                  if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO)
                  {
                      if (count == n)
                      {
                          //on commence la lecture an plein milieu du son
                          //container.seekKeyFrame(i, dur/2, container.SEEK_FLAG_BYTE);
                          format = coder.getSampleFormat();

                          audioCoder = coder;
                          audioStreamId = i;

                          break;
                      }
                      count += 1;
                  }
             }
            if (audioCoder.open() < 0)
                throw new RuntimeException("could not open audio decoder for container: "+f);

            int sr = container.getStream(audioStreamId).getStreamCoder().getSampleRate();
            zoomFactor = (int) Math.round(220.*sr/11630.);

            long dur = container.getDuration();//en microsecondes
            samples = new int[(int)(dur*sr/(1000*1000))];
            //openJavaSound(audioCoder);


            /*
             * Now, we start walking through the container looking at each packet.
             */
            IPacket packet = IPacket.make();
            //on parcours tout le fichier f
            while(container.readNextPacket(packet) >= 0 && !stopThread)
            {

                      /*
                       * Now we have a packet, let's see if it belongs to our audio stream
                       */
                      //on s'assure que le packet lu correspond au bon stream
                      if (packet.getStreamIndex() == audioStreamId)
                      {
                        /*
                         * We allocate a set of samples with the same number of channels as the
                         * coder tells us is in this buffer.
                         *
                         * We also pass in a buffer size (1024 in our example), although Xuggler
                         * will probably allocate more space than just the 1024 (it's not important why).
                         */
                        IAudioSamples samples = IAudioSamples.make(1024, audioCoder.getChannels());

                        /*
                         * A packet can actually contain multiple sets of samples (or frames of samples
                         * in audio-decoding speak).  So, we may need to call decode audio multiple
                         * times at different offsets in the packet's data.  We capture that here.
                         */
                        int offset = 0;

                        /*
                         * Keep going until we've processed all data
                         */
                        while(offset < packet.getSize())
                        {
                          //if i remove this line, no more audio glitches
                          int bytesDecoded = audioCoder.decodeAudio(samples, packet, offset);
                          if (bytesDecoded < 0)
                            throw new RuntimeException("got error decoding audio in: " + f);
                          offset += bytesDecoded;

                          /*
                           * Some decoder will consume data in a packet, but will not be able to construct
                           * a full set of samples yet.  Therefore you should always check if you
                           * got a complete set of samples from the decoder
                           */
                          if (!stopThread)
                          if(samples.isComplete())
                          {
                            makeWaveform(samples);

                            currentPlayTime += samples.getNumSamples();
                            //System.out.println("max = "+48000*container.getDuration()/1000000 + " current = "+currentPlayTime);
                          }
                        }
                      }
                      else
                      {
                        /*
                         * This packet isn't part of our audio stream, so we just silently drop it.
                         */

                      }
                  }

         }
         }
    }
public类线程{
字符串f;
int n;
DrawWaveform(最终字符串文件,最终int nstream)
{
这是设置优先级(10);
f=文件;
n=n流;
}
公开募捐{
stopThread=false;
{
IContainer容器=IContainer.make();
container.open(f,IContainer.Type.READ,null);
//查询要打开的调用找到了多少流
int numStreams=container.getNumStreams();
整数计数=0;
IStreamCoder音频编码器=空;
int audioStreamId=-1;
for(int i=0;i=0&&!stopThread)
{
/*
*现在我们有了一个数据包,让我们看看它是否属于我们的音频流
*/
//关于s'quele包lu-au-bon流
if(packet.getStreamIndex()==audioStreamId)
{
/*
*我们分配一组样本,样本数量与
*编码器告诉我们它在这个缓冲区中。
*
*我们还传入一个缓冲区大小(在我们的示例中为1024),尽管Xuggler
*可能会分配比1024更多的空间(为什么不重要)。
*/
IAudioSamples samples=IAudioSamples.make(1024,audioCoder.getChannels());
/*
*一个数据包实际上可以包含多组样本(或样本帧)
*在音频解码中,我们可能需要调用decode audio multiple
*数据包数据中不同偏移量的时间。我们在这里捕获它。
*/
整数偏移=0;
/*
*继续,直到我们处理完所有数据
*/
while(偏移量
如果我删除所需的解码音频线路,我也会删除故障

我试图更改线程的优先级,但没有成功。我还试图改变缓冲区的大小,相同

那么,有没有办法避免这种情况


感谢大家检查一下:你确定是
解码音频
造成的(使用评测还是其他什么)?如果没有,如果你解码音频,但不绘制波形会发生什么