gpt4 book ai didi

java - 如何在android中合并两个音频文件

转载 作者:行者123 更新时间:2023-12-03 02:38:29 25 4
gpt4 key购买 nike

关闭。这个问题需要更多 focused .它目前不接受答案。












想改进这个问题?更新问题,使其仅关注一个问题 editing this post .

7年前关闭。




Improve this question




我有 2 个音频文件。第一个是背景音乐,第二个是演讲。 (每篇约4分钟)

现在我想将它们混合起来,并收到一个带有背景音乐的 4 分钟演讲。

最佳答案

您不需要 FFMPEG,您可以使用 android 中可用的标准编解码器。

   public void playFile(String fileToPlay)
{
// see where we find a suitable autiotrack
MediaExtractor extractor = new MediaExtractor();
try
{
extractor.setDataSource(fileToPlay);
}
catch (IOException e)
{
out.release();
return;
}
extractor.selectTrack(0);

String fileType=typeForFile(fileToPlay);
if (fileType==null)
{
out.release();
extractor.release();
return;
}

MediaCodec codec = MediaCodec.createDecoderByType(fileType);
MediaFormat wantedFormat=extractor.getTrackFormat(0);
codec.configure(wantedFormat,null,null,0);
codec.start();

ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();

// Allocate our own buffer
int maximumBufferSizeBytes = 0;
for(ByteBuffer bb:outputBuffers)
{
int c=bb.capacity();
if (c>maximumBufferSizeBytes) maximumBufferSizeBytes=c;
}
setupBufferSizes(maximumBufferSizeBytes/4);

final MediaCodec.BufferInfo bufferInfo=new MediaCodec.BufferInfo();
MediaFormat format=null;
while(true)
{
long timeoutUs=1000000;
int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
if (inputBufferIndex >= 0)
{
ByteBuffer targetBuffer = inputBuffers[inputBufferIndex];
int read = extractor.readSampleData(targetBuffer, 0);
int flags=extractor.getSampleFlags();
if (read>0)
codec.queueInputBuffer(inputBufferIndex, 0,read, 0, flags);
else
codec.queueInputBuffer(inputBufferIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
extractor.advance();
}

int outputBufferIndex = codec.dequeueOutputBuffer(bufferInfo,timeoutUs);
if (outputBufferIndex >= 0)
{
final boolean last = bufferInfo.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM;

int s=bufferInfo.size/4;
ByteBuffer bytes=outputBuffers[outputBufferIndex];
((ByteBuffer)bytes.position(bufferInfo.offset)).asShortBuffer().get(shorts,0,s*2);
process(shorts,0,s*2);

codec.releaseOutputBuffer(outputBufferIndex, false);
if (last)
break;
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
{
outputBuffers = codec.getOutputBuffers();
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
{
format = codec.getOutputFormat();
}
}

extractor.release();
codec.stop();
codec.release();

上面的代码处理 1 个文件的读取。 “处理”例程(尚未定义)接收交错的样本数组(左/右/左/右/左/右)。您现在需要做的就是将这些 channel 添加到目标缓冲区。例如
short[] target=new short[LENGTH OF 4 MINUTES];
int idx=0;
process(short[] audio, int l)
{
for(int i=0;i<l;i++)
target[idx++]+=audio[i]/2;
}

生成的目标数组随后包含您的叠加样本。

关于java - 如何在android中合并两个音频文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24631602/

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