From 59c44af4cb391a7bfd223f36b357cf74274fbd9d Mon Sep 17 00:00:00 2001 From: Tyler Roach Date: Thu, 13 Apr 2017 14:56:22 -0400 Subject: [PATCH 1/2] Added mp3 support to FLV extractor --- .../extractor/flv/AudioTagPayloadReader.java | 55 ++++++++++++++----- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java index 3ee87b47ea..2fc586ce22 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java @@ -15,6 +15,7 @@ */ package com.google.android.exoplayer2.extractor.flv; +import android.util.Log; import android.util.Pair; import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.Format; @@ -29,6 +30,9 @@ import java.util.Collections; */ /* package */ final class AudioTagPayloadReader extends TagPayloadReader { + private static final String TAG = "AudioTagPayloadReader"; + + private static final int AUDIO_FORMAT_MP3 = 2; private static final int AUDIO_FORMAT_ALAW = 7; private static final int AUDIO_FORMAT_ULAW = 8; private static final int AUDIO_FORMAT_AAC = 10; @@ -36,6 +40,11 @@ import java.util.Collections; private static final int AAC_PACKET_TYPE_SEQUENCE_HEADER = 0; private static final int AAC_PACKET_TYPE_AAC_RAW = 1; + // SAMPLING RATES USED FOR MP3 + private static final int[] AUDIO_SAMPLING_RATE_TABLE = new int[] { + 5512, 11025, 22050, 44100 + }; + // State variables private boolean hasParsedAudioDataHeader; private boolean hasOutputFormat; @@ -55,8 +64,19 @@ import java.util.Collections; if (!hasParsedAudioDataHeader) { int header = data.readUnsignedByte(); audioFormat = (header >> 4) & 0x0F; - // TODO: Add support for MP3. - if (audioFormat == AUDIO_FORMAT_ALAW || audioFormat == AUDIO_FORMAT_ULAW) { + if (audioFormat == AUDIO_FORMAT_MP3) { + int sampleRateIndex = (header >> 2) & 0x03; + if (sampleRateIndex < 0 || sampleRateIndex >= AUDIO_SAMPLING_RATE_TABLE.length) { + Log.d(TAG, "Invalid sample rate, attempting to read at 44.1k"); + //rather than throw an exception, lets just attempt to play at 44.1k + sampleRateIndex = 3; + } + int sampleRate = AUDIO_SAMPLING_RATE_TABLE[sampleRateIndex]; + Format format = Format.createAudioSampleFormat(null, MimeTypes.AUDIO_MPEG, null, + Format.NO_VALUE, Format.NO_VALUE, 1, sampleRate, null, null, 0, null); + output.format(format); + hasOutputFormat = true; + } else if (audioFormat == AUDIO_FORMAT_ALAW || audioFormat == AUDIO_FORMAT_ULAW) { String type = audioFormat == AUDIO_FORMAT_ALAW ? MimeTypes.AUDIO_ALAW : MimeTypes.AUDIO_ULAW; int pcmEncoding = (header & 0x01) == 1 ? C.ENCODING_PCM_16BIT : C.ENCODING_PCM_8BIT; @@ -77,22 +97,27 @@ import java.util.Collections; @Override protected void parsePayload(ParsableByteArray data, long timeUs) { - int packetType = data.readUnsignedByte(); - if (packetType == AAC_PACKET_TYPE_SEQUENCE_HEADER && !hasOutputFormat) { - // Parse the sequence header. - byte[] audioSpecificConfig = new byte[data.bytesLeft()]; - data.readBytes(audioSpecificConfig, 0, audioSpecificConfig.length); - Pair audioParams = CodecSpecificDataUtil.parseAacAudioSpecificConfig( - audioSpecificConfig); - Format format = Format.createAudioSampleFormat(null, MimeTypes.AUDIO_AAC, null, - Format.NO_VALUE, Format.NO_VALUE, audioParams.second, audioParams.first, - Collections.singletonList(audioSpecificConfig), null, 0, null); - output.format(format); - hasOutputFormat = true; - } else if (audioFormat != AUDIO_FORMAT_AAC || packetType == AAC_PACKET_TYPE_AAC_RAW) { + if (audioFormat == AUDIO_FORMAT_MP3) { int sampleSize = data.bytesLeft(); output.sampleData(data, sampleSize); output.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null); + } else { + int packetType = data.readUnsignedByte(); + if (packetType == AAC_PACKET_TYPE_SEQUENCE_HEADER && !hasOutputFormat) { + // Parse the sequence header. + byte[] audioSpecificConfig = new byte[data.bytesLeft()]; + data.readBytes(audioSpecificConfig, 0, audioSpecificConfig.length); + Pair audioParams = CodecSpecificDataUtil.parseAacAudioSpecificConfig(audioSpecificConfig); + Format format = + Format.createAudioSampleFormat(null, MimeTypes.AUDIO_AAC, null, Format.NO_VALUE, Format.NO_VALUE, audioParams.second, audioParams.first, + Collections.singletonList(audioSpecificConfig), null, 0, null); + output.format(format); + hasOutputFormat = true; + } else if (audioFormat != AUDIO_FORMAT_AAC || packetType == AAC_PACKET_TYPE_AAC_RAW) { + int sampleSize = data.bytesLeft(); + output.sampleData(data, sampleSize); + output.sampleMetadata(timeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null); + } } } From 329b8910cac6684ea4f67327fe434b182bff5e30 Mon Sep 17 00:00:00 2001 From: Rohit Krishnan Date: Mon, 17 Apr 2017 22:07:33 -0400 Subject: [PATCH 2/2] Remove unnecessary check. sampleRateIndex is masked with 0x03 so it is constrained to be between 0 and 3. --- .../exoplayer2/extractor/flv/AudioTagPayloadReader.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java b/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java index 2fc586ce22..d87802eca6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/extractor/flv/AudioTagPayloadReader.java @@ -30,8 +30,6 @@ import java.util.Collections; */ /* package */ final class AudioTagPayloadReader extends TagPayloadReader { - private static final String TAG = "AudioTagPayloadReader"; - private static final int AUDIO_FORMAT_MP3 = 2; private static final int AUDIO_FORMAT_ALAW = 7; private static final int AUDIO_FORMAT_ULAW = 8; @@ -66,11 +64,6 @@ import java.util.Collections; audioFormat = (header >> 4) & 0x0F; if (audioFormat == AUDIO_FORMAT_MP3) { int sampleRateIndex = (header >> 2) & 0x03; - if (sampleRateIndex < 0 || sampleRateIndex >= AUDIO_SAMPLING_RATE_TABLE.length) { - Log.d(TAG, "Invalid sample rate, attempting to read at 44.1k"); - //rather than throw an exception, lets just attempt to play at 44.1k - sampleRateIndex = 3; - } int sampleRate = AUDIO_SAMPLING_RATE_TABLE[sampleRateIndex]; Format format = Format.createAudioSampleFormat(null, MimeTypes.AUDIO_MPEG, null, Format.NO_VALUE, Format.NO_VALUE, 1, sampleRate, null, null, 0, null);