代码之家  ›  专栏  ›  技术社区  ›  Martin L.

Android PCM->AAC=M4A vs.MPEG2-TS

  •  0
  • Martin L.  · 技术社区  · 10 年前

    如何将原始AAC数据打包成MPEG2-TS流?

    我正在连续录制(麦克风)&将Android中的PCM音频压缩为AAC:

        encoder = MediaCodec.createEncoderByType("audio/mp4a-latm");
        MediaFormat format = new MediaFormat();
        format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
        format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2);
        format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
        format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024);
        format.setInteger(MediaFormat.KEY_AAC_PROFILE,
                MediaCodecInfo.CodecProfileLevel.AACObjectLC);
        encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
    

    当这产生一个原始的无头AAC时,我还为每个帧添加了所需的MPEG标题:

        private void addADTStoPacket(byte[] packet, int packetLen) {
        int profile = 2; // M4A LC
                            // 39=MediaCodecInfo.CodecProfileLevel.AACObjectELD;
        int freqIdx = 4; // 44.1KHz
        int chanCfg = 2; // CPE
    
        // fill in ADTS data
        packet[0] = (byte) 0xFF;
        packet[1] = (byte) 0xF9;
        packet[2] = (byte) (((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2));
        packet[3] = (byte) (((chanCfg & 3) << 6) + (packetLen >> 11));
        packet[4] = (byte) ((packetLen & 0x7FF) >> 3);
        packet[5] = (byte) (((packetLen & 7) << 5) + 0x1F);
        // packet[6] = (byte) 0xFC;
        packet[6] = (byte) 0x00;// number of frames = 1;
    }
    

    这很好,我可以用VLC或谷歌音乐播放器播放创建的AAC文件。

    现在我的问题是:

    我想将编码数据作为HTTP LIVE STREAM(HLS)发送给一些渲染器,就像我已经在使用WAV和MP3流一样。

    但如果我将其发送到Android应用程序,则流不会开始播放,直到我中断录制并因此刷新/完成流。MP3没有问题,这里的播放在几秒钟后开始。

    关于“ Supported Media Types “-Android的页面,HLS仅在

    HTTP/HTTPS实时流传输草案协议:仅限MPEG-2 TS媒体文件

    谁能告诉我,如何将原始AAC流打包成MPEG-2 TS流,而不是像现在这样打包成MPEG4流?

    我是这个领域的新手,请原谅错误。

    1 回复  |  直到 10 年前
        1
  •  0
  •   szatmary    10 年前

    你可以回答自己的问题。您需要将ADTS版本设置为MPEG2而不是MPEG4。 packet[1] = (byte) 0xF1;

    而且 packet[6] = (byte) 0xFC; 是正确的,除非您知道缓冲区填充度值。

    在此处查看更多信息: http://wiki.multimedia.cx/index.php?title=ADTS