基于PlatinumKit库的DLNA服务端开发
首先,需要特别感谢蓝斯老师的资料,我这里有很大一部分是参考蓝斯老师的,附上传送门:http://blog.csdn.net/lancees/article/details/9178385


图1
PltMediaRendererDelegate *mediaRenderDelegate; PLT_MediaRenderer *mediaRenderer; PLT_DeviceHostReference device; PLT_UPnP upnp; JNIEXPORT jint JNICALL Java_com_pngcui_skyworth_dlna_jni_PlatinumJniProxy_startDlnaMediaRender (JNIEnv *env, jclass, jbyteArray name, jbyteArray uuid) { ; jbyte *bytes; char *c_name = ConvertJByteaArrayToChars(env, name, bytes); jbyte *bytes2; char *c_uuid = ConvertJByteaArrayToChars(env, uuid, bytes2); LOGI("name = %s,uuid = %s",c_name,c_uuid); if(mediaRenderDelegate == NULL) mediaRenderDelegate = new PltMediaRendererDelegate(); mediaRenderer= new PLT_MediaRenderer(c_name,false,c_uuid); mediaRenderer->SetDelegate(mediaRenderDelegate); PLT_DeviceHostReference device1(mediaRenderer); device = device1; upnp.AddDevice(device); ret = upnp.Start(); env->ReleaseByteArrayElements(name, bytes, JNI_ABORT); env->ReleaseByteArrayElements(uuid, bytes2, JNI_ABORT); delete c_name; delete c_uuid; return ret; }
NPT_Result PLT_MediaRenderer::OnAction(PLT_ActionReference& action, const PLT_HttpRequestContext& context) { NPT_COMPILER_UNUSED(context); /* parse the action name */ NPT_String name = action->GetActionDesc().GetName(); LOGI("OnAction -> %s",name.GetChars()); ... ) { return OnPlay(action); } ... return NPT_FAILURE; } NPT_Result PLT_MediaRenderer::OnPlay(PLT_ActionReference& action) { if (m_Delegate) { return m_Delegate->OnPlay(action); } return NPT_ERROR_NOT_IMPLEMENTED; }
NPT_Result PltMediaRendererDelegate::OnPlay(PLT_ActionReference& action) { LOGI("OnPlay"); NPT_String curURI; action->GetArgumentValue("CurrentURI", curURI); NPT_String metaData ; action->GetArgumentValue("CurrentURIMetaData", metaData); ActionInflect(MEDIA_RENDER_CTL_MSG_PLAY, curURI.GetChars(),metaData.GetChars()); return NPT_SUCCESS; } void PltMediaRendererDelegate::ActionInflect(int cmd, const char* value, const char* data) { int status; JNIEnv *env = NULL; bool isAttach = false; if(g_vm == NULL) LOGI("g_vm == NULL"); status = g_vm->GetEnv((void **) &env, JNI_VERSION_1_4); ) { status = g_vm->AttachCurrentThread(&env, NULL); LOGI("status = %d",status); ) { LOGI("callback_handler: failed to attach , current thread, status = %d", status); return; } isAttach = true; } jstring valueString = NULL; jstring dataString = NULL; jclass inflectClass = g_inflectClass; if (inflectClass == NULL) { LOGI("inflectClass == NULL return"); } jmethodID inflectMethod = g_methodID; if (inflectMethod == NULL) { LOGI("inflectMethod == NULL return"); } if (inflectClass == NULL || inflectMethod == NULL) { LOGI("goto end"); goto end; } LOGI("CMD = %d VALUE = %s DATA = %s",cmd, value, data); valueString = env->NewStringUTF(value); dataString = env->NewStringUTF(data); env->CallStaticVoidMethod(inflectClass, inflectMethod, cmd, valueString, dataString); env->DeleteLocalRef(valueString); env->DeleteLocalRef(dataString); end: if (env->ExceptionOccurred()) { LOGI("clear..."); env->ExceptionDescribe(); env->ExceptionClear(); } if (isAttach) { g_vm->DetachCurrentThread(); } }
注:Android6.0以上版本无法使用 env->CallStaticVoidMethod进行反射,因为google官方对jvm进行了一些列的优化
void InitInflectClass(JavaVM* vm) { g_vm = vm; JNIEnv *env = NULL; int status = g_vm->GetEnv((void **) &env, JNI_VERSION_1_4); ) { return ; } jclass inflectClass = env->FindClass("com/pngcui/skyworth/dlna/jni/PlatinumReflection"); if (inflectClass == NULL) { LOGI("inflectClass == NULL return"); return ; } g_inflectClass = (jclass)env->NewGlobalRef(inflectClass); jmethodID methodID = env->GetStaticMethodID(inflectClass, "onActionReflection", "(ILjava/lang/String;Ljava/lang/String;)V"); if (methodID == NULL) { LOGI("methodID == NULL return"); return ; } g_methodID = methodID; return ; }
/* * Class: com_pngcui_skyworth_dlna_jni_PlatinumJniProxy * Method: responseGenaEvent * Signature: (J)I */ JNIEXPORT jboolean JNICALL Java_com_pngcui_skyworth_dlna_jni_PlatinumJniProxy_responseGenaEvent (JNIEnv *env, jclass, jint cmd, jbyteArray value, jbyteArray data) { // NPT_LOG_INFO("response"); jbyte *bytes; char *c_value = ConvertJByteaArrayToChars(env, value, bytes); jbyte *bytes2; char *c_data = ConvertJByteaArrayToChars(env, data, bytes2); LOGI("ResponseGenaEvent value = %s data = %s",c_value,c_data); mediaRenderer->UpdateServices(c_value,c_data); env->ReleaseByteArrayElements(value, bytes, JNI_ABORT); env->ReleaseByteArrayElements(data, bytes2, JNI_ABORT); delete c_value; delete c_data; return true; }
NPT_Result PLT_MediaRenderer::UpdateServices(const char* value,const char* data) { PLT_Service* serviceUpdate; if(FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", serviceUpdate) == NPT_ERROR_NO_SUCH_ITEM){ LOGI("cant find PLT_Service....."); return NPT_FAILURE; } ) == ) == ':') { ) == 'd') { serviceUpdate->SetStateVariable("CurrentTrackDuration", value); serviceUpdate->SetStateVariable("CurrentMediaDuration", value); } else { serviceUpdate->SetStateVariable("RelativeTimePosition", value); serviceUpdate->SetStateVariable("AbsoluteTimePosition", value); } } else { serviceUpdate->SetStateVariable("TransportState", value); } return NPT_SUCCESS; }

NPT_Result PLT_MediaRenderer::OnAction(PLT_ActionReference& action, const PLT_HttpRequestContext& context) { ... // other actions rely on state variables NPT_CHECK_LABEL_WARNING(action->SetArgumentsOutFromStateVariable(), failure); return NPT_SUCCESS; failure: action->SetError(,"No Such Action."); return NPT_FAILURE; }
接下来就是APP播放的实现了,可参考蓝斯老师的博客:http://blog.csdn.net/lancees/article/details/8951679
基于PlatinumKit库的DLNA服务端开发的更多相关文章
- 基于JAX-WS的Web Service服务端/客户端 ;JAX-WS + Spring 开发webservice
一.基于JAX-WS的Web Service服务端/客户端 下面描述的是在main函数中使用JAX-WS的Web Service的方法,不是在web工程里访问,在web工程里访问,参加第二节. JAX ...
- Day01_搭建环境&CMS服务端开发
学成在线 第1天 讲义-项目概述 CMS接口开发 1 项目的功能构架 1.1 项目背景 受互联网+概念的催化,当今中国在线教育市场的发展可谓是百花齐放.如火如荼. 按照市场领域细分为:学前教育.K12 ...
- Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)
本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...
- Swift3.0服务端开发(三) Mustache页面模板与日志记录
本篇博客主要介绍如果在Perfect工程中引入和使用Mustache页面模板与日志记录系统.Mustache页面模板类似于PHP中的smarty模板引擎或者Java中的JSTL标签.当然Mustach ...
- Swift3.0服务端开发(五) 记事本的开发(iOS端+服务端)
前边以及陆陆续续的介绍了使用Swift3.0开发的服务端应用程序的Perfect框架.本篇博客就做一个阶段性的总结,做一个完整的实例,其实这个实例在<Swift3.0服务端开发(一)>这篇 ...
- WCF服务端开发和客户端引用小结
1.服务端开发 1.1 WCF服务创建方式 创建一个WCF服务,总是会创建一个服务接口和一个服务接口实现.通常根据服务宿主的不同,有两种创建方式. (1)创建WCF应用程序 通过创建WCF服务应用程序 ...
- 从架构师视角看是否该用Kotlin做服务端开发?
前言 自从Oracle收购Sun之后,对Java收费或加强控制的尝试从未间断,谷歌与Oracle围绕Java API的官司也跌宕起伏.虽然Oracle只是针对Oracle JDK8的升级收费,并释放了 ...
- 微服务项目开发学成在线_day01_CMS服务端开发
05-CMS需求分析-什么是CMS 什么是CMS?CMS (Content Management System)即内容管理系统,不同的项目对CMS的定位不同.CMS有哪些类型? 每个公司对每个项目的C ...
- 俯瞰 Java 服务端开发
原文首发于 github ,欢迎 star . Java 服务端开发是一个非常宽广的领域,要概括其全貌,即使是几本书也讲不完,该文将会提到许多的技术及工具,但不会深入去讲解,旨在以一个俯瞰的视角去探寻 ...
随机推荐
- THREE笛卡尔右手坐标系详解
1,正常的笛卡尔右手坐标系,以屏幕右方为+X轴,屏幕上方为+Y轴,垂直屏幕向外为+Z轴,如下图,xy轴组成的平面为屏幕面 但由于THREE里的相机并不总是从屏幕正前方视角,还可以设置坐标系任意一个轴为 ...
- File 常用方法
1.判断当前文件是否封装的文件夹目录 //返回true--是,false--不是 File file =new File("C:\\Users\\mac\\Desktop\\复习.txt&q ...
- java 与操作系统同步问题(三)————父亲儿子女儿水果问题
问题描述:父亲每次都会放一个水果在桌子上,女儿喜欢吃香蕉(只吃香蕉), 儿子喜欢吃苹果(只吃苹果).父亲每次只会随机往桌子上放一个水果(苹果或香蕉),儿子,女儿会来取.使用p.v操作来完成父亲.儿子. ...
- Linux常用命令-jdk和Tomcat
一.JDK的安装和配置 1.下载jdk文件 去官方网站下载Linux 64位 jdk-8u131-linux-x64.tar.gz 2.使用Ftp工具上传到/usr/local 下. 使用命令:ta ...
- 玩转Storage Table 的PartitionKey,RowKey设计
参阅的文章 l https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/designing-a-scalable ...
- javascript基础-闭包
原理 函数里包含函数,即闭包. 包含函数的结果是,子函数会挟持父函数的活动对象.子函数在访问一个变量时,先读自身的活动对象,是否包含此变量,没有从父函数里找,还没有,去祖函数,层层回溯,直到windo ...
- 一天搞定CSS:盒模型content、padding、border、margin--06
1.盒模型 网页设计中常听的属性名:内容(content).填充(padding).边框(border).边界(margin), CSS盒子模式都具备这些属性. 这些属性我们可以用日常生活中的常见事物 ...
- java中的中文参数存到数据库乱码问题
关于java中的中文参数乱码问题,遇见过很多,若开发工具的字符集环境和数据库的字符集环境都一样,存到数据库中还是乱码的话,可以通过以下方法解决: 用数据库客户端检查每个字段的字符集和字符集校对和这个表 ...
- Dojo初探之1:AMD规范,编写符合AMD规范(异步模块加载机制)的模块化JS(其中dojo采用1.11.2版本)
一.AMD规范探索 1.AMD规范(即异步模块加载机制) 我们在接触js的时候,一般都是通过各种function来定义一些方法,让它们帮我们做一些事情,一个js可以包含很多个js,而这些functio ...
- WPF Dashboard仪表盘控件的实现
1.确定控件应该继承的基类 从表面上看,目前WPF自带常用控件中,没有一个是接近这个表盘控件的,但将该控件拆分就能够发现,该控件的每个子部分都是在WPF中存在的,因此我们需要将各个子控件组合才能形成这 ...