前期准备
1:app/src/main下建立JniLibs文件包 复制大牛工程的so包以及jar包 jar包右键导入项目出现’>’
2:java下建立com.daniulive.smartpublisher文件包复制项目中的SmartPublisherJniV2.java
3:非正式需要把app的名字改成SmrtPublisherSDKDemo
public class VideoDataService extends Service {
private SmartPublisherJniV2 publisherJniV2;
private long publisherHandle = 0;
private long before;//第一次开启服务记录的时间
//加载包
static {
System.loadLibrary("SmartPublisher");
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
try {
before=System.currentTimeMillis();
publisherJniV2=new SmartPublisherJniV2();
//audio_opt是否推送音频 video_opt是否推送视频 width height视频高宽
publisherHandle=publisherJniV2.SmartPublisherOpen(getActivity(),0,2,480,360);
VideoFeeder.VideoFeed videoFeed = VideoFeeder.getInstance().provideTranscodedVideoFeed();
videoFeed.addVideoDataListener(new VideoFeeder.VideoDataListener() {
@Override
public void onReceive(byte[] bytes, int i) {
// NativeHelper.getInstance().parse(bytes, i);
//当前时间减去第一次时间拿到时间戳
long time = System.currentTimeMillis() - before;
// Log.d("djdjdj", bytes[0] + "**"+bytes[1]+ "**"+bytes[2]+ "**"+bytes[3]+ "**"+bytes[4]+ "**"+bytes[5]+ "**"+bytes[6]+ "**"+bytes[7]+ "**"+bytes[8]+ "**"+bytes[9]+ "**"+bytes[10]+ "**"+bytes[11]+ "**"+bytes[12]+ "**"+bytes[13]+ "**"+bytes[14]+ "**"+bytes[15]+ "**"+bytes[16]+ "**"+bytes[17]+ "**"+bytes[18]);
//H.264对应1||编码后的video数据||size data length||is_key_frame 是否I帧 if with key frame, please set 1, otherwise, set 0
// * timestamp video timestamp
// * @param pts Presentation Time Stamp, 显示时间戳
// * @return {0} if successful
publisherJniV2.SmartPublisherPostVideoEncodedData(publisherHandle, 1, byte2Byffer(bytes), i, bytes[4] == 39 ? 1 : 0, time, time);
}
});
//推流地址
publisherJniV2.SmartPublisherSetURL(publisherHandle,"rtmp://stream.jizhenkeji.com/live/test");
//开始推流
publisherJniV2.SmartPublisherStartPublisher(publisherHandle);
}catch (Exception e){
e.printStackTrace();
stopSelf();
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
}
/**
* byte 数组转byteBuffer
* @param byteArray
*/
public static ByteBuffer byte2Byffer(byte[] byteArray) {
//初始化一个和byte长度一样的buffer
ByteBuffer buffer=ByteBuffer.allocateDirect(byteArray.length);
// 数组放到buffer中
buffer.put(byteArray);
//重置 limit 和postion 值 否则 buffer 读取数据不对
buffer.flip();
return buffer;
}
//10进制byte[]转16进制
public static final String bytesToHexString(byte[] buffer) {
StringBuffer sb = new StringBuffer(buffer.length);
String temp;
for (int i = 0; i < buffer.length; ++i) {
temp = Integer.toHexString(0xff & buffer[i]);
if (temp.length() < 2)
sb.append(0);
sb.append(temp);
}
return sb.toString();
}
//是否包含SPSPPS
private boolean IsSPSPPS(@NonNull byte[] buffer) {
if (buffer.length < 5) {
return false;
}
//00 00 00 01
if (buffer[0] == 0
&& buffer[1] == 0
&& buffer[2] == 0
&& buffer[3] == 1) {
int nalType = buffer[4] & 0x1f;
if (nalType == 0x07 || nalType == 0x08) {
return true;
}
}
//00 00 01
if (buffer[0] == 0
&& buffer[1] == 0
&& buffer[2] == 1) {
int nalType = buffer[3] & 0x1f;
if (nalType == 0x07 || nalType == 0x08) {
return true;
}
}
return false;
}
//是否是I帧
private boolean IsKeyFrame(@NonNull byte[] buffer) {
if (buffer.length < 5) {
return false;
}
//00 00 00 01
if (buffer[0] == 0
&& buffer[1] == 0
&& buffer[2] == 0
&& buffer[3] == 1) {
int nalType = buffer[4] & 0x1f;
if (nalType == 0x05) {
return true;
}
}
//00 00 01
if (buffer[0] == 0
&& buffer[1] == 0
&& buffer[2] == 1) {
int nalType = buffer[3] & 0x1f;
if (nalType == 0x05) {
return true;
}
}
return false;
}
}