Skip to content

Commit

Permalink
add AAC Encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
shogo4405 committed Dec 7, 2016
1 parent b86f943 commit 75ac3d6
Show file tree
Hide file tree
Showing 22 changed files with 729 additions and 52 deletions.
16 changes: 8 additions & 8 deletions app/app.iml
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,20 @@
<sourceFolder url="file:https://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file:https://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file:https://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file:https://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file:https://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file:https://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file:https://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file:https://$MODULE_DIR$/build/intermediates/builds" />
Expand Down Expand Up @@ -103,8 +103,8 @@
</content>
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="support-annotations-23.4.0" level="project" />
<orderEntry type="library" exported="" name="commons-io-2.5" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.4.0" level="project" />
<orderEntry type="library" exported="" name="animated-vector-drawable-23.4.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="hamcrest-core-1.3" level="project" />
<orderEntry type="library" exported="" name="commons-lang3-3.4" level="project" />
Expand Down
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
</application>

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-feature android:name="android.hardware.camera"/>

Expand Down
4 changes: 3 additions & 1 deletion app/src/main/java/com/haishinkit/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import com.haishinkit.media.AudioInfo;
import com.haishinkit.rtmp.RTMPConnection;
import com.haishinkit.rtmp.RTMPStream;
import com.haishinkit.view.CameraView;
Expand All @@ -20,7 +21,8 @@ protected void onCreate(Bundle savedInstanceState) {
stream = new RTMPStream(connection);

cameraView = new CameraView(this);
stream.attachCamera(cameraView.getCamera());
stream.attachAudio(new AudioInfo());
//stream.attachCamera(cameraView.getCamera());
setContentView(cameraView);

connection.connect("rtmp:https://192.168.179.3/live");
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/com/haishinkit/flv/SoundType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.haishinkit.flv;

import com.haishinkit.lang.IRawValue;

public enum SoundType implements IRawValue<Byte> {
MONO((byte) 0x00),
STEREO((byte) 0x01);

private final Byte rawValue;

SoundType(final byte rawValue) {
this.rawValue = rawValue;
}

public final Byte rawValue() {
return rawValue;
}
}
216 changes: 216 additions & 0 deletions app/src/main/java/com/haishinkit/iso/AudioSpecificConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package com.haishinkit.iso;

import com.haishinkit.lang.IRawValue;
import com.haishinkit.util.ByteBufferUtils;
import com.haishinkit.util.Log;

import org.apache.commons.lang3.builder.ToStringBuilder;
import java.nio.ByteBuffer;

/**
* The Audio Specific Config is the global header for MPEG-4 Audio
*
* @see http:https://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config
* @see http:https://wiki.multimedia.cx/?title=Understanding_AAC
*/
public final class AudioSpecificConfig {
public static final int ADTS_HEADER_SIZE = 7;

public enum AudioObjectType implements IRawValue<Byte> {
UNKNOWN((byte) 0x00),
AAC_MAIN((byte) 0x01),
AAC_LC((byte) 0x02),
AAC_SSL((byte) 0x03),
AAC_LTP((byte) 0x04),
AAC_SBR((byte) 0x05),
AAC_SCALABLE((byte) 0x06),
TWINQVQ((byte) 0x07),
CELP((byte) 0x08),
HXVC((byte) 0x09);

public static AudioObjectType rawValue(final byte rawValue) {
switch (rawValue) {
case 0x01:
return AAC_MAIN;
case 0x02:
return AAC_LC;
case 0x03:
return AAC_SSL;
case 0x04:
return AAC_LTP;
case 0x05:
return AAC_SBR;
case 0x06:
return AAC_SCALABLE;
case 0x07:
return TWINQVQ;
case 0x08:
return CELP;
case 0x09:
return HXVC;
}
return UNKNOWN;
}

private final byte rawValue;

AudioObjectType(final byte rawValue) {
this.rawValue = rawValue;
}

public Byte rawValue() {
return rawValue;
}
}

public enum SamplingFrequency implements IRawValue<Byte> {
HZ96000((byte) 0x00),
HZ88200((byte) 0x01),
HZ64000((byte) 0x02),
HZ48000((byte) 0x03),
HZ44100((byte) 0x04),
HZ32000((byte) 0x05),
HZ24000((byte) 0x06),
HZ22050((byte) 0x07),
HZ16000((byte) 0x08),
HZ12000((byte) 0x09),
HZ11025((byte) 0x0A),
HZ8000((byte) 0x0B),
HZ7350((byte) 0x0C);

public static SamplingFrequency rawValue(final byte rawValue) {
switch (rawValue) {
case 0x00:
return HZ96000;
case 0x01:
return HZ88200;
case 0x02:
return HZ64000;
case 0x03:
return HZ48000;
case 0x04:
return HZ44100;
case 0x05:
return HZ32000;
case 0x06:
return HZ24000;
case 0x07:
return HZ22050;
case 0x08:
return HZ16000;
case 0x09:
return HZ12000;
case 0x0A:
return HZ11025;
case 0x0B:
return HZ8000;
case 0x0C:
return HZ7350;
}
return HZ96000;
}

private final byte rawValue;

SamplingFrequency(final byte rawValue) {
this.rawValue = rawValue;
}

public Byte rawValue() {
return rawValue;
}
}

public enum ChannelConfiguration implements IRawValue<Byte> {
DEFINE_IN_AOT_SPECIFIC_CONFIG((byte) 0x00),
FRONT_OF_CENTER((byte) 0x01),
FRONT_LEFT_AND_FRONT_RIGHT((byte) 0x02),
FRONT_CENTER_AND_FRONT_LEFT_AND_FRONT_RIGHT((byte) 0x03),
FRONT_CENTER_AND_FRONT_LEFT_AND_FRONT_RIGHT_AND_BACK_CENTER((byte) 0x04),
FRONT_CENTER_AND_FRONT_LEFT_AND_FRONT_RIGHT_AND_BACK_LEFT_AND_BACK_RIGHT((byte) 0x05),
FRONT_CENTER_AND_FRONT_LEFT_AND_FRONT_RIGHT_AND_BACK_LEFT_AND_BACK_RIGHT_LFE((byte) 0x06),
FRONT_CENTER_AND_FRONT_LEFT_AND_FRONT_RIGHT_AND_SIDE_LEFT_AND_RIGHT_AND_BACK_RIGHT_LFE((byte) 0x07),
UNKNOWN((byte) 0xFF);

public static ChannelConfiguration rawValue(final byte rawValue) {
switch (rawValue) {
case 0x00:
return DEFINE_IN_AOT_SPECIFIC_CONFIG;
case 0x01:
return FRONT_OF_CENTER;
case 0x02:
return FRONT_LEFT_AND_FRONT_RIGHT;
case 0x03:
return FRONT_CENTER_AND_FRONT_LEFT_AND_FRONT_RIGHT;
case 0x04:
return FRONT_CENTER_AND_FRONT_LEFT_AND_FRONT_RIGHT_AND_BACK_CENTER;
case 0x05:
return FRONT_CENTER_AND_FRONT_LEFT_AND_FRONT_RIGHT_AND_BACK_LEFT_AND_BACK_RIGHT;
case 0x06:
return FRONT_CENTER_AND_FRONT_LEFT_AND_FRONT_RIGHT_AND_BACK_LEFT_AND_BACK_RIGHT_LFE;
case 0x07:
return FRONT_CENTER_AND_FRONT_LEFT_AND_FRONT_RIGHT_AND_SIDE_LEFT_AND_RIGHT_AND_BACK_RIGHT_LFE;
default:
return UNKNOWN;
}
}

private final byte rawValue;

ChannelConfiguration(final byte rawValue) {
this.rawValue = rawValue;
}

public Byte rawValue() {
return rawValue;
}
}

private final AudioObjectType type;
private final SamplingFrequency frequency;
private final ChannelConfiguration channel;

public AudioSpecificConfig(final AudioObjectType type, final SamplingFrequency frequency, final ChannelConfiguration channel) {
this.type = type;
this.frequency = frequency;
this.channel = channel;
}

public AudioSpecificConfig(final ByteBuffer buffer) {
byte[] bytes = new byte[2];
buffer.get(bytes);
type = AudioObjectType.rawValue((byte) (bytes[0] >> 3));
frequency = SamplingFrequency.rawValue((byte) (((bytes[0] & 0b00000111) << 1) | (bytes[1] & 0xFF) >> 7));
channel = ChannelConfiguration.rawValue((byte) ((bytes[1] & 0b01111000) >> 3));
buffer.flip();
}

public final AudioObjectType getType() {
return type;
}

public final SamplingFrequency getFrequency() {
return frequency;
}

public final ChannelConfiguration getChannel() {
return channel;
}

public final byte[] toADTS(final int length) {
final int fullSize = ADTS_HEADER_SIZE + length;
byte[] adts = new byte[ADTS_HEADER_SIZE];
adts[0] = (byte) 0xFF;
adts[1] = (byte) 0xF9;
adts[2] = (byte) (((type.rawValue() - 1) << 6) | (frequency.rawValue() << 2) | (channel.rawValue() >> 2));
adts[3] = (byte) ((channel.rawValue() & 3) | fullSize >> 11);
adts[4] = (byte) ((fullSize & 0x7FF) >> 3);
adts[5] = (byte) (((fullSize & 7) << 5) | 0x1F);
adts[6] = (byte) 0xFC;
return adts;
}

public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
25 changes: 25 additions & 0 deletions app/src/main/java/com/haishinkit/media/AACEncoder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.haishinkit.media;

import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import java.io.IOException;

public final class AACEncoder extends EncoderBase {
public static final String MIME = "audio/mp4a-latm";

public AACEncoder() {
super(MIME);
}

@Override
protected MediaCodec createMediaCodec() throws IOException {
MediaCodec codec = MediaCodec.createEncoderByType(MIME);
MediaFormat mediaFormat = MediaFormat.createAudioFormat(MIME, 44100, 1);
mediaFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
mediaFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 64000);
codec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
return codec;
}
}
Loading

0 comments on commit 75ac3d6

Please sign in to comment.