gpt4 book ai didi

java - 使用 Xuggler 进行音频转换

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:54:39 26 4
gpt4 key购买 nike

我正在尝试使用 Java 中的 Xuggler 将 aac/wav/wma 音频文件转换为 mp3。

不幸的是,我的质量损失很大。我的输入文件大小约为 7MB,输出文件大小仅为 1.5MB。

采样率设置为44100Hz,是否还有其他参数需要设置?

感谢您的回答。

  if (args.length <= 1)
throw new IllegalArgumentException("must pass an input filename and output filename as argument");

IMediaWriter writer = ToolFactory.makeWriter(args[1]);

String filename = args[0];

// Create a Xuggler container object
IContainer container = IContainer.make();

// Open up the container
if (container.open(filename, IContainer.Type.READ, null) < 0)
throw new IllegalArgumentException("could not open file: " + filename);

// query how many streams the call to open found
int numStreams = container.getNumStreams();

// and iterate through the streams to find the first audio stream
int audioStreamId = -1;
IStreamCoder audioCoder = null;
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();

if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO)
{
audioStreamId = i;
audioCoder = coder;
audioCoder.setBitRate(container.getBitRate());

break;
}
}

if (audioStreamId == -1)
throw new RuntimeException("could not find audio stream in container: "+filename);

/* We read only AAC file for the moment */
if(audioCoder.getCodecID() != ICodec.ID.CODEC_ID_AAC
&& audioCoder.getCodecID() != ICodec.ID.CODEC_ID_WAVPACK
&& audioCoder.getCodecID() != ICodec.ID.CODEC_ID_WMAV1
&& audioCoder.getCodecID() != ICodec.ID.CODEC_ID_WMAV2
&& audioCoder.getCodecID() != ICodec.ID.CODEC_ID_WMAPRO
&& audioCoder.getCodecID() != ICodec.ID.CODEC_ID_WMAVOICE)
{
System.out.println("Read only AAC, WAV or WMA files");
System.exit(1);
}

audioCoder.setSampleFormat(IAudioSamples.Format.FMT_S16);
/*
* Now we have found the audio stream in this file. Let's open up our decoder so it can
* do work.
*/
if (audioCoder.open() < 0)
throw new RuntimeException("could not open audio decoder for container: "+filename);

int streamIndex = writer.addAudioStream(0, 0, audioCoder.getChannels(), audioCoder.getSampleRate());


System.out.println("audio Frame size : "+audioCoder.getAudioFrameSize());


/*
* Now, we start walking through the container looking at each packet.
*/
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() == 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(512, audioCoder.getChannels(),IAudioSamples.Format.FMT_S16 );

/*
* 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 = audioCoder.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())
{
writer.encodeAudio(streamIndex, samples);
}
}
}
else
{
/*
* This packet isn't part of our audio stream, so we just silently drop it.
*/
do {} while(false);
}
}

最佳答案

我会做这样的事情:

public void convertToMP3(File input, File output, int kbps) { //modify on your convenience
// create a media reader
IMediaReader mediaReader = ToolFactory.makeReader(input.getPath());

// create a media writer
IMediaWriter mediaWriter = ToolFactory.makeWriter(output.getPath(), mediaReader);

// add a writer to the reader, to create the output file
mediaReader.addListener(mediaWriter);

// add a IMediaListner to the writer to change bit rate
mediaWriter.addListener(new MediaListenerAdapter() {
@Override
public void onAddStream(IAddStreamEvent event) {
IStreamCoder streamCoder = event.getSource().getContainer().getStream(event.getStreamIndex()).getStreamCoder();
streamCoder.setFlag(IStreamCoder.Flags.FLAG_QSCALE, false);
streamCoder.setBitRate(kbps);
streamCoder.setBitRateTolerance(0);
}
});

// read and decode packets from the source file and
// and dispatch decoded audio and video to the writer
while (mediaReader.readPacket() == null);
}

输入是您要转换的文件 (aac/wav/wma),输出是一个新的 .mp3 文件(Xuggler 通过扩展名确定转换)。

您可以通过增加 kbps 来提高质量(即对于 320 kbps,您需要传入 320000)。

希望对您有所帮助:-)

仅供引用:对于 Java 项目,您需要导入以下内容(如果您尚未导入):

import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.event.IAddStreamEvent;
import com.xuggle.xuggler.IStreamCoder;

关于java - 使用 Xuggler 进行音频转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6899492/

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