基于Platinum库的DMR实现(android)-MediaRender

xiaoxiao2021-02-28  73

接上篇博文: 基于CyberGarage库的dlna开发(android)

文章讲述了用CyberGarage库的DMP实现

部分童鞋想知道DMR是如何实现的

网上似乎也没看到相关的Android code

有鉴于此,蓝老师特地捣鼓了project并上传至github

希望对童鞋们有帮助~

本例所采用的upnp框架是Platinum SDK

官方网址是http://www.plutinosoft.com/platinum 

该库是一个跨平台的C++库,利用该库,可以很容易就构建出DLNA/UPnP控制点 (DLNA/UPnP Control Point)DLNA/UPnP设备(DLNA/UPnP Device),其中包括有UPnP AV Media Server, Media Render & Control Point的例子 

该库稳定强大,被很多知名产品所沿用,口碑较好自然也为楼主所青睐

关于该库如何编译,请参考这篇博文:NDK下 将Platinum SDK 编译成so库 

下面给出运行效果图:

JNI接口文件:

[java]  view plain  copy 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;       }                 }   反射类:

[java]  view plain  copy 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

[java]  view plain  copy 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();       }          @Override       public 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;               }           }          }              @Override       public 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;       }          @Override       public boolean stopEngine() {           PlatinumJniProxy.stopMediaRender();           mApplication.setDevStatus(false);           return true;       }          @Override       public 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

关于SO库的具体C++实现可参考这篇博文:

http://blog.csdn.net/lancees/article/details/9178385

DMS的实现请参考这篇博文:基于Platinum库的DMS实现(android)

more brilliantPlease pay attention to my  blog -->http://blog.csdn.net/geniuseoe2012 

转载请注明原文地址: https://www.6miu.com/read-51667.html

最新回复(0)