How can I package raw AAC-data into a MPEG2-TS stream?
I'm continuous recoding (microphone) & compressing PCM-audio inside Android to 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);
As this produces a raw, headless AAC, I'm also adding the required MPEG-headers for each frame:
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;
}
This is working fine and I can play the created AAC-files eg. with VLC or the Google Music Player.
Now my question:
I would like to send the encoded data as a HTTP LIVE STREAM (HLS) to some renderers like I'm already doing it with WAV and MP3-streams.
But if I'm sending it to an Android-app, the stream does not start to play, until I interrupt the recording and therefor flushing/finishing the stream. No problems with MP3, here the playback is starting after seconds.
Regarding the "Supported Media Types"-page of Android, HLS is only supported on
HTTP/HTTPS live streaming draft protocol: MPEG-2 TS media files only
Who can tell me, how to package the raw AAC-stream into an MPEG-2 TS-stream rather than into a MPEG4-stream like now?
I'm new at this area, please excuse mistakes.
You sort of answer your own question. You need to set the ADTS version to MPEG2 instead of MPEG4. packet[1] = (byte) 0xF1;
Also packet[6] = (byte) 0xFC;
is correct unless you know the buffer fullness value.
see more here: http://wiki.multimedia.cx/index.php?title=ADTS