【问题标题】:MediaCodec - downsampled audio from 48k Hz to 44.1k Hz still plays at slower speedMediaCodec - 从 48k Hz 到 44.1k Hz 的下采样音频仍以较慢的速度播放
【发布时间】:2017-02-27 14:07:37
【问题描述】:

到目前为止,在我使用 MediaCodec 连接视频的过程中,我终于设法将 48k Hz 音频重新采样为 44.1k Hz。

我一直在测试将视频与两个视频连接在一起,第一个视频具有 22050 Hz 2 通道格式的音轨,第二个具有 24000 Hz 1 通道格式的音轨。由于我的解码器只为第一个视频输出 44100 Hz 2 通道原始音频,为第二个视频输出 48000 Hz 2 通道原始音频,我使用此方法将第二个视频的解码器输出的 ByteBuffers 从 48000 Hz 重新采样到 44100 Hz:

private byte[] minorDownsamplingFrom48kTo44k(byte[] origByteArray)
{
    int origLength = origByteArray.length;
    int moddedLength = origLength * 147/160;
    //int moddedLength = 187*36;
    int delta = origLength - moddedLength;
    byte[] resultByteArray = new byte[moddedLength];
    int arrayIndex = 0;
    for(int i = 0; i < origLength; i+=44)
    {
        for(int j = i; j < (i+40 > origLength ? origLength : i + 40); j++)
        {
            resultByteArray[arrayIndex] = origByteArray[j];
            arrayIndex++;
        }
        //Log.i("array_iter", i+" "+arrayIndex);
    }
    //smoothArray(resultByteArray, 3);
    return resultByteArray;
}

但是,在输出视频文件中,视频在到达具有下采样音轨的第二个视频时播放速度较慢。音调相同,噪音消失了,但音频样本播放速度变慢了。

我的输出格式实际上是 22050 Hz 2 通道,在第一个视频之后。

编辑:就好像播放器仍然播放音频,就好像它具有 48000 Hz 的采样率,即使它被下采样到 44100 Hz。

我的问题:

  1. 如何缓解此问题?因为我认为在这种情况下更改时间戳不起作用。我只是使用解码器提供的时间戳,并根据第一个视频的最后一个时间戳进行一些偏移。
  2. 问题是否与 CSD-0 ByteBuffers 相关?
  3. 如果MediaCodec 可以选择动态更改视频比特率,那么动态更改音频采样率或通道数的新功能是否可行?

【问题讨论】:

    标签: android audio android-mediacodec


    【解决方案1】:

    事实证明,这就像限制我的 ByteBuffers 的大小一样简单。

    解码器输出 8192 字节(2048 个样本)。

    下采样后,数据变为 7524 字节(1881 个样本)——原本是 7526 字节,但总计 1881.5 个样本,所以我将其向下取整。

    主要错误是在这段代码中,我必须使采样率接近原始:

    byte[] finalByteBufferContent = new byte[size / 2]; //here
    
    for (int i = 0; i < bufferSize; i += 2) {
        if ((i + 1) * ((int) samplingFactor) > testBufferContents.length) {
            finalByteBufferContent[i] = 0;
            finalByteBufferContent[i + 1] = 0;
        } else {
            finalByteBufferContent[i] = testBufferContents[i * ((int) samplingFactor)];
            finalByteBufferContent[i + 1] = testBufferContents[i * ((int) samplingFactor) + 1];
        }
    }
    
    bufferSize = finalByteBufferContent.length;
    

    其中size 是解码器输出ByteBuffer 的长度,testBufferContents 是我用来修改其内容的字节数组(并且是下采样到 7524 字节的那个)。

    生成的字节数组的长度仍然是 4096 字节而不是 3762 字节。

    new byte[size / 2] 更改为new byte[testBufferContents.length / 2] 解决了这个问题。

    【讨论】:

      猜你喜欢
      • 2013-08-04
      • 1970-01-01
      • 2013-11-18
      • 2020-10-27
      • 1970-01-01
      • 1970-01-01
      • 2012-07-26
      • 1970-01-01
      • 2018-09-30
      相关资源
      最近更新 更多