Appearance
当前版本: v1.1
苏州必捷网络有限公司
1.概述
1.1 目的
用于指导使用必捷Miracast 接收端SDK(基于WifiP2pManager)的开发人员进行开发及测试。
1.2 读者对象
本文档适用于使用BJSDK 开发Android平台Miracast 接收端的开发人员。
2. 范围
2.1 功能
本SDK可以接受来自Android手机,PC电脑,安卓系统ipad使用Miracast方式的投屏处理,并提供接口给应用层调用处理。
2.2 SDK 框架
1.cast_base_lib-1.0.53-release.aar:它是一个Android Module,它定义了基础的MediaChannel,Module接口。
2.bj_miracastgc_lib-1.0.8-release.aar:它是一个Android Module,定义了MiraProxyModule,以及相关JNI接口。
2.3 SDK Demo实现
MiracastSink是接收端的一个参考实现,它基于bj_miracastgc_lib-1.0.8-release.aar实现了Miracast接收端功能。
其中MiraProxyModuleImp实现了MiraProxyBaseImp接口。
MiraRenderChannel实现了MediaChannel接口,配合VideoCodec类 实现了对Miracast音视频会话的处理。
MiraCastServer 负责接收P2PServer 发送的广播来进行对P2P连接成功事件进行处理。
2.4 SDK 交付物
SDK库
DEMO源码
SDK接口文档
3. 接口
接口主要在MiraProxyModule,MediaChannel,MiracastUibc和MiraProxyBaseImp中进行定义。
MiraProxyModule类 提供了初始话SDK和强制结束会话,重启Miracast 服务等接口。
MiraProxyBaseImp是一个抽象类,需要由用户实现相关接口,SDK通过该接口类来通知用户程序Miracast一些投屏事件的发生。
MiracastUibc类 提供了用于反控TCP通道连接,反控消息传输等接口,用于需要根据android层检测到的不同触控事件,来进行调用反控接口来对发射端进行反向控制。
MediaChannel是一个抽象类,需由用户程序实现,SDK通过此接口类将音视频数据控制事件通知应用程序,应用程序在对应播放器中进行处理。
用户需实现MediaChannel,MiraProxyBaseImp相关接口, 也可参考我司提供的DEMO源代码实现。
3.1 MediaChannel抽象类
MediaChannel定义了一个抽象类,客户需要根据自身实际情况实现下列接口。
当会话建立成功后,协议栈会调用MediaChannel类中的相应接口回吐数据或者处理控制事件。
以下为客户需要在MediaChannel子类中实现的接口。
3.1.1 初始化接口
java
public abstract boolean open();
描述
在投屏会话创建时由用户调用,一般用于播放器解码器的初始化等操作。用于方便用户多态化的实现。
返回值
true : 成功
false : 失败
3.1.2 去初始化接口
java
public abstract void close();
描述
投屏会话结束时由用户调用,和open()接口对应,一般用于结束会话相关的播放器配置。用于方便用户多态化的实现。
3.1.3 设置窗口句柄
java
public void setSurface(Surface surface)
描述
设置当前MediaChannel关联的显示相关的Surface,视频将显示到该Surface。该Surface来自用户用于显示视频的view。
参数
surface: 显示相关的Surface,通常来自用户用于显示视频的view。
调用示例
参考Demo中的实现。
3.1.4 音频数据回吐接口
java
public abstract void onAudioFrame(byte[] buffer,int len,long ts);
描述
回调接口,吐出音频数据为PCM格式,用户需要实现对音频数据的播放处理功能。
音频格式如下,播放器需按照以下格式进行音频的播放。
音频参数 | 值 |
---|---|
采样率 | 48000 |
音频格式 | S16 |
声道数 | 2 |
参数
名称 | 描述 |
---|---|
buffer | 音频数据数组。 |
len | 数据长度。 |
ts | 时间戳。 |
调用示例
请参考demo源码。
3.1.5 视频数据回吐接口
java
public void onVideoFrame(byte[] buffer,int len,long ts)
描述
镜像视频数据回调接口,该接口中吐出的是H264视频数据,用户需要进行解码并播放。
参数
名称 | 描述 |
---|---|
buffer | 音频数据数组。 |
len | 数据长度。 |
ts | 时间戳,时间戳单位为1/1000000秒。 |
3.1.6 隐藏鼠标接口
java
public void hindCursor()
描述
该接口通知应用需要隐藏鼠标(比如发射端用播放器全屏播放视频时,鼠标会自动消失,此时会通知接收端隐藏鼠标),此时播放器需要将鼠标进行隐藏。当有新的updateCursorPos,或者updateCursorShape消息时鼠标需再次进行显示。
3.1.7 更新鼠标图片接口
java
public void updateCursorShape(byte[] pngData)
描述
回调接口,当sdk 收到发射端的鼠标相关信息时触发,用于绘画Miracast的鼠标(由于Miracast鼠标信息是独立通道不包含在视频流中),应用层实现相关逻辑。
参数
pngData: 发射端发送的图片bit数据。
调用示例
java
@Override
public void updateCursorShape(byte[] pngData) {
if (pngData.length != 0) {
Bitmap bmp = BitmapFactory.decodeByteArray(pngData, 0, pngData.length); //encode png to bitmap
bmp = BitmapFactory.decodeByteArray(pngData, 0, pngData.length); //encode png to bitmap
EventBus.getDefault().post(new MouseEvent(bmp,getChannelId(), DemoApplication.MOUSEBITMAP));
}
}
3.1.8 更新鼠标位置接口
java
public void updateCursorPos(short x,short y)
描述
该接口通知更新鼠标位置x,y。屏幕左上角坐标为(0,0)。
参数
名称 | 描述 |
---|---|
x | 鼠标在图像中的x坐标。 |
y | 鼠标在图像中的y坐标。 |
调用示例
java
@Override
public void updateCursorPos(short x, short y) {
EventBus.getDefault().post(new MouseEvent(bmp, x, y,getChannelId(), DemoApplication.MOUSEISMOVE));
}
注意事项
播放器需要根据实际图像大小和当前屏幕大小换算坐标位置。例如发射端发射的视频图像为720P,坐标位置(1280,720),当前显示的播放器对应的视图为1080P屏幕,则很显然需要将实际鼠标的显示位置换算成(1920,1080),可参考demo中的实际位置计算方法进行换算。
3.1.9 统计媒体数据信息接口
java
public void onMediaStatistics(MediaStatistics videoStatistics, MediaStatistics audioStatistics)
描述
回调接口,投屏过程中SDK调用,用于统计实时媒体数据信息,用于开发者查看实时传输数据,应用层实现相关逻辑。
参数
名称 | 描述 |
---|---|
videoStatistics | 视频传输的相关实时数据对象。 |
audioStatistics | 音频传输的相关实时数据对象。 |
调用示例
java
/*
MediaStatistics类成员函数部分说明:
getBitrateKbpsCurRound():获取当前时间段的视频码率
getBitrateKbps() :获取当前瞬时视频码率
getLostRateCurRound() :获取当前时间段的丢包率
getLostRate() :获取当前瞬时丢包率
*/
@Override
public void onMediaStatistics(MediaStatistics videoStatistics, MediaStatistics audioStatistics){
if (audioStat != null){
audioStat.bitrate_kbps = audioStatistics.getBitrateKbps();
audioStat.bitrate_kbps_this_round = audioStatistics.getBitrateKbpsCurRound();
audioStat.lostrate = audioStatistics.getLostRate();
audioStat.lostrate_this_round = audioStatistics.getLostRateCurRound();
}
if (codec != null){
codec.onMediaStatistics(videoStatistics);
}
}
3.1.10 设置音频编码信息接口
java
public void setTrackCodecInfo(byte[] data, int trackId, String metaDscp)
描述
回调接口,SDK通知上层获取的音频流 codec specific data 信息。
参数
名称 | 描述 |
---|---|
data | 音频编码所需配置信息。 |
trackId | 音频流的ID。 |
metaDscp | codec specific data。 |
调用示例
java
@Override
public void setTrackCodecInfo(byte[] data, int trackId, String metaDscp) {
Log.i(TAG, "setTrackCodecInfo trackId:" + trackId + " metaDscp:" + metaDscp);
if (trackId == 1)
{
MediaFormat audioFormat = MediaFormat.createAudioFormat(MediaFormat.MIMETYPE_AUDIO_AAC, 48000, 2);
ByteBuffer aacConf = ByteBuffer.allocate(5);
aacConf.put(data);
aacConf.put((byte) 0x00);
aacConf.flip();
Log.i(TAG, "conf aac codec:" + aacConf + " metaDscp:" + metaDscp);
audioFormat.setByteBuffer(metaDscp, aacConf);
if (this.audioDecoder != null) {
this.audioDecoder.stop();
this.audioDecoder.configure(audioFormat, null, null, 0);
this.audioDecoder.start();
}
this.audioDecodeThread = new WorkThread("channel_audio_decode_" + this.getChannelId());
this.audioDecodeThread.start();
this.audioDecodeRunner = new AudioDecoderAndRender();
this.audioDecodeHandler = new WorkHandler(this.audioDecodeThread.getLooper());
this.audioDecodeHandler.post(this.audioDecodeRunner);
Log.i(TAG, "conf aac codec success:" + aacConf + " metaDscp:" + metaDscp);
return;
}
return;
}
3.1.11 通知音频编码信息接口
java
public void notifyTrackCodecInfo(int trackId, AudioTrackInfo audioTrackInfo)
描述
回调接口,投屏过程中SDK调用,通知用户层音频相关信息,用户通过音频信息创建对应的的音频播放器,应用层实现相关逻辑。
参数
名称 | 描述 |
---|---|
trackId | 音频流的ID。 |
audioTrackInfo | AudioTrackInfo 类实例,包含音频的声道,采样率等信息, 具体见3.5小节。 |
调用示例
java
@Override
public void notifyTrackCodecInfo(int trackId, AudioTrackInfo audioTrackInfo) {
this.getMediaInfo().setAudioTrack(audioTrackInfo);
Log.i(TAG, "notifyTrackCodecInfo audio:" + audioTrackInfo.toString());
if (this.getMediaInfo().getAudioTrack().getAudioCodecType() == MediaConst.AUDIO_TRACK_AAC) {
this.createAacPlayer(); // 创建AAC播放器
} else if (this.getMediaInfo().getAudioTrack().getAudioCodecType() == MediaConst.AUDIO_TRACK_PCM) { // 创建PCM播放器
this.createPcmPlayer();
}
}
3.1.12 重协商接口
java
public MediaChannelInfo mediaNegotiation(MediaChannelInfo info)
描述
回调接口,投屏过程中SDK调用,当投屏分辨率变化时通知上层, 需要用户根据收到的分辨率对视频编码器进行对应配置。
参数
info : MediaChannel 相关的信息类,其中包含该投屏通道对应的相关音频或视频等数据,每个channelId对应一个MediaChannelInfo ,具体见3.5小节。
返回值
MediaChannelInfo类,具体内容见3.5小节。
调用示例
java
@Override
public MediaChannelInfo mediaNegotiation(MediaChannelInfo info){
Log.i(TAG, "MediaChannelInfo mediaNegotiation"+videoWidth+info.getVideoTrack().getWidth());
if(videoWidth != info.getVideoTrack().getWidth() || videoHeight != info.getVideoTrack().getHeight()){
videoWidth = info.getVideoTrack().getWidth();
videoHeight = info.getVideoTrack().getHeight();
}
return null;
}
3.1.13 设置channelID
java
public void setChannelId(int channelId);
描述
设置channelId。Miracast SDK 中 MediaChannel 的 channelId值目前由SDK维护,故该接口用户不需要调用。
参数
channelId : 表示投屏某一路的唯一ID。
注意事项
由于channelId目前由SDK维护,故在reqMediaChannel 返回 MediaChannel 后由SDK 调用该接口进行设置,设置的channelId值为 reqMediaChannel 的channelId参数值。
3.1.14 获取channelID
java
public int getChannelId();
描述
获取MediaChannel的 channelId值。
3.2 MiraProxyBaseImp抽象类
MiraProxyBaseImp定义了一个抽象类,客户需要根据自身实际情况实现下列接口。
当会话建立过程中,协议栈会调用MiraProxyBaseImp实现类中的实现接口通知上层,获取信息。
以下为客户需要在MiraProxyBaseImp子类中实现的接口。
3.2.1 Miracast会话结束回调
java
public void onHangup(int channelId);
描述
回调接口,用于当SDK内部结束Miracast会话时通知上层。
参数
channelId : 表示投屏某一路的唯一ID。
3.2.2 创建Miracast会话播放通道接口
java
public MediaChannel reqMediaChannel(MediaChannelInfo channelInfo, UserInfo info, int channelId);
描述
回调接口,当Miracast连接成功,收到setup消息后触发该回调,需要用户根据参数信息,返回实现的MediaChannel子类对象,应用层实现相关逻辑。
参数 | 描述 |
---|---|
channelInfo | 用于保存当前Miracast连接的相关信息,如音视频流相关编码信息,是否支持UIBC等,具体见3.5小节。 |
info | 用来保存当前Miracast连接的设备信息,具体见3.5小节。 |
channelId | 本次投屏通道的唯一ID,即channelId。该值从1000000开始每次投屏后向上递增。 |
调用示例
java
@Override
public MediaChannel reqMediaChannel(MediaChannelInfo channelInfo, UserInfo info, int channelId) {
MediaChannel channel = new MiraRenderChannel(channelInfo,info);
channel.setChannelId(channelId);
if (!openAndStartChannel(channel)){
Log.e(TAG, "reqMediaChannel failed,because openAndStartChannel failed.");
return null;
}
if(SharedPreferenceHelper.getInstance().getPerformanceMode()){
DemoApplication.APP.getEventBus().post(new MirrorTextureEvent(channel, info));
}else {
DemoApplication.APP.getEventBus().post(new MirrorSurfaceEvent(channel, info));
}
return channel;
}
返回值
MediaChannel 类,子类对象父类实现的实例,返回用于SDK回调使用的实例。
3.2.3 创建Miracast会话播放通道接口
java
public abstract void relMediaChannel(MediaChannel channel);
描述
回调接口,Miracast会话结束时通知上层释放该通道的MediaChannel对象,应用层实现相关逻辑。
参数
channel: reqMediaChannel函数中由用户创建,由SDK维护的MediaChannel子类实例。
调用示例
java
@Override
public void relMediaChannel(MediaChannel channel) {
Log.e(TAG, "relMediaChannel " + channel.getChannelId());
channel.close();
CloseChannelEvent event = new CloseChannelEvent(channel.getChannelId());
DemoApplication.APP.getEventBus().post(event);
}
3.2.4 Miracast底层服务错误上报接口
java
public void onError(int error)
描述
回调接口,Miracast服务发生错误时触发该回调,应用层实现相关逻辑(该接口为保留接口,目前未调用该接口)。
3.3 MiraProxyModule类中的接口说明
3.3.1 设置客户定制的模块实现类接口
java
public void setProxyImp(MiraProxyBaseImp imp)
描述
设置用户实现的MiraProxyBaseImp,以便以底层回调的吐出。
参数
imp: 用户实现的MiraProxyBaseImp接口实例。
3.3.2 初始化接口
java
public native boolean initMira(Properties props, Context context);
描述
MiraProxyModule类的initMira方法初始化Miracast接收端模块。App在启动做初始化时调用,MiraProxyModule对象应设计为全局只有一个。
参数
名称 | 描述 |
---|---|
Properties | java Properties类对象。 |
Context | android Conext 类对象 |
返回值
true :初始化成功。
false:初始化失败。
其中Properties支持MiraProxyModule类中以下属性的设置:
属性名称 | 描述 | 默认 |
---|---|---|
PARA_NAME_LICENSE | license Key,为使用必捷授权申请库或者申请工具申请的license授权。SDK内部会对此进行授权和校验。 | “license” |
PARA_NAME_LOG_LEVEL | 最低打印日志的级别:NOUSE(0),CRIT(1),ERROR(2),WARN(3),INFO(4),DEBUG(5),DETAIL(6) | 4(INFO) |
PARA_NAME_WIDI_NAME | 设备名称。 | “widi_name” |
PARA_NAME_SDK_VIDEO_JITTERBUF | 是否启用 jitterbuffer 。 1:启用 0:不启用 | 0 |
PARA_NAME_ERRFRAME_PROCESS_MODE | 错帧处理方式。 1:丢弃 0:不丢弃 | 0 |
PARA_NAME_FORCEDROP_FIRSTFRAME_WHEN_LOSTPAC | 强制丢掉第一帧当第一帧丢包。 | 1 |
PARA_NAME_MIN_KEYFRAME_REQ_INTERVAL_MS | 最小关键帧请求间隔。 | 3000 |
PARA_NAME_MIRACAST_CONFIG | MIRACAST的能力集, 目前设置64为禁用UIBC。 | 0 |
PARA_NAME_WIDI_HDCP_PORT | 设置HDCP端口, 不设置端口则默认不启用。 | “” |
PARA_LICENSE_CHECK_TOKEN | 由必捷分配,用于初始化SDK的license校验和包名认证,防止被他人盗用。 | |
PARA_LICENSE_CHECK_PASS | 由必捷分配,用于初始化SDK的license校验密码,防止盗用。 |
调用示例
java
public void prepareMiracastProxy(String deviceName,String key) {
this.miraProxyModule = new MiraProxyModule();
Properties prop = new Properties();
if(SharedPreferenceHelper.getInstance().getJitterBuffer()){
prop.put(MiraProxyModule.PARA_NAME_SDK_VIDEO_JITTERBUF,"1");
}
prop.put(MiraProxyModule.PARA_NAME_ERRFRAME_PROCESS_MODE,"1");
prop.put(MiraProxyModule.PARA_NAME_FORCEDROP_FIRSTFRAME_WHEN_LOSTPAC,"0");
prop.put(MiraProxyModule.PARA_NAME_MIN_KEYFRAME_REQ_INTERVAL_MS,"1500");
prop.put(MiraProxyModule.PARA_NAME_LOG_LEVEL,"5");
prop.put(MiraProxyModule.PARA_NAME_LICENSE, key);
prop.put(MiraProxyModule.PARA_NAME_WIDI_NAME, deviceName);
prop.put(MiraProxyModule.PARA_NAME_MIRACAST_CONFIG,"64"); // 64 代表禁用UIBC
prop.put(MiraProxyModule.PARA_LICENSE_CHECK_TOKEN,licenseCheckToken);
prop.put(MiraProxyModule.PARA_LICENSE_CHECK_PASS,licenseCheckPass);
if(SharedPreferenceHelper.getInstance().getHdcp()){
prop.put(MiraProxyModule.PARA_NAME_WIDI_HDCP_PORT, "10001"); //set hdcp port
}
if (miraProxyModule.initMira(prop, DemoApplication.getContext())) {
Log.d(TAG, "miraProxyModule init success");
} else {
Log.d(TAG, "miraProxyModule init failed");
return ;
}
}
3.3.3 去初始化接口(保留接口)
java
public native void fini();
描述
MiraProxyModule类的fini方法去初始化Miracast模块。App销毁Miracast接收端服务时调用。(目前无效,通过关闭底层Miracast服务来关闭Miracast接收端服务)。
3.3.4 开始Miracast会话接口
java
public native boolean startMiraSession(String ip, String port, String mac, String name);
描述
根据收到的 P2Pserver "com.bjnet.cbox.module.p2pservice.connect"广播携带的ip,mac等信息开始进行Miracast连接
参数
名称 | 描述 |
---|---|
ip | 投屏设备的IP。 |
port | WIDI端口(一般为7236 : 0x1c44)。 |
mac | 设备mac地址。 |
name | 设备名称。 |
返回值
true :开始Miracast会话成功。
false:开始Miracast会话失败。
3.3.5 结束miracast会话接口
java
public void stopMiraSession(int channelId)
// channelId :表示投屏某一路的唯一ID
描述
根据channelID结束对应的Miracast会话。
参数
channelId : 表示投屏某一路的唯一ID。
返回值
true :成功。
false:失败。
3.3.6 关键帧请求接口
java
public void reqKeyFrame(int channelId);
描述
请求关键帧时调用,应用层实现相关逻辑。
参数
channelId : 表示投屏某一路的唯一ID。
3.3.7 获取channel ID接口
java
public MediaChannel getMediaChannelById(int channelId)
描述
根据 channel ID获取对应连接绑定的MediaChannel对象。
参数
channelId : 表示投屏某一路的唯一ID。
返回值
获取channelId对应的MediaChannel。
3.3.8 获取MiracastUibc实例接口
java
public MiracastUibc getUibcChannelById(int channelId)
描述
根据channel ID来获取对应连接绑定的MiracastUibc对象。
参数
channelId : 表示投屏某一路的唯一ID。
返回值
获取channelId对应的MiracastUibc。
注意
MiracastUibc在Miracast连接后SDK根据channel ID自动生成,无需用户进行创建。
3.4 MiracastUibc 类中的接口说明
MiracastUibc类 提供了用于反控TCP通道连接,反控消息传输等接口,及反控所需要的发射端IP和端口,用于需要根据android层检测到的不同触控事件,来进行调用反控接口,来对发射端进行反向控制。
在投屏成功后,SDK 会根据channelId创建MiracastUibc对象,用户需在投屏成功后通过MiraProxyModule类中getUibcChannelById() 函数来获取channelId对应的MiracastUibc对象。该对象生命周期由SDK维护。
相关接口如下:
3.4.1 获取UIBC设备IP
java
public String getIp();
描述
获取MiracastUibc对应发射端的UIBC Ip地址。
返回值
MiracastUibc connect函数所需的UIBC的ip地址。
3.4.2 获取UIBC port
java
public int getPort();
描述
获取MiracastUibc对应发射端的UIBC端口。
返回值
MiracastUibc connect函数所需的UIBC的端口。
3.4.3 建立UIBC TCP连接
java
public void connect(String ip, int port, int channelId);
描述
根据发射端ip和通过getPort()获取的端口来进行UIBC连接。
参数
名称 | 描述 |
---|---|
ip | 对端IP地址,通过getIp()获取。 |
port | RTSP协商获得的发射端端口,通过getPort()获取。 |
channelId | 表示投屏某一路的唯一ID。 |
3.4.4 关闭UIBC TCP连接
java
public native void removeSocket(int channelId);
描述
关闭UIBC TCP连接通道。
参数
channelId : 表示投屏某一路的唯一ID。
3.4.5 确认Socket连接是否存在
java
public native boolean confirmSocketBuild(int channelId);
描述
部分设备在连接成功后,会因为防火墙等因素,而被断开,故有时需用该接口进行确认连接是否存在。
参数
channelId : 表示投屏某一路的唯一ID。
返回值
true :当前channelId对应的UIBC连接存在。
false:当前channelId对应的UIBC连接不存在。
3.4.6 鼠标点击事件或触屏事件
java
public native boolean onTouchAction(MotionEvent event, int video_width, int video_height,int sinkWidth,int sinkHeight,int channelId);
描述
根据event中的tooltype来判断是鼠标还是触控进行相应的反控,对应Android 的 onTouch事件。
参数
名称 | 描述 |
---|---|
event | android层获取到的event事件。 |
video_width | 投屏协商分辨率 width。 |
video_height | 投屏协商分辨率 height。 |
sinkWidth | android用户层设置的View width。 |
sinkHeight | android用户层设置的View width。 |
channelId | 表示投屏某一路的唯一ID。 |
返回值
true :调用成功。
false:调用失败。
调用示例
具体实现可参考DEMO源代码。
3.4.7 鼠标移动事件
java
public native void mouseAction(MotionEvent event, int video_width, int video_height,int sinkWidth,int sinkHeight,int channelId);
描述
鼠标移动需要进行跟随,所以需要调用该接口,对应Android 的 onGenericMotion事件。
参数
名称 | 描述 |
---|---|
event | android层获取到的event事件。 |
video_width | 投屏协商分辨率 width。 |
video_height | 投屏协商分辨率 height。 |
sinkWidth | android用户层 设置的View width。 |
sinkHeight | android用户层 设置的View width。 |
channelId | 表示投屏某一路的唯一ID。 |
调用示例
具体实现可参考DEMO源代码。
3.5 上述类接口涉及的BJ自定义数据存储类
3.5.1 MediaChannelInfo 类
描述
在某路投屏成功后,由SDK初始化,通过 reqMediaChannel 回调接口参数获取。下面是其相关属性:
名称 | 描述 |
---|---|
videoTrack | VideoTrackInfo类,包含video编码信息。 |
audioTrack | AudioTrackInfo类,包含audio编码信息。 |
supportUibc | bool 值,true :发射端支持反控,false:发射端不支持反控。 |
3.5.2 VideoTrackInfo 类
描述
MediaChannelInfo类的属性成员,包含sdk 根据RTSP协商后,设置的video编码信息。下面是其相关属性:
名称 | 描述 |
---|---|
width | 视频宽度。 |
height | 视频高度。 |
bitrate | 视频码率。 |
frameRate | 视频帧率。 |
videoCodecType | 视频编码器类型。 |
3.5.3 AudioTrackInfo 类
描述
MediaChannelInfo类的属性成员,包含sdk 根据RTSP协商后,设置的video编码信息。下面是其相关属性:
名称 | 描述 |
---|---|
bitDep | 音频采样精度。 |
sampleRate | 音频采样率。 |
channels | 音频声道。 |
channelLayOut | 音频声道布局。 |
audioCodecType | 音频编码器类型。 |
3.5.4 MediaStatistics 类
描述
Miracast投屏中网络传输实时数据的相关类。下面是其相关属性:
名称 | 描述 |
---|---|
bitrateKbpsCurRound | 一段时间内的平均码率。 |
bitrateKbps | 码率。 |
lostRateCurRound | 一段时间内的平均丢包率。 |
lostRate | 丢包率。 |
3.5.5 UserInfo 类
描述
保存Miracast投屏中,对端设备的一些信息。下面是其相关属性:
名称 | 描述 |
---|---|
deviceType | 投屏设备类型:Miracast投屏 固定为0。 |
deviceName | 投屏设备名称。 |
ip | 投屏设备Ip。 |
model | “”, 保留值。 |
mac | “”,目前部分方式投屏,获取不到mac地址,故仅做保留。 |
userdata | windwos投屏:"windows_miracast" , 手机投屏为: “”。 |
3.6 License授权校验错误码说明
错误码值 | 说明 |
---|---|
801 | 输入deviceId 无效。 |
802 | proGuardSalt输入无效。 |
803 | proGuardMode输入无效。 |
804 | 服务器返回值为空(请检查网络是否正常)。 |
810 | 获取本地 deviceId 地址失败。 |
811 | 输入的deviceId无法通过验证(请检查本地设备初始化是否正常)。 |
812 | license 申请结果异常, 请检查网络状态。 |
1001 | license_check_token校验失败,包名不匹配。 |
1002 | license_check_token校验失败。 |
1003 | license_check_pass密码校验失败。 |
1004 | license_check_token校验失败,非法的校验类型。 |
-101 | 无法获取deviceId。 |
-102 | 无法获取硬件信息。 |
-103 | 检验deviceId失败。 |
-104 | 校验硬件信息失败。 |
-105 | SDK类型不一致。 |
-106 | 授权(license Key)已过期。 |
-107 | 无法解析license。 |
-108 | license Key解析错误, 请检查 license 是否读取成功,申请license过程是否出现异常。 |
-109 | license Key为空。 |
-110 | 平台类型不匹配(SDK用于windows, android平台必须匹配)。 |
-111 | productId不匹配。 |
4. Android服务
Miracast SDK中服务仅包含P2P Android服务,用于处理P2P连接。
4.1 P2pServer 服务说明
专门用于进行P2P连接的服务类,下面是P2pServer相关的自定义广播。
4.1.1 P2P连接成功广播
java
com.bjnet.cbox.module.p2pservice.connect
描述:当P2P连接成功后,P2pServer 会发送相关广播。
4.1.2 修改服务发现名称广播
java
com.bjnet.cbox.module.p2pservice.rename
/*
可携带键值对:
wfd_name : 设置的服务发现名称。
*/
描述
用于修改P2P设备名称,当用户需要修改Miracast 发现的设备名称,则需要发送该广播。
调用示例
java
Intent renameIntent = new Intent("com.bjnet.cbox.module.p2pservice.rename");
renameIntent.putExtra("wfd_name", customName);
sendBroadcast(renameIntent);
4.1.3 服务支持的初始化参数
键 | 值类型 | 描述 |
---|---|---|
IS_CREAT_P2P_GO | bool | 用于初始化设置为P2P GO模式进行P2P连接,true:启用P2P GO,false : 是不启用。 |
SET_DEVICE_NAME | string | 设置P2PServer 初始化设置的服务发现名称。 |
调用示例
java
p2pService = new Intent(this, P2pService.class);
if(SharedPreferenceHelper.getInstance().getIsP2pGo()){
p2pService.putExtra("IS_CREAT_P2P_GO", true);
}
p2pService.putExtra("SET_DEVICE_NAME",SharedPreferenceHelper.getInstance().getDeviceName());
this.startService(p2pService);
5 混淆规则
5.1 混淆规则
Android APP集成该SDK时,混淆规则方面请加入以下规则。
-keepclasseswithmembernames class * {
native <methods>;
}
-keep class com.bjnet.cbox.module.* { *; }
-keep class com.bjnet.cbox.util.Log { *; }
5.2 MiracastSink Demo 简要说明
MiracastSink 是一个演示SDK使用的Android APP。SDK和源码请联系我司商务或技术接口获取。
MiracastSink 中实现了MediaChannel 和 MiraProxyBaseImp 抽象类接口,并通过MiraProxyModule 和 MiracastUibc 实现了miracast sink端的实现,并启动播放相关的View,创建用于播放的Surface。
5.3 客户如何使用SDK
在 AndroidManifest.xml 文件中添加系统权限,由于通过WifiP2pManager 中部分接口未开发,且通过反射后要求系统权限才可调用成功。
导入aar,在app目录下新建libs目录并将aar文件放在该目录下。
然后在build.gradle(app)中 dependencies 上方及内部分别添加如下所示代码:
xmlrepositories { flatDir { dirs 'libs' } } dependencies { ... implementation(name: 'bj_miracastgc_lib-1.0.8-release', ext: 'aar') implementation(name: 'cast_base_lib-1.0.52-release', ext: 'aar') ... }
混淆规则请按照5.1节要求设置。