3

I'm working on adding a live broadcasting feature to an Android app. I do so through RTMP and make use of the DailyMotion Android SDK, which in turn makes use of Kickflip.

Everything works perfect, except for the playback of the audio on the website (which makes use of Flash). The audio does work in VLC, so it seems to be an issue with Flash being unable to decode the AAC audio.

For the audio I instantiate an encoder with the "audio/mp4a-latm" mime type. The Android developer docs state the following about this mime type: "audio/mp4a-latm" - AAC audio (note, this is raw AAC packets, not packaged in LATM!). I expect that my problem lies here, but yet I have not been able to find a solution for it.

Pretty much all my research, including this SO question about the matter pointed me in the direction of adding an ADTS header to the audio byte array. That results in the following code in the writeSampleData method:

boolean isHeader = false;
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
    isHeader = true;
} else {
    pts = bufferInfo.presentationTimeUs - mFirstPts;
}

if (mFirstPts != -1 && pts >= 0) {
    pts /= 1000;

    byte data[] = new byte[bufferInfo.size + 7];
    addADTStoPacket(data, bufferInfo.size + 7);
    encodedData.position(bufferInfo.offset);
    encodedData.get(data, 7, bufferInfo.size);

    addDataPacket(new AudioPacket(data, isHeader, pts, mAudioFirstByte));
}

The addADTStoPacket method is identical to the one in the above mentioned SO post, but I will show it here regardless:

private void addADTStoPacket(byte[] packet, int packetLen) {
    int profile = 2;  //AAC LC
    //39=MediaCodecInfo.CodecProfileLevel.AACObjectELD;
    int freqIdx = 4;  //44.1KHz
    int chanCfg = 1;  //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;
}

The variables in the above method match the settings I have configured in the application, so I'm pretty sure that's fine.

The data is written to the output stream in the following method of the AudioPacket class:

@Override
public void writePayload(OutputStream outputStream) throws IOException {
    outputStream.write(mFirstByte);
    outputStream.write(mIsAudioSpecificConfic ? 0 : 1);
    outputStream.write(mData);
}

Am I missing something here? I could present more code if necessary, but I think this covers the most related parts. Thanks in advance and I really hope someone is able to help, I've been stuck for a couple of days now...

Community
  • 1
  • 1
user1796440
  • 366
  • 3
  • 11
  • Because I have not been able to resolve this issue and both my research and my question did not lead to an answer, I have looked for an alternative way to solve this. I decided to drop the DailyMotion SDK and made some modifications to the FFmpegMuxer. Because the FFmpegWrapper of Kickflip did not work, I had to make adjustments to the C file and compile it afterwards. Because it needed the FFmpeg library, I compiled that as well as Libx264. This way I was able to get the audio working. – user1796440 May 04 '16 at 16:58

0 Answers0