【问题标题】:How to combine two audio files on top of each other in android [closed]如何在android中合并两个音频文件[关闭]
【发布时间】:2014-08-29 04:12:58
【问题描述】:

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

现在我想将它们混合起来,并获得一个 4 分钟的演讲和背景音乐。

【问题讨论】:

  • -1 你不应该来这里让人们为你做你的工作。发布您尝试过的代码以及您认为错误的地方,并提供有用的信息,例如堆栈跟踪和输出
  • 亲爱的斯图!这只是我项目的一小部分。我的项目几乎完成了,我只是被我项目的这一部分困住了。如果您搜索有关此主题的 Stack,您可以找到 20 多个问题和答案,我几乎尝试了所有这些,但没有一个帮助我。我使用“完整”一词的目的是给出一个清晰正确的答案,而不是说使用“FFMPEG”库。说一下如何使用这个库
  • 我为这个问题获得了赏金,但你回答晚了,赏金已过期。现在没有选择把它交给你。您的答案也适用于 1 个音频而不是 2 个音频,这对我来说是模棱两可的。但我给了你“正确答案打勾”以表示感谢而不是你的不尊重。祝你好运
  • 你从这个星球上消失不是我的问题。我在截止日期前一天,所以请联系版主来奖励该赏金。我给出的答案向您展示了如何加载 android 编解码器支持的任何音频。第二部分解释了如何叠加两个音轨。
  • 这个问题似乎是题外话,因为它是关于要求一个免费的开发人员。

标签: java android audio


【解决方案1】:

您不需要 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个文件的读取。 “处理”例程(尚未定义)接收交错的样本数组(左/右/左/右/左/右)。您现在需要做的就是将这些通道添加到目标缓冲区。例如

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

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

【讨论】:

    【解决方案2】:

    要合并两个音频文件,您必须使用为 Android 编译的 FFMPEG util。 以下是我找到的一些关于为 android 编译 FFMPEG 的链接:

    1. How to Build FFmpeg for Android
    2. Download FFMPEG library for Android (SourceForge)

    Here 是关于如何在 android 中使用 FFMPEG 库来合并 2 个音频文件的 Google 群组线程。

    也请查看this SO 帖子。 希望对您有所帮助。

    【讨论】:

    • 给出一个样本或完整的答案。我已经对其进行了测试,并且无法使用该 lib 。你给我的那个库也是用于 C# 而不是 java(但我有那个 java lib 但不能使用它)
    • @Sadegh 很高兴看到一点赞赏!
    • 我知道,当我们连续几天偶然发现一个问题时,这很令人沮丧。我刚刚搜索了它并给了你一些指示,以便你可以尝试一下。至少展示您尝试过的内容以及遇到的问题!
    猜你喜欢
    • 1970-01-01
    • 2015-06-22
    • 2016-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    相关资源
    最近更新 更多