EasyDlna说明
2019-06-12 17:55 指针空间 阅读(777) 评论(0) 编辑 收藏 举报转载自https://blog.csdn.net/darling757267/article/details/52859153
https://code.csdn.net/Innost/easydlna 代码下载处!
中文说明:
Instructions in English:
一、项目整体介绍
EasyDlna是一个基于Android平台(实际上其核心代码也支持PC平台)的DLNA应用程序集合,它支持DLNA规范中如下组件程序:
- DMS:Digital MediaServer,提供媒体文件浏览,下载等。
- DMC:Digital MediaController,可操作其他服务。
- DMR:Digital MediaRender,可被DMC操作以播放DMS上的媒体文件。
EasyDlna是一个典型的C/S架构,目前它包含如下几个组件:
- EasyDlnaServer:这个是EasyDlna C/S架构中的S端,它提供DLNA各组件的核心实现(DMS,DMR,和DMC)。一般来说,设备只要安装这个服务,即可实现DLNA全部功能。
- EasyDlnaAPI:这个是EasyDlna C/S架构中的C端API封装,以jar包格式提供,客户端使用此jar包可与EasyDlnaServer建立交互关系。
- EasyDlnaClient和EasyDlnaPlayer:这是EasyDlna C/S架构的C端(属于范例APK,用户可参考其实现以实现更为优秀的应用程序)。它们是两个APK,并通过EasyDlnaAPI jar包和EasyDlnaServer通信。其中EasyDlnaClient实现了DMC,而EasyDlnaPlayer实现了DMR。
另外,EasyDlnaServer的核心代码中使用了JNI,它包括:
- EasyDlnaServer/jni/libeasydlna:它是对libupnp的改造,使其符合EasyDlna的设计架构。libeasydlna可加载不同厂商实现的dlna动态库。
- EasyDlnaServer/jni/ libeasydlna_dlna_plugin:它是本项目提供的默认dlna动态库实现。
- libeasydlna.so将加载libeasydlna_dlna_plugin实现的dlna动态库。通过这种方式,第三方开发者可实现自己的dlna动态库供libeasydlna加载。
图1所示为Easydlna的框架结构图。
图1 Easydlna框架图
二、编译和安装
2.1 JNI相关库的编译:
- 到code.csdn.net上搜索EasyDlna,或者git clone git://code.csdn.net/Innost/easydlna.git下载源码。
- 下载NDK编译环境:https://developer.android.com/tools/sdk/ndk/index.html#Installing,选择android-ndk-r10c-linux-x86_64.bin。推荐使用Ubuntu 64位机器作为开发平台。
- 配置NDK环境,使得ndk_build命令在PATH环境中。即在任何一个目录下都可以执行ndk_build(ndk_build是NDK提供的一个命令)。
- 进入EasyDlnaServer目录,执行
- ndk-build -B NDK_PROJECT_PATH=`pwd` NDK_PLATFORM=android-14 命令。它将编译jni目录中的内容,最终会生成libeasy_dlna.so和libeasydlna_dlna_plugin.so。
2.2 其他Java包/APK编译
- EasyDlnaServer、EasyDlnaClient和EasyDlnaPlayer均属于Android应用程序,可通过Eclipse导入并在其中编译。
- EasyDlnaAPI是一个Java库,通过Eclipse加载Java工程创建,最终需通过export导出为Jar包。注意,EasyDlnaAPI编译的时候依赖Android SDK提供的Android.jar包。
- EasyDlnaClient和EasyDlnaPlayer依赖EasyDlnaAPI.jar。所以,当EasyDlnaAPI导出后,需要将其手动拷贝到EasyDlnaClient/libs和EasyDlnaPlayer/libs目录,并在EasyDlnaClient和EasyDlnaPlayer的Eclipse工程中,将各自libs/下的EasDlnaAPI.jar包作为依赖库加入。
2.3 APK Demo
图2所示为EasyDlnaServer运行界面:
图2 EasyDlnaServer运行界面
- 进入EasyDlnaServer后,通过单击图2左边的EasyDlnaServer图标可启动EasyDlnaServer,它是一个DMS。
- 图2右边所示为DMS的配置,可以设置可共享的媒体类型,DMS服务器名等。设置完毕后单击“StartService”按钮
图3所示为EasyDlnaClient运行界面。
图3 EasyDlnaClient运行示意图
图3中:
- 右上角对话框为搜索并链接上的DMS,可通过它选择需要连接的DMS。
- 中间红框为该DMS上的视频、音频和图片资源
- 单击Menu键,可弹出右下角的红框。其中有四个按钮,分别用户重新搜索DMS、重新枚举DMS上的媒体资源、重新搜索DMR和退出。
单击任何一个媒体资源,将弹出图4:
图4 播放选择
EasyDlnaClient支持本地Render和远程Render播放。本地Render名为“Local Render”,远程Render为搜索到的DMR名。单击媒体文件,可选择是Local Render播放还是远程Render播放。注意,只有搜索到DMR时,”Select a render“菜单才会将其显示出来。
三、代码实现说明
本节介绍JNI、EasyDlnaServer以及EasyDlnaAPI的实现。EasyDlnaClient和EasyDlnaPlayer做为Demo API,请自行研究。
3.1 JNI库实现
1. libeasydlna
libeasydlna位于EasyDlnaServer/jni/libeasydlna目录下,其包含四个子目录:
- dlnafw:对原libupnp进行了C++封装,对外提供一致的接口。
- ixml,threadutil和upnp:原libupnp的代码。
图5所示为dlnafw中定义的几个核心类及作用:
图5 dlnafw核心类
图5中:
- IUpnp、IUpnpControlPoint以及IUpnpDevice是对libupnp中相关操作类的封装。
- IWebVFSCallbacks:是对HTTP文件操作请求的封装。
- IDlnaFrame实现了对插件类的操作,可从第三方插件中获取它们实现的DLNA组件。这些组件由接口类IDMServer、IDMController和IDMRender表达。
2. libeasydlna_dlna_plugin
- libeasydlna_dlna_plugin是本项目提供的默认dlna插件实现。其目录包括:
- libeasydlna_dlna_plugin:DLNA组件的通用实现。
- Android:DLNA组件中某些服务项部分的Android平台实现。
先来看如图6的DLNA组件通用实现类:
图6 DLNA组件通用实现
- CESDlnaPlugin.h:插件必须实现其中的这5个函数。dlnafw将调用其中的函数以获取插件实现的DLNA组件。
- CESDMServer、CESDMRender和CESDMController是该插件提供的DLNA组件实现。
- IDlnaContentDirectory、IDlnaAVTransport、IDlnaConnectionManager以及IDlnaRenderingControl是DLNA不同组件必须实现的服务接口。这些由dlnafw定义,而默认插件分别实现了它们。
Android目录下是某些服务或组件在Android平台上的实现。通过这种分模块方式,开发者可以很轻松的:
通过第三方插件来实现不同组件。
利用默认插件,并提供不同服务实现来定制dlna功能。
3.2 EasyDlnaServer
EasyDlnaServer中的核心package是com.easydlna.dlna.service,如图7所示:
图7 com.easydlna.dlna.service类
DMService、DMCService和DMRService都是Android Service的派生类。其中,DMSservice实现了DMS,一个设备一般创建一个DMS即可。DMCService为一个Controller,它可以搜索网络内部的DMS和DMR(本设备上运行的DMS和DMR也会被搜索到)。DMRService实现了一个DMRender,一般一个设备创建一个DMR即可。
DlnaDevice是Java层对DLNA设备的封装。
ContentInfo是对DMS中媒体资源信息的封装。
RenderStatus是对DMR播放媒体资源时一些诸如时间,状态等信息的封装。
说明:
DMService是EasyDlna中DMS的实现,它将通过JNI与libeasydlna以及libeasydlna_dlna_plugin交互。其列举的媒体信息来源于MediaProvider。
DMCService是EasyDlna中DMC功能的桥接和代理,它通过EasyDlnaAPI与客户端(例如EasyDlnaClient)交互。客户端是真正意义上的DMC。
DMRService是EasyDlna中DMR功能的桥接和代理,它通过EasyDlnaAPI与客户端(例如EasyDlnaRender)交互。客户端是真正意义上的DMR。
3.3 EasyDlnaAPI
EasyDlnaAPI封装了与EasyDlnaServer交互的细节,外部程序只需要实现对应的接口类即可。图8所示为其中的几个重要类图。
图8 EasyDlnaAPI三个重要类
图8中三个Client类分别和EasyDlnaServer中的三个Service交互。
四、总结和改进
图9所示为本项目的代码行数统计。
图9 代码行数统计
- 大部分C代码由libupnp引入。
- C++/java代码总计大约在2万行左右
下面列出针对此项目的一些改善建议:
- DMS,DMR等DLNA组建的XML描述目前都是硬编码在native的头文件中,以后可通过Java层传递对应的XML文件来提供更加灵活的实现方式。
- EasyDlnaServer和EasyDlnaAPI中有部分代码重合(com.easydlna.dlna.service包),未来可开发一个公共的模块。
- EasyDlnaServer中的DMCService会去枚举DMS上的媒体资源信息,由于设备上的媒体资源信息都非常多,所以列举速度比较慢,这一块需要做更为精细的控制和优化。
- EasyDlnaServer的DMS提供基于HTTP方式的媒体文件下载和播放,以后希望能提供流方式的媒体文件播放,可推荐的开源流媒体服务库包括live555。
EasyDlnaInstructions and Implementation Details
1 Overview of EasyDlna
EasyDlna is anDLNA application suites based on Android platform. Currently, it supportsfollowing components defined by DLNA protocol:
- DMS: Digital Media Sever which supply media resources browsing andplaying.
- DMC:Digital Media Controller which is used to interact with otherUPNP Devices like DMS or DMR.
- DMR:Digital Media Render which is used to play media resources foundin one or more DMSs. It likes a MediaPlayer, but it could only be controlled byDMC.
EasyDlna usesC/S software architecture, it contains following things:
- EasyDlnaServer:Server in C/S arch. It has implemented DMS,DMR andDMC.
- EasyDlnaAPI: API wrapper for Client usage. It is a jar file, Clientsapk should use this jar to communicate with EasyDlnaServer.
- EasyDlnaClient and EasyDlnaPlayer:They are two apks which are alsoclients in C/S arch. EasyDlnaClient implents DMC and EasyDlnaPlayer implementsDMR.
In addition toJava code, Some core features of EasyDlnaServer are implemented by native codeusing JNI. The JNI parts of EasyDlnaserver are composed of:
- EasyDlnaServer/jni/libeasydlna:a modification version of libupnp for EasyDlna own usage. It could load vendorspecific dlna implementation libraries.
- EasyDlnaServer/jni/ libeasydlna_dlna_plugin: Default implementationof dlna provided by this project.
In short,libeasydlna.so will load libeasydlna_dlna_plugin which implements some corefeatures of DLNA. Though this way, 3rd party developers could develop their ownfeatures and could be loaded by EasyDlnal.
Figure 1 showssome hints of EasyDlna Architecture.
Figure 1 Easydlna Architecture
2 Build and Installation
2.1 JNI relatedcode compilation:
- download all code using "git clone git://code.csdn.net/Innost/easydlna.git",or search EasyDlna in code.csdn.net
- download NDK build enviroment tools though https://developer.android.com/tools/sdk/ndk/index.html#Installing.Recommended tools is android-ndk-r10c-linux-x86_64.binand Ubuntu 64 platform.
- Configure NDK build enviroment: add ndk_build command path to PATHenviromet, so you could execute "ndk_build" command in any path
- cd EasyDlnaServer dir, and execute " ndk-build-B NDK_PROJECT_PATH=`pwd` NDK_PLATFORM=android-14 ", it willcompile code under jni dir and the created so will be libeasy_dlna.so andlibeasydlna_dlna_plugin.so
2.2 Java Packageand APKCompilation
- EasyDlnaServer,EasyDlnaClient and EasyDlnaPlayer are Android APKs,please import their code into Eclipse.
- EasyDlnaAPI is a Java project, Please use Eclipse to import it. Thefinal EasyDlnaAPI.jar could be exported using Eclipse. Note that EasyDlnaAPIdepends on android.jar which is provided through Android SDK.
- EasyDlnaClient and EasyDlnaPlayer depend on EasyDlnaAPI.jar. Afteryou get EasyDlnaAPI.jar, manually copy it to EasyDlnaClient/libs andEasyDlnaPlayer/libs. And also use " Add External Jar" to putEasyDlnaAPI.jar into Build Path of each APK.
2.3 APK Demo
Figure 2 showshow EasyDlnaServer looks like when it is running:
Figure2 UI of EasyDlnaServer
- When it is launched, Click "EasyDlnaServer" icon to startDMService.
- From right part of figure 2, you could configure DMS, like what kindof Media Resource could be browsed by DMC and the name of DMS.Afterconfiguration, click "Start Service" to really start DMService.
Figure 3 showsUI of EasyDlnaClient:
Figure 3 UIof EasyDlnaClient
From Figure 3:
- Right Top is a list box which shows connected DMSs the DMC finds inLocal Network. You could select the desired DMS to browse its media resources.
- In the middle red frame, it categorize media resources into Video,Audio and Image types.
- Click Menu button of Android device, it will show UI in the bottomwhich resides four buttons. It could enable user to rescan DMSs, Refresh MediaResources in selected DMS, Rescan DMP and Exit the current application.
When click onemedia resouce, figure 4 tells you what will happen:
Figure 4 Play selected media resource
EasyDlnaClientsupports Local Render and Remote Render. The local render's name is "LocalRender". The name of a Rmote Render is actually the name of the DMR . Whenyou click a media resource, It will pop a "Select a Render" dialog toask where to play it. So, if only DMR has been found, it will have an option in"Select a Render" dialog.
If you chooseLocal Render, EasyDlnaClient will play the selected media resource for you.
3. Code Implementation
This sectionwill talk a little detail info about JNI part, EasyDlnaServer and EasyDlnaAPI.Please read the code of the rest part.
3.1 Implementationof JNI part
1. libeasydlna
libeasydlnalocates in EasyDlnaServer/jni/libeaydlna, it includes for child dirs:
- dlnafw:c++ wrapperof libupnp.
- ixml,threadutil and upnp:code of libupnp
Figure 5 showsserveral important classes of dlnafw.
Figure 5 dlnafw
In figure 5:
- IUpnp、IUpnpControlPointand IUpnpDevice are wrapper of related action/data structure of libupnp
- IWebVFSCallbacks:interface which abstracts file operations when using http todownload a file.
- IDlnaFrame implements plugin operation which is used to get DLNAcomponents implemented by other plugin. These DLNA compoments could beabstracted into 3 classes, they are IDMServer, IDMController and IDMRender,
2. libeasydlna_dlna_plugin
libeasydlna_dlna_pluginprovides default implmentation of dlna plugin, its dir include:
- libeasydlna_dlna_plugin:common implementaion of DLNA components
- Android:Some services (a definition used in DLNA protocol) implmented inAndroid Platform.
Figure 6 showcommon part of DLNA plugin:
Figure 6 Commonpart of DLNA Plugin:
- CESDlnaPlugin.h:A dlna plugin must implements 5 functions listed in the figure.dlnafw will call them to get vendor specific DLNA components.
- CESDMServer、CESDMRender和CESDMController are DLNA components implemented by this default DLNAplugin.。
- IDlnaContentDirectory,IDlnaAVTransport,IDlnaConnectionManager and IDlnaRenderingControlare different DLNA services that different DLNA components must have. They aredefined in dlnafw and our default DLNA plugin must implement them.
In Androidplatform, its specific implementation locates in Android dir. Through this way,developers could easily:
- Using special dlna plugin to implement their own features.
- Using default dlna plugin but choose default services implementationto customize dlna features.
3.2 EasyDlnaServer
Figure 7 showcore package "com.easydlna.dlna.service" of EasyDlnaServer:
Figure 7 com.easydlna.dlna.service
- DMService、DMCService and DMRService are all derived from Android Service.DMService implemnt DMS feature. One device only need to create one DMS.DMCService is a controller, it could scan DMSs and DMRs in the local network.DMRService is a DMRender. One device only need to create one DMR.
- DlnaDevice is a wrapper of DLNA device in Java layer.
- ContentInfo is a wrapper of Media Resource in DMS.
- RenderStatus is a wrappper of playing info such as time, status of aplayer.
Notes that:
- DMService is the implementation of DMS in EasyDlna project. It useJNI to communicate with libeasydlna and libeasydlna_dlna_plugin. The MediaResource info are from MediaProvider in Android Platform.
- DMCService is actually a brigde or proxy of DMC feature. It will useEasyDlnaAPI to the real DMC implementation(for example, EasyDlanCilent).
- DMRService is actually a bridge or proxy of DMR feature. It will useEasyDlnaAPI to the real DMR implementation(like EasyDlnaPlayer).
3.3 EasyDlnaAPI
EasyDlnaAPI encapsulatesall detailed interactions with EasyDlnaServer, Clients only need to implementsome classes and interfaces exportedby EasyDlnaAPI. Figure 8 shows threeimportant classes in EasyDlnaAPI.
Figure 8 Three important classes of EasyDlnaAPI
The above threeclients will interact with corresponding services in EasyDlnaServer.
4 Summary andfuture improvements
Figure 9 showssource code lines of EasyDlna Project:
Figure 9 source code lines
Most C part code is brought by libupnp.
- C++ and java code together are about 20000 lines.
- Here are someimprovements hints about this project:
- In current implementation, XML descripion of DLNA components arehard coded. In the future, we could use xml files.
- Some codes (com.easydlna.dlna.service actually) of EasyDlnaServerand EasyDlnaAPI are duplicate, we could develop a common part to eraseduplication.
q DMCService in EasyDlnaServer will browse media resources of a DMS.As nowadays, a device has many media files, this procedure will last long. Somefiner improvement is needed.
q DMS in EasyDlnaServer provides media resource download only in httpways. In the future, stream media server is prefered. The recommondedopensource stream media server is live555, Please give it a try!