当前位置: 首页 > 知识库问答 >
问题:

使用MediaCodec和MediaMuxer将PCM编码为AAC时没有音频

游安康
2023-03-14

我正在使用MediaCodec将PCM数据转换为AAC,并使用MediaMuxer将此aac数据存储到m4a文件中。没有视频。

该文件会生成,甚至会播放。但是没有声音。如果我将aac文件导入Audacity,它不会显示任何数据。音频的长度甚至是预期的时间。我知道数据正在被编码,尽管我不确定这些数据是否被正确编码。

对pcm数据进行编码:

audioEncoder.setCallback(object : MediaCodec.Callback() {

    override fun onInputBufferAvailable(mc: MediaCodec, inputBufferId: Int) {
        updateRemoveAudioBufferIndex(inputBufferId)
    }

    override fun onOutputBufferAvailable(mc: MediaCodec, outputBufferId: Int, bufferInfo: MediaCodec.BufferInfo) {
        val outputBuffer = mc.getOutputBuffer(outputBufferId)

        if (bufferInfo.flags == MediaCodec.BUFFER_FLAG_CODEC_CONFIG) {
            audioEncoder.releaseOutputBuffer(outputBufferId, false)
            return
        }

        if (bufferInfo.size > 0) {
            outputBuffer?.position(bufferInfo.offset);
            outputBuffer?.limit(bufferInfo.offset + bufferInfo.size)

            muxer!!.writeSampleData(audioTrackIndex, outputBuffer!!, bufferInfo)
            audioEncoder.releaseOutputBuffer(outputBufferId, false)
        }

        if (bufferInfo.flags == BUFFER_FLAG_END_OF_STREAM) {
            cleanupAudioEncoder()
        }

    }

    override fun onError(mc: MediaCodec, ex: MediaCodec.CodecException) {
    }

    override fun onOutputFormatChanged(mc: MediaCodec, mf: MediaFormat) {
        audioTrackIndex = muxer!!.addTrack(audioEncoder.outputFormat)
        startMuxer()
    }
})

val format = MediaFormat()
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm")
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1)
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 32000)
format.setInteger(MediaFormat.KEY_BIT_RATE, 128000)
format.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC)

audioEncoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE)
audioEncoder.start()


fun encodeAudio(pcmData: ByteBuffer) {
    if (audioInputBufferIds.isNotEmpty()) {
        val bufferId = updateRemoveAudioBufferIndex()
        val buffer = audioEncoder.getInputBuffer(bufferId) as ByteBuffer
        buffer.clear()
        buffer.put(pcmData)

        val flags = if (encodingStopped) BUFFER_FLAG_END_OF_STREAM else 0

        audioEncoder.queueInputBuffer(bufferId, 0, pcmData.capacity(), presentationTimeAudio.toLong(), flags)
        presentationTimeAudio += bufferIntervalInMicroseconds
    }
}

我已经浏览了大量示例,我所做的一切似乎都是正确的。如果我在onOutputBuffer可用函数中放置断点,很明显我正在接收编码数据。

共有1个答案

弓温书
2023-03-14

事实证明,将数据放入缓冲区后需要倒回缓冲区:

buffer.put(pcmData)
buffer.rewind()

老实说,我对我遇到的使用buffer.put但从不调用倒带的示例应用程序的数量感到非常惊讶。为什么它们甚至可以工作,我不明白。倒带时的留档声明如下:

回退此缓冲区。位置设置为零并丢弃标记。假设限制已适当设置,请在一系列通道写入或获取操作之前调用此方法。

https://docs.oracle.com/javase/7/docs/api/java/nio/Buffer.html#rewind()

MediaCodec希望缓冲区在开始编码之前指向位置0。因为我没有调用rewind,put函数导致缓冲区位于最后一个位置,因此MediaCodec认为这意味着没有数据要编码。奇怪的是,当编解码器没有提供编码数据时,MediaMuxer甚至会费心写出数据。

 类似资料:
  • 我正在修改一个Android框架示例,将MediaCodec生成的基本AAC流打包成一个独立的。mp4文件。我使用的是一个实例,其中包含一个由实例生成的AAC曲目。 然而,我总是最终得到一个错误消息调用:

  • 我正在尝试使用使用编解码器对一些音频流进行编码。为此,我使用了google cts ExtractEncodeMust的这个实现。 对于某些aac文件,它会在编码某些帧后抛出。更准确地说,它会在第1030行抛出异常,。 我正在配置如下: 我完全不知道如何解决这个问题。任何形式的帮助都将不胜感激。 带有一些日志的堆栈跟踪: 设备:小米POCO x3 操作系统:Android10 导致溢出的示例文件信

  • 我正在尝试使用android AudioRecord和MediaCodec对aac音频进行编码。我创建了一个非常类似于(使用Android MediaCodec从相机编码H.264)的编码器类。使用此类,我创建了一个AudioRecord实例,并告诉它将其byte[]数据读出到AudioEncoder(audioEncoder.offerEncoder(Data))。 这是我的音频记录设置 我成功

  • 我正在使用Android中的一个媒体编解码器类(Jelly Bean)将PCM格式编码为AAC。该文件已编码,但没有音乐播放器能够播放该文件。我在网上找不到任何工作代码或适当的文档。 这是我的代码:

  • 问题很简单,但我没有任何线索来解决它: 我编写一行代码来在我的Nexus 4(Android 4.4.2)上创建AAC编码器 保存在“codec”中的返回值不为空,但我在Logcat中收到一条红色错误消息: 我还尝试了另一条线: 并得到相同的错误结果。 在使用MediaCodec之前,我是否错过了任何初始化步骤?我在官方文档中没有找到有关此的任何信息。 有人遇到过这个问题吗? 实际上,我正在尝试将

  • 我能够在MediaCodec和MediaMuxer的帮助下录制(编码)视频。接下来,我需要在MediaCodec和MediaMuxer的帮助下处理音频部分和带视频的mux音频。 我面临两个问题: > 如何将音频和视频数据传递给MediaMuxer(因为writeSampleData()方法一次只接受一种类型的数据)? 我提到了MediaMuxerTest,但它使用的是MediaExtractor。