SDK初始化
依赖配置
com.android.support:appcompat-v7:28.0.0
com.tencent:mmkv:1.0.18
com.google.code.gson:gson:2.8.5
com.alibaba:fastjson:1.1.67.android
com.google.zxing:core:3.3.0
packagingOptions {
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
}
权限配置
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
初始化流程
1.初始化SDK
IPCSDK.initSDK(this);
2.设置流的配置
配置参数
package com.tuya.smart.aiipc.ipc_sdk.api;
public class Common {
/**
* 码流通道类型
* */
public class ChannelIndex {
public static final int E_CHANNEL_VIDEO_MAIN = 0;
public static final int E_CHANNEL_VIDEO_SUB = 1;
public static final int E_CHANNEL_VIDEO_3RD = 2;
public static final int E_CHANNEL_VIDEO_4TH = 3;
public static final int E_CHANNEL_VIDEO_MAX = 8; //最大支持视频码流路数
public static final int E_CHANNEL_AUDIO = 9;
public static final int E_CHANNEL_AUDIO_2RD = 10;
public static final int E_CHANNEL_AUDIO_3RD = 11;
public static final int E_CHANNEL_AUDIO_4TH = 12;
public static final int E_CHANNEL_MAX = 16;
}
/**
* 时间类型
* */
public class EventType {
public static final int EVENT_TYPE_MOTION_DETECT = 0; /* 移动侦测触发的存储 */
public static final int EVENT_TYPE_DOOR_BELL = 1; /* 门铃唤醒触发的存储 */
public static final int EVENT_TYPE_INVALID = 2;
}
/**
* 传输特定的NAL 类型
* */
public class NAL_TYPE {
public static final int NAL_TYPE_IDR = 3;
public static final int NAL_TYPE_PB = 4;
}
/**
* 上报数据类型
* */
public class NOTIFICATION_CONTENT_TYPE_E {
public static final int NOTIFICATION_CONTENT_MP4 = 0; /* 视频,.mp4文件 */
public static final int NOTIFICATION_CONTENT_JPEG = 1; /* 图片,.jpeg文件 */
public static final int NOTIFICATION_CONTENT_PNG = 2; /* 图片,.png文件 */
public static final int NOTIFICATION_CONTENT_MAX = 3;
}
public class ParamKey {
/**
* 宽
* */
public final static String KEY_VIDEO_WIDTH = "video-width";
/**
* 高
* */
public final static String KEY_VIDEO_HEIGHT = "video-height";
/**
* capture 图像的分辨率
* */
public final static String KEY_VIDEO_PREVIEW_SIZE = "video-preview-size";
/**
* 支持的分辨率
* */
public final static String KEY_VIDEO_SUPPORTED_PREVIEW_SIZES = "video-support-preview-sizes";
/**
* 视频帧率
* */
public final static String KEY_VIDEO_FRAME_RATE = "video-frame-rate";
/**
* 视频码率
* */
public final static String KEY_VIDEO_BIT_RATE = "video-bit-rate";
/**
* 视频支持的码率
* */
public final static String KEY_VIDEO_SUPPORTED_BIT_RATE = "video-supported-bit-rate";
/**
* I 帧间隔
* */
public final static String KEY_VIDEO_I_FRAME_INTERVAL = "video-i-frame-interval";
/**
* 音频通道数
* */
public final static String KEY_AUDIO_CHANNEL_NUM = "audio-channel-num";
/**
* 音频采样率
* */
public final static String KEY_AUDIO_SAMPLE_RATE = "audio-sample-rate";
/**
* 音频采样位数
* */
public final static String KEY_AUDIO_SAMPLE_BIT = "audio-sample-bit";
/**
* 音频采样帧率
* */
public final static String KEY_AUDIO_FRAME_RATE = "audio-frame-rate";
}
}
private void LoadParamConfig() {
IParamConfigManager configManager = IPCServiceManager.getInstance().getService(IPCServiceManager.IPCService.MEDIA_PARAM_SERVICE);
configManager.setInt(Common.ChannelIndex.E_CHANNEL_VIDEO_MAIN, Common.ParamKey.KEY_VIDEO_WIDTH, 1280);
configManager.setInt(Common.ChannelIndex.E_CHANNEL_VIDEO_MAIN, Common.ParamKey.KEY_VIDEO_HEIGHT, 720);
configManager.setInt(Common.ChannelIndex.E_CHANNEL_VIDEO_MAIN, Common.ParamKey.KEY_VIDEO_FRAME_RATE, 20);
configManager.setInt(Common.ChannelIndex.E_CHANNEL_VIDEO_MAIN, Common.ParamKey.KEY_VIDEO_I_FRAME_INTERVAL, 1);
configManager.setInt(Common.ChannelIndex.E_CHANNEL_VIDEO_MAIN, Common.ParamKey.KEY_VIDEO_BIT_RATE, 1000_000);
configManager.setInt(Common.ChannelIndex.E_CHANNEL_AUDIO, Common.ParamKey.KEY_AUDIO_CHANNEL_NUM, 1);
configManager.setInt(Common.ChannelIndex.E_CHANNEL_AUDIO, Common.ParamKey.KEY_AUDIO_SAMPLE_RATE, 8000);
configManager.setInt(Common.ChannelIndex.E_CHANNEL_AUDIO, Common.ParamKey.KEY_AUDIO_SAMPLE_BIT, 16);
configManager.setInt(Common.ChannelIndex.E_CHANNEL_AUDIO, Common.ParamKey.KEY_AUDIO_FRAME_RATE, 25);
}
3.获取配网服务开始配网
INetConfigManager iNetConfigManager = IPCServiceManager.getInstance().getService(IPCServiceManager.IPCService.NET_CONFIG_SERVICE);
iNetConfigManager.configNetInfo(new INetConfigManager.NetConfigCallback() {
@Override
public void configOver(String token) {
//配网完成,开始准备开启推流服务
}
@Override
public void startConfig() {
android.util.Log.d(TAG, "startConfig: ");
}
@Override
public void recConfigInfo() {//收到配网信息了
android.util.Log.d(TAG, "recConfigInfo: ");
}
});
}
4.开始推流
//获取服务
IMediaTransManager transManager = IPCServiceManager.getInstance().getService(IPCServiceManager.IPCService.MEDIA_TRANS_SERVICE);
//将对应的参数设置进去,第一个参数为配网所获取的token,第二个为存储配置信息的路径,其余几个先用demo的值进行测试
transManager.initTransSDK(token, "/sdcard/",
"TQNRbAHdrGmqk5bs", "tuyaa10e7bea6ac9ad5d", "eANvTmHNARMYlUBoGMBb1LMc1oNDA8TF");
// Log.d(TAG, "dpReport1: " + TranJNIApi.dpReport(TUYA_DP_SD_STATUS_ONLY_GET, DPConst.Type.PROP_VALUE, 1, 1));
// Log.d(TAG, "dpReport2: " + TranJNIApi.dpReport(TUYA_DP_PTZ_CONTROL, DPConst.Type.PROP_ENUM, 0, 1));
// Log.d(TAG, "dpReport3: " + TranJNIApi.dpReport(TUYA_DP_SD_STORAGE_ONLY_GET, DPConst.Type.PROP_STR, "100|3|97", 1));
// Log.d(TAG, "dpReport4: " + TranJNIApi.dpReport(TUYA_DP_SD_UMOUNT, DPConst.Type.PROP_BOOL, true, 1));
//开启传输
transManager.startMultiMediaTrans();
//增加音频回调接口
transManager.addAudioTalkCallback(new AudioTalkCallback() {
@Override
public void onAudioTalkData(byte[] data) {
}
});
PermissionUtil.check(MainActivity.this, new String[]{
Manifest.permission.RECORD_AUDIO,
}, () -> {
videoCapture = new VideoCapture();
audioCapture = new AudioCapture();
//推流
/**
* push 视频流到SDK中
* */
transManager.pushMediaStream(Common.ChannelIndex.E_CHANNEL_VIDEO_MAIN, type, bytes, 0);
videoCapture.startVideoCapture();
audioCapture.startCapture();
});
/**
* push 一帧多媒体流到SDK
* @param streamType 媒体数据类型 {@link Common.ChannelIndex}
* @param nalType 是视频流时,为H264码流的nal类型. 是音频流时,此参数无效,默认为0
* @param streamData 码流数据
* @param timeStamp 每一帧数据产生的时间戳
* */
int pushMediaStream(int streamType, int nalType, byte[] streamData, long timeStamp);
注意:如果操作的SDK相关的类的时候是在非主进程中的话,那么获取权限的部分可能会存在一定的问题,这个时候需要在AndnroidManifest.xml中添加如下申明:
****
<!-- 如果是跨进程的,那么申明一下所在的进程--> <receiver android:name="com.tuya.smart.aiipc.base.permission.IPCBroadcastReceiver" android:process=":x"> <intent-filter> <action android:name="com.tuya.smart.aiipc.base.permission.BROADCAST_ACTION"/> </intent-filter> </receiver>
将android:process处的值改为和所在进程一样的值。ex:在如下的进程操作的SDK
<service android:name="com.tuya.smart_doorbell.service.DoorBellService" android:process=":x" //上面的广播需要和次值保持一致 android:enabled="true" android:exported="true"> </service>
在推送流的时候,关键帧之前必须要加上SPS和PPS的数据
if (info.flags == BUFFER_FLAG_KEY_FRAME) { outputStream.reset(); try { outputStream.write(SPS); outputStream.write(PPS); outputStream.write(bytes); } catch (IOException e) { e.printStackTrace(); } bytes = outputStream.toByteArray(); type = Common.NAL_TYPE.NAL_TYPE_IDR; }
Last updated