zoukankan      html  css  js  c++  java
  • 基于Platinum库的DMR实现(android)

    接上篇博文: 基于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接口文件:

    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();
    	}
    
    	@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 brilliant,Please pay attention to my CSDN blog -->http://blog.csdn.net/geniuseoe2012 

  • 相关阅读:
    websocket 初识
    JavaScript 系列博客(四)
    JavaScript 系列博客(三)
    JavaScript 系列博客(二)
    JavaScript 系列博客(一)
    前端(八)之形变
    前端(七)之动画与阴影
    java变量、数据类型
    js简单的获取与输出
    Eclipse字体修改
  • 原文地址:https://www.cnblogs.com/lance2016/p/5204280.html
Copyright © 2011-2022 走看看