gpt4 book ai didi

java - SourceDataLine.start() 将对象清空

转载 作者:行者123 更新时间:2023-11-30 04:40:05 26 4
gpt4 key购买 nike

这是具有症状的代码:

      /*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.zove.xuggleraudio;

import com.xuggle.xuggler.IAudioSamples;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IStream;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IPacket;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;

import javax.sound.sampled.SourceDataLine;

/**
* Class that represents an audio player with the expected
* controls (start, stop, pause, resume).
* @author Mciavilli
*/
public class Audio
{
//The name of the file to be played
private final String filename;
//Our connection to the mixer
private final SourceDataLine mLine;
//The index of the audio stream inside the file
private final int audioId;
//Xuggler media container
private final IContainer container;
//The stream decoder
private final IStreamCoder streamCoder;

/*
* Constructor that takes a String argument
*/
public Audio(String filename)
{
this.filename = filename;
//Create Xuggler container object
this.container = IContainer.make();
//Open the container
if(container.open(filename, IContainer.Type.READ, null) < 0)
throw new IllegalArgumentException("Invalid file name: " + this.filename);
//find the audio stream within contained streams
this.audioId = getAudioId(container);
//get the audio stream
IStream stream = container.getStream(audioId);
//get the stream decoder
this.streamCoder = stream.getStreamCoder();
//open the stream decoder
if (this.streamCoder.open() < 0)
throw new RuntimeException("could not open audio decoder for container: "
+ filename);
//Get a pipe to the sound mixer
this.mLine = readySoundSystem(streamCoder);
}

private int getAudioId(IContainer container)
{
//see how many streams are there
int numStreams = container.getNumStreams();
int audioId = -1;
for(int i = 0; i < numStreams ; i++)
{
IStream stream = container.getStream(i);
IStreamCoder streamCoder = stream.getStreamCoder();
if(streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO)
audioId = i;
break;
}//end for statement
//No audio stream found
if(audioId == -1)
throw new RuntimeException("Failed to find an audio stream in:" +
this.filename);

return audioId;
}//end method getAudioId

private SourceDataLine readySoundSystem(IStreamCoder aAudioCoder)
{
AudioFormat audioFormat = new AudioFormat(aAudioCoder.getSampleRate(),
(int)IAudioSamples.findSampleBitDepth(aAudioCoder.getSampleFormat()),
aAudioCoder.getChannels(),
true, /* xuggler defaults to signed 16 bit samples */
false);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
try
{
SourceDataLine mLine = (SourceDataLine) AudioSystem.getLine(info);
/**
* if that succeeded, try opening the line.
*/
mLine.open(audioFormat);
/**
* And if that succeed, start the line.
*/
mLine.start();
}
catch (LineUnavailableException e)
{
throw new RuntimeException("could not open audio line");
}
return mLine;
}//end method readySoundSystem
/*
* starts playing the file.
* returns true if successful.
* should be called only once per Audio object
*/
public boolean start()
{
if(!mLine.isActive())
{
IPacket packet = IPacket.make();
while(container.readNextPacket(packet) >= 0)
{
/*
* Now we have a packet, let's see if it belongs to our audio stream
*/
if (packet.getStreamIndex() == this.audioId)
{
/*
* 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, this.streamCoder.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())
{
int bytesDecoded = this.streamCoder.decodeAudio(samples, packet, offset);
if (bytesDecoded < 0)
throw new RuntimeException("got error decoding audio in: " + filename);
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 (samples.isComplete())
{
playSound(samples);
}
}//end inner while block
}//end inner if block
else
{
/*
* This packet isn't part of our audio stream, so we just silently drop it.
*/
do {} while(false);
}//end else block
}//end outer while block
//success!
return true;
}//end outer if block
//The sound is already playing
return false;
}//end method start

private void playSound(IAudioSamples aSamples)
{
/**
* We're just going to dump all the samples into the line.
*/
byte[] rawBytes = aSamples.getData().getByteArray(0, aSamples.getSize());
this.mLine.write(rawBytes, 0, aSamples.getSize());
}//end method playJavaSound

/*
* stops the playback
* returns true if suucessful
*/
public boolean stop()
{
if(mLine.isActive())
{
this.mLine.stop();
return true;
}
return false;
}

public static void main(String args[]) throws InterruptedException
{
if(args.length != 1)
throw new IllegalArgumentException("illegal arguments passed");
Audio audio = new Audio(args[0]);
audio.start();
Thread.sleep(10 * 1000);
audio.stop();
}

}//end class Audio

导致问题的行是第 104 行:

mLine.start();

当我检查调试器时,mLine 对象(SourceDataLine 对象)在执行该行之前一直正常,这会导致 mLine 等于“null”。

我认为这个问题和here是一样的.

我还尝试使用 Clip 而不是 SourceDataLine,但最终遇到了相同的问题。

有趣的是,这个问题并没有发生在 original Xuggler program 中。 ,并且调用 start() 并没有产生那么糟糕的效果。

最佳答案

您有一个成员变量 mLine 和一个局部变量 mLine。只有后者才会被分配。当它超出范围时,您在调试器中看到的是成员变量,它仍然为空。

关于java - SourceDataLine.start() 将对象清空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12503719/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com