如何在两个音频文件在机器人彼此的顶部相结合 [英] How to combine two audio files on top of each other in android

查看:154
本文介绍了如何在两个音频文件在机器人彼此的顶部相结合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个音频文件。第一是背景音乐和第二个是一个讲话。 (他们每个人都在约4分钟长度)

I have 2 audio files. the first is background music and the second is a speech. (Each of them is about 4 minutes in length)

现在我想将它们混合并获得4分钟的演讲用的背景音乐。

Now I want to mix them and receive a 4 minute speech with a background music.

推荐答案

您不需要FFmpeg中,可以使用现有的标准codeCS在android系统。

You don't need FFMPEG, you can use the standard codecs available in 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文件看完上面的code交易。的进程例程(其尚未定义)接收采样的交错阵列(左/右/左/右/左/右)。所有你现在需要做的就是添加这些渠道的目标缓冲区。例如

The above code deals with the reading of 1 file. The 'process' routine (which isn't defined yet) receives an interleaved array of samples (left/right/left/right/left/right). All you need to do now is add these channels to a target buffer. E.g

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;
}

然后将得到的目标阵列包含您的覆盖样本。

The resulting target array contains then your overlaid samples.

这篇关于如何在两个音频文件在机器人彼此的顶部相结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆