package com.laifeng.sopcastsdk.stream.packer.rtmp;
import android.media.MediaCodec;
import com.laifeng.sopcastsdk.stream.packer.AnnexbHelper;
import com.laifeng.sopcastsdk.stream.packer.Packer;
import com.laifeng.sopcastsdk.stream.packer.flv.FlvPackerHelper;
import java.nio.ByteBuffer;
import static com.laifeng.sopcastsdk.stream.packer.flv.FlvPackerHelper.AUDIO_HEADER_SIZE;
import static com.laifeng.sopcastsdk.stream.packer.flv.FlvPackerHelper.AUDIO_SPECIFIC_CONFIG_SIZE;
import static com.laifeng.sopcastsdk.stream.packer.flv.FlvPackerHelper.VIDEO_HEADER_SIZE;
import static com.laifeng.sopcastsdk.stream.packer.flv.FlvPackerHelper.VIDEO_SPECIFIC_CONFIG_EXTEND_SIZE;
/**
* @Title: FlvPacker
* @Package com.laifeng.sopcastsdk.stream.packer
* @Description:
* @Author Jim
* @Date 16/9/13
* @Time 上午11:51
* @Version
*/
public class RtmpPacker implements Packer, AnnexbHelper.AnnexbNaluListener{
public static final int FIRST_VIDEO = 1;
public static final int FIRST_AUDIO = 2;
public static final int AUDIO = 3;
public static final int KEY_FRAME = 4;
public static final int INTER_FRAME = 5;
public static final int CONFIGRATION = 6;
private OnPacketListener packetListener;
private boolean isHeaderWrite;
private boolean isKeyFrameWrite;
private int mAudioSampleRate, mAudioSampleSize;
private boolean mIsStereo;
private AnnexbHelper mAnnexbHelper;
public RtmpPacker() {
mAnnexbHelper = new AnnexbHelper();
}
@Override
public void setPacketListener(OnPacketListener listener) {
packetListener = listener;
}
@Override
public void start() {
mAnnexbHelper.setAnnexbNaluListener(this);
}
@Override
public void onVideoData(ByteBuffer bb, MediaCodec.BufferInfo bi) {
mAnnexbHelper.analyseVideoData(bb, bi);
}
@Override
public void onAudioData(ByteBuffer bb, MediaCodec.BufferInfo bi) {
if(packetListener == null || !isHeaderWrite || !isKeyFrameWrite) {
return;
}
bb.position(bi.offset);
bb.limit(bi.offset + bi.size);
byte[] audio = new byte[bi.size];
bb.get(audio);
int size = AUDIO_HEADER_SIZE + audio.length;
ByteBuffer buffer = ByteBuffer.allocate(size);
FlvPackerHelper.writeAudioTag(buffer, audio, false, mAudioSampleSize);
packetListener.onPacket(buffer.array(), AUDIO);
}
@Override
public void stop() {
isHeaderWrite = false;
isKeyFrameWrite = false;
mAnnexbHelper.stop();
}
@Override
public void onVideo(byte[] video, boolean isKeyFrame) {
if(packetListener == null || !isHeaderWrite) {
return;
}
int packetType = INTER_FRAME;
if(isKeyFrame) {
isKeyFrameWrite = true;
packetType = KEY_FRAME;
}
//确保第一帧是关键帧,避免一开始出现灰色模糊界面
if(!isKeyFrameWrite) {
return;
}
int size = VIDEO_HEADER_SIZE + video.length;
ByteBuffer buffer = ByteBuffer.allocate(size);
FlvPackerHelper.writeH264Packet(buffer, video, isKeyFrame);
packetListener.onPacket(buffer.array(), packetType);
}
@Override
public void onSpsPps(byte[] sps, byte[] pps) {
if(packetListener == null) {
return;
}
//写入第一个视频信息
writeFirstVideoTag(sps, pps);
//写入第一个音频信息
writeFirstAudioTag();
isHeaderWrite = true;
}
private void writeFirstVideoTag(byte[] sps, byte[] pps) {
int size = VIDEO_HEADER_SIZE + VIDEO_SPECIFIC_CONFIG_EXTEND_SIZE + sps.length + pps.length;
ByteBuffer buffer = ByteBuffer.allocate(size);
FlvPackerHelper.writeFirstVideoTag(buffer, sps, pps);
packetListener.onPacket(buffer.array(), FIRST_VIDEO);
}
private void writeFirstAudioTag() {
int size = AUDIO_SPECIFIC_CONFIG_SIZE + AUDIO_HEADER_SIZE;
ByteBuffer buffer = ByteBuffer.allocate(size);
FlvPackerHelper.writeFirstAudioTag(buffer, mAudioSampleRate, mIsStereo, mAudioSampleSize);
packetListener.onPacket(buffer.array(), FIRST_AUDIO);
}
public void initAudioParams(int sampleRate, int sampleSize, boolean isStereo) {
mAudioSampleRate = sampleRate;
mAudioSampleSize = sampleSize;
mIsStereo = isStereo;
}
}