我使用一个线程绘制波形,另一个线程播放音频。唯一的问题是我在播放时有音频卡顿,它来自 decodeAudio 过程:audioCoder.decodeAudio(samples, packet, offset);
这是我的波形绘图课:
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 线,我也会删除故障。
我试图改变线程的优先级,但没有运气。我也尝试更改缓冲区大小,相同。
那么,有没有办法避免这种情况?
谢谢一堆