0

1 つのスレッドを使用して波形を描画し、もう 1 つのスレッドを使用してオーディオを再生します。唯一の問題は、再生時に音声が途切れることです。これは、decodeAudio 手順に起因します。

ここに私の波形描画クラスがあります:

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.
                         */

                      }
                  }

         }
         }
    }

必要なdecodeAudio行を削除すると、グリッチも削除されます。

スレッドの優先順位を変更しようとしましたが、うまくいきませんでした。同じように、バッファサイズも変更しようとしました。

それで、これを避ける方法はありますか?

本当にありがとう

4

1 に答える 1

0

確認するだけです:本当にdecodeAudio責任がありますか(プロファイリングなどを使用して)?そうでない場合、オーディオをデコードして波形を描画しないとどうなりますか?

于 2012-08-24T09:34:50.730 に答える