基于Platinum库的DMR实现(android)
接上篇博文: 基于CyberGarage库的dlna开发(android)
文章讲述了用CyberGarage库的DMP实现
部分童鞋想知道DMR是如何实现的
网上似乎也没看到相关的androidcode
在下不才,自个儿捣鼓了project并上传至github
今与诸君共赏
本例所采用的upnp框架是PlatinumSDK
官方网址是http://www.plutinosoft.com/platinum
该库是一个跨平台的C++库,利用该库,可以很容易就构建出DLNA/UPnP控制点(DLNA/UPnPControlPoint)和DLNA/UPnP设备(DLNA/UPnPDevice),其中包括有UPnPAVMediaServer,MediaRender&ControlPoint的例子
该库稳定强大,被很多知名产品所沿用,口碑较好自然也为楼主所青睐
关于该库如何编译,请参考这篇博文:NDK下 将Platinum SDK 编译成so库
下面给出运行效果图:
JNI接口文件:
public class PlatinumJniProxy { static { System.loadLibrary("git-platinum"); } public static native int startMediaRender(byte[] friendname ,byte[] uuid); public static native int stopMediaRender(); public static native boolean responseGenaEvent(int cmd, byte[] value ,byte[] data); public static native boolean enableLogPrint(boolean flag); public static int startMediaRender(String friendname ,String uuid){ if (friendname == null)friendname = ""; if (uuid == null)uuid = ""; int ret = -1; try { ret = startMediaRender(friendname.getBytes("utf-8"), uuid.getBytes("utf-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();} return ret; } public static boolean responseGenaEvent(int cmd, String value, String data){ if (value == null)value = ""; if (data == null)data = ""; boolean ret = false; try {ret = responseGenaEvent(cmd, value.getBytes("utf-8"), data.getBytes("utf-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();} return ret; } }
反射类:
public class PlatinumReflection {private static final CommonLog log = LogFactory.createLog();private static final int MEDIA_RENDER_CTL_MSG_BASE = 0x100;/*----------------------------------------------------------------*/public static final int MEDIA_RENDER_CTL_MSG_SET_AV_URL = (MEDIA_RENDER_CTL_MSG_BASE+0);public static final int MEDIA_RENDER_CTL_MSG_STOP = (MEDIA_RENDER_CTL_MSG_BASE+1);public static final int MEDIA_RENDER_CTL_MSG_PLAY = (MEDIA_RENDER_CTL_MSG_BASE+2);public static final int MEDIA_RENDER_CTL_MSG_PAUSE = (MEDIA_RENDER_CTL_MSG_BASE+3);public static final int MEDIA_RENDER_CTL_MSG_SEEK = (MEDIA_RENDER_CTL_MSG_BASE+4);public static final int MEDIA_RENDER_CTL_MSG_SETVOLUME = (MEDIA_RENDER_CTL_MSG_BASE+5);public static final int MEDIA_RENDER_CTL_MSG_SETMUTE = (MEDIA_RENDER_CTL_MSG_BASE+6);public static final int MEDIA_RENDER_CTL_MSG_SETPLAYMODE = (MEDIA_RENDER_CTL_MSG_BASE+7);public static final int MEDIA_RENDER_CTL_MSG_PRE = (MEDIA_RENDER_CTL_MSG_BASE+8);public static final int MEDIA_RENDER_CTL_MSG_NEXT = (MEDIA_RENDER_CTL_MSG_BASE+9);/*----------------------------------------------------------------*//*----------------------------------------------------------------*//* * * * */public static final int MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_DURATION = (MEDIA_RENDER_CTL_MSG_BASE+0);public static final int MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_POSITION = (MEDIA_RENDER_CTL_MSG_BASE+1);public static final int MEDIA_RENDER_TOCONTRPOINT_SET_MEDIA_PLAYINGSTATE = (MEDIA_RENDER_CTL_MSG_BASE+2);/*----------------------------------------------------------------*/public static final String RENDERER_TOCONTRPOINT_CMD_INTENT_NAME="com.geniusgithub.platinum.tocontrolpointer.cmd.intent";public static final String GET_RENDERER_TOCONTRPOINT_CMD="get_dlna_renderer_tocontrolpointer.cmd";public static final String GET_PARAM_MEDIA_DURATION="get_param_media_duration";public static final String GET_PARAM_MEDIA_POSITION="get_param_media_position";public static final String GET_PARAM_MEDIA_PLAYINGSTATE="get_param_media_playingstate";/*----------------------------------------------------------------*/ public static final String MEDIA_PLAYINGSTATE_STOP="STOPPED"; public static final String MEDIA_PLAYINGSTATE_PAUSE="PAUSED_PLAYBACK"; public static final String MEDIA_PLAYINGSTATE_PLAYING="PLAYING"; public static final String MEDIA_PLAYINGSTATE_TRANSTION="TRANSITIONING"; public static final String MEDIA_PLAYINGSTATE_NOMEDIA="NO_MEDIA_PRESENT"; /*----------------------------------------------------------------*/ public static final String MEDIA_SEEK_TIME_TYPE_REL_TIME="REL_TIME"; public static final String MEDIA_SEEK_TIME_TYPE_TRACK_NR="TRACK_NR"; public static interface ActionReflectionListener{public void onActionInvoke(int cmd,String value,String data);}private static ActionReflectionListener mListener;public static void onActionReflection(int cmd,String value,String data){if (mListener != null){mListener.onActionInvoke(cmd, value, data);}}public static void setActionInvokeListener(ActionReflectionListener listener){mListener = listener;}}
工作线程DMRWorkThread
public class DMRWorkThread extends Thread implements IBaseEngine{private static final CommonLog log = LogFactory.createLog();private static final int CHECK_INTERVAL = 30 * 1000; private Context mContext = null;private boolean mStartSuccess = false;private boolean mExitFlag = false;private String mFriendName = "";private String mUUID = "";private RenderApplication mApplication;public DMRWorkThread(Context context){mContext = context;mApplication = RenderApplication.getInstance();}public void setFlag(boolean flag){mStartSuccess = flag;}public void setParam(String friendName, String uuid){mFriendName = friendName;mUUID = uuid;mApplication.updateDevInfo(mFriendName, mUUID);}public void awakeThread(){synchronized (this) {notifyAll();}}public void exit(){mExitFlag = true;awakeThread();}@Overridepublic void run() {log.e("DMRWorkThread run...");while(true){if (mExitFlag){stopEngine();break;}refreshNotify();synchronized(this){try{wait(CHECK_INTERVAL);}catch(Exception e){e.printStackTrace();}}if (mExitFlag){stopEngine();break;}}log.e("DMRWorkThread over...");}public void refreshNotify(){if (!CommonUtil.checkNetworkState(mContext)){return ;}if (!mStartSuccess){stopEngine();try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}boolean ret = startEngine();if (ret){mStartSuccess = true;}}}@Overridepublic boolean startEngine() {if (mFriendName.length() == 0){return false;}int ret = PlatinumJniProxy.startMediaRender(mFriendName, mUUID);boolean result = (ret == 0 ? true : false);mApplication.setDevStatus(result);return result;}@Overridepublic boolean stopEngine() {PlatinumJniProxy.stopMediaRender();mApplication.setDevStatus(false);return true;}@Overridepublic boolean restartEngine() {setFlag(false);awakeThread();return true;}}
通过startMediaRender开启设备后就可以被外界所发现,控制点发送控制信息后
动作action的回调通过反射类PlatinumReflection的静态方法onActionReflection执行
GENA事件则通过PlatinumJniProxy类的responseGenaEvent传递
详情大家down code去了解吧
Github下载页:https://github.com/geniusgithub/MediaRender
DLNA开发文档链接:http://download.csdn.net/detail/geniuseoe2012/4969961
morebrilliant,PleasepayattentiontomyCSDNblog-->http://blog.csdn.net/geniuseoe2012
更多相关文章
- Android(安卓)Message 及其使用
- Android(安卓)网络图片加载
- 第一天Android校内实习笔记--回顾
- Android(安卓)用 libusb 操作 USB 设备,无须 root
- 解决android下创建avd设备不成功.txt
- 9.9、Libgdx之软键盘
- Android(安卓)Http异步请求,Callback
- 07.Android之Bluetooth
- Android(安卓)判断当前线程是否是主线程的方法