Giter VIP home page Giter VIP logo

dlna-cast's Introduction

DLNA-Cast

Author: LIUWEI
Email: [email protected]

Download

整理重构中.... 整理重构中.... 整理重构中....

有时间会更新这个库,好多人在问Dmr的问题,我这个只是最简单的一个VideoView示例,具体还是需要自己集成播放器,实现各种格式的流。 另外我也在做DLNA的Flutter库,差不多了也会开源出来。

投屏 爱奇艺、优酷、腾讯 TV端的时候,m3u8格式会失败,url需要带参数,带上之后就可以了,这个有时间再研究下(自己模拟了下,可以正常投屏了,但是应该有有效期,暂不清楚具体的机制) 国内Tv App很多不支持多码率的流,用单码率就就可以播放,但是爱奇艺不行,app应该有特殊的限制。

功能

基于Cling库封装的DLNA投屏库

  • 支持移动端设备发现控制投射功能(DMC)
  • 支持电视端设备播放器功能(DMR)
  • 支持服务端设备共享内容(DMS)

Cling库(v2.1.1)

Cling Core Cling Support

#App示例

AppScreenshot AppScreenshot AppScreenshot AppScreenshot

使用说明

引用地址

在项目根gradle中引入

allprojects {
    repositories {
		...
        maven { url 'http://4thline.org/m2' }
		maven { url 'https://jitpack.io' }
	}
}

在项目模块gradle中引入

api 'com.github.devin1014.DLNA-Cast:dlna-dmc:vx.x.x' 
api 'com.github.devin1014.DLNA-Cast:dlna-dmr:vx.x.x'
api 'com.github.devin1014.DLNA-Cast:dlna-dms:vx.x.x'

直接引用aar亦可

权限申明

在AndroidManifest.xml中需要添加如下

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

服务申明

在AndroidManifest.xml中需要添加如下

<service android:name="com.android.cast.dlna.dmc.DLNACastService"/>
<service android:name="com.android.cast.dlna.dmr.DLNARendererService"/>
<service android:name="com.android.cast.dlna.dms.DLNAContentSercice"/>

注册服务

在Activity或者Fragment中绑定/解绑

@Override
protected void onStart() {        
    DLNACastManager.getInstance().bindCastService(this);
}

@Override
protected void onStop() {
    DLNACastManager.getInstance().unbindCastService(this);
}

当绑定服务后,会自动搜索设备,也可以手动搜索。

DLNACastManager.getInstance().search();

监听设备

DLNACastManager.getInstance().registerDeviceListener(listener);
DLNACastManager.getInstance().unregisterListener(listener);

当发现新设备时需要添加到设备列表中用于显示。

  • OnDeviceRegistryListener 该接口回调始终在主线程线程被调用

连接设备

deviceControl: DeviceControl = DLNACastManager.connectDevice(device, callback)

DeviceControl接口如下:
DeviceControl {
    // 投射当前视频
    fun setAVTransportURI(uri: String, title: String, callback: ServiceActionCallback<Unit>?) {}
    // 投射下一个视频(不是每个播放器都支持这个功能,当前播放结束自动播放下一个)
    fun setNextAVTransportURI(uri: String, title: String, callback: ServiceActionCallback<Unit>?) {}
    // 播放
    fun play(speed: String, callback: ServiceActionCallback<Unit>?) {}
    // 暂停
    fun pause(callback: ServiceActionCallback<Unit>?) {}
    // 停止
    fun stop(callback: ServiceActionCallback<Unit>?) {}
    // 快进/快退
    fun seek(millSeconds: Long, callback: ServiceActionCallback<Unit>?) {}
    // 播放下一个视频
    fun next(callback: ServiceActionCallback<Unit>?) {}
    // 播放上一个视频
    fun previous(callback: ServiceActionCallback<Unit>?) {}
    // 获取当前投射视频的播放信息,当前时间/总时间
    fun getPositionInfo(callback: ServiceActionCallback<PositionInfo>?) {}
    // 获取当前视频信息
    fun getMediaInfo(callback: ServiceActionCallback<MediaInfo>?) {}
    // 获取当前播放状态等
    fun getTransportInfo(callback: ServiceActionCallback<TransportInfo>?) {}
    // 设置音量
    fun setVolume(volume: Int, callback: ServiceActionCallback<Unit>?) {}
    // 获取音量
    fun getVolume(callback: ServiceActionCallback<Int>?) {}
    // 设置静音
    fun setMute(mute: Boolean, callback: ServiceActionCallback<Unit>?) {}
    // 获取是否静音
    fun getMute(callback: ServiceActionCallback<Boolean>?) {}
    // 查询objectId的信息(‘0’默认值即所有信息)
    fun browse(objectId: String, flag: BrowseFlag, filter: String, firstResult: Int, maxResults: Int, callback: ServiceActionCallback<DIDLContent>?) {}
    // 查找objectId的信息
    fun search(containerId: String, searchCriteria: String, filter: String, firstResult: Int, maxResults: Int, callback: ServiceActionCallback<DIDLContent>?) {}
}

每个操作都有相应的参数和事件回调接口,监听操作是否成功

dlna-cast's People

Contributors

devin1014 avatar weiliush avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dlna-cast's Issues

无法投屏本地视频

本地文件选择后的播放路径是:http://192.168.1.101:8192/storage/emulated/0/yyy/ppppp.mp4
1.投屏播放网络文件是可以的
2.发现有报错
W/System.err: java.lang.RuntimeException: Null or empty XML
W/System.err: at org.fourthline.cling.support.lastchange.LastChangeParser.parse(LastChangeParser.java:108)
W/System.err: at com.android.cast.dlna.dmc.control.CastSubscriptionCallback.eventReceived(CastSubscriptionCallback.java:72)
W/System.err: at org.fourthline.cling.controlpoint.SubscriptionCallback$2.eventReceived(SubscriptionCallback.java:223)
W/System.err: at org.fourthline.cling.model.gena.RemoteGENASubscription.receive(RemoteGENASubscription.java:114)
W/System.err: at org.fourthline.cling.protocol.sync.ReceivingEvent$2.run(ReceivingEvent.java:131)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:929)
W/System.err: java.lang.RuntimeException: Null or empty XML
W/System.err: at org.fourthline.cling.support.lastchange.LastChangeParser.parse(LastChangeParser.java:108)
W/System.err: at com.android.cast.dlna.dmc.control.CastSubscriptionCallback.eventReceived(CastSubscriptionCallback.java:72)
W/System.err: at org.fourthline.cling.controlpoint.SubscriptionCallback$2.eventReceived(SubscriptionCallback.java:223)
W/System.err: at org.fourthline.cling.model.gena.RemoteGENASubscription.receive(RemoteGENASubscription.java:114)
W/System.err: at org.fourthline.cling.protocol.sync.ReceivingEvent$2.run(ReceivingEvent.java:131)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:929)
您能帮忙看下是哪里的问题吗?

请问支持服务端吗?

我利用手机可以投射到电脑(win Media player)播放视频,可以用电脑不能反向操作(电脑可播放设备列表无对应设备),请问怎们才能支持?

电视安装云视听极光,无法检索出,日志出现崩溃

2022-08-18 21:13:48.900 17063-18089/com.android.cast.dlna.demo E/DLNA_Cast: ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2022-08-18 21:13:48.901 17063-18089/com.android.cast.dlna.demo E/DLNA_Cast: │ Thread: cling-10
2022-08-18 21:13:48.901 17063-18089/com.android.cast.dlna.demo E/DLNA_Cast: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2022-08-18 21:13:48.901 17063-18089/com.android.cast.dlna.demo E/DLNA_Cast: │ [客厅极光TV(dlna)] discovery failed...
2022-08-18 21:13:48.901 17063-18089/com.android.cast.dlna.demo E/DLNA_Cast: └────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2022-08-18 21:13:48.901 17063-18089/com.android.cast.dlna.demo E/DLNA_Cast: ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2022-08-18 21:13:48.901 17063-18089/com.android.cast.dlna.demo E/DLNA_Cast: │ Thread: cling-10
2022-08-18 21:13:48.901 17063-18089/com.android.cast.dlna.demo E/DLNA_Cast: ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
2022-08-18 21:13:48.902 17063-18089/com.android.cast.dlna.demo E/DLNA_Cast: │ org.fourthline.cling.model.ValidationException: Validation of device graph failed, call getErrors() on exception
2022-08-18 21:13:48.902 17063-18089/com.android.cast.dlna.demo E/DLNA_Cast:

爱投屏电视投屏失败

这边测试发现,使用提前投屏软件进行爱投屏电视投屏的时候,电视会弹窗询问是否允许,用DLNA_Cast进行投屏,电视不会弹出询问,投屏无法成功。是不是缺少了什么参数?

简单的一个类,搜索不出设备,偶尔进页面崩溃,demo中的mainactivity 如果OnDeviceRegistryListener不在adapter中,直接写在activity也搜不出设备

/**

  • 投屏
    /
    class TpActivity : BaseActivity(R.layout.cling_dialog),
    OnDeviceRegistryListener {
    private val clingDeviceAdapter by lazy { ClingDeviceAdapter() }
    private val deviceList = mutableListOf<Device<
    , *, *>>()

    companion object {
    private const val TAG = "ClingListDialog"
    fun startTpActivity(context: Context, title: String, url: String, img: String, id: String) {
    val intent = Intent(context, TpActivity::class.java)
    intent.putExtra("title", title)
    intent.putExtra("url", url)
    intent.putExtra("img", img)
    intent.putExtra("id", id)
    context.startActivity(intent)
    }
    }

    private var title: String = ""
    private var url: String = ""
    private var img: String = ""
    private var id: String = ""

    override fun initView(savedInstanceState: Bundle?) {
    title = intent?.getStringExtra("title") ?: title
    url = intent?.getStringExtra("url") ?: url
    img = intent?.getStringExtra("img") ?: img
    id = intent?.getStringExtra("id") ?: id
    DLNACastManager.getInstance().registerDeviceListener(this)
    mBinding.apply {
    wifi = "当前wifi:<${Utils.getWiFiInfoSSID(this@TpActivity)}>"
    ivClose.setOnClickListener { finish() }
    clingRecycler.addLinearManager()
    clingDeviceAdapter.setList(deviceList)
    clingDeviceAdapter.setOnItemClickListener { _, _, position ->
    clingDeviceAdapter.setSelectedDevice(clingDeviceAdapter.getItem(position))

// startActivity(Intent(requireContext(), TpActivity::class.java))
}
clingRecycler.adapter = clingDeviceAdapter
}

}

override fun initData() {

}

override fun onStart() {
    super.onStart()
    DLNACastManager.getInstance().bindCastService(this)
}

override fun onStop() {
    DLNACastManager.getInstance().unbindCastService(this)
    super.onStop()
}

override fun onDestroy() {
    DLNACastManager.getInstance().unregisterListener(this)
    super.onDestroy()
}

override fun onDeviceAdded(device: Device<*, *, *>?) {
    device?.also {
        if (!deviceList.contains(it)) {
            deviceList.add(it)
        }
    }
}

override fun onDeviceUpdated(device: Device<*, *, *>?) {
}

override fun onDeviceRemoved(device: Device<*, *, *>?) {
    if (deviceList.contains(device)) {
        deviceList.remove(device)
    }
}

}

手机端投射到TV端,播放m3u8格式电视剧,现象:加载一会儿之后,直接跳到下一集了(第一集跳到第二集,第二集加载一会儿之后跳到第三集)

1,我们项目分手机端和TV端,手机端已经做好了,TV端基于作者项目renderer开发的;
2,手机端投射到TV端,播放m3u8格式电视剧,现象:加载一会儿之后,直接跳到下一集了(第一集跳到第二集,第二集加载一会儿之后跳到第三集);
3,把视频地址单独拿出来,放在demo里面的app端,通过app端投射是可以正常播放的;
4,麻烦作者帮忙看下大概是什么原因?

dmr接收到currentURIMetaData为空时报错

currentURIMetaData包含了投屏过来的标题等信息,有的第三方投屏投屏过来只有currentURI,而currentURIMetaData为空时就会报错,
Error: Current state of service prevents invokingthat action. Parameter specified as non-null is null:method com.android.cast.dlna.dmr. service.AVTransportServicelmpl.setAVTransportURl, parametercurrentURlMetaData. (HT TP response was: 500

Internal Server Error)
大佬能修改为可空吗!

爱投屏的投屏不了

您好,我们这边发现在创维电视的爱投屏,都无法投屏成功,看您的Demo截图有创维电视,想问一下您是可以投屏成功的吗?是否有需要传递什么特定的参数。然后我们也发现电信盒子也无法投屏成功。但也都没有回调失败信息。

怎么投本地视频呢

大佬这个项目很棒啊,有博客或文档么,好好学习下,我自己做的app想加本地投屏功能

api问题

我导入了api 'devin1014.android:dlna-dmc:1.0.0'没法在声明中添加
在AndroidManifest.xml中需要添加如下

偶尔报错

java.lang.ExceptionInInitializerError
at org.fourthline.cling.transport.impl.AsyncServletStreamServerImpl.createServlet(AsyncServletStreamServerImpl.java:98)
at org.fourthline.cling.transport.impl.AsyncServletStreamServerImpl.init(AsyncServletStreamServerImpl.java:76)
at org.fourthline.cling.transport.RouterImpl.startAddressBasedTransports(RouterImpl.java:434)
at org.fourthline.cling.transport.RouterImpl.enable(RouterImpl.java:132)
at org.fourthline.cling.android.AndroidRouter.enable(AndroidRouter.java:91)
at org.fourthline.cling.UpnpServiceImpl.(UpnpServiceImpl.java:87)
at org.fourthline.cling.android.AndroidUpnpServiceImpl$1.(AndroidUpnpServiceImpl.java:54)
at org.fourthline.cling.android.AndroidUpnpServiceImpl.onCreate(AndroidUpnpServiceImpl.java:54)
at com.android.cast.dlna.dmc.DLNACastService.onCreate(DLNACastService.java:22)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3967)
at android.app.ActivityThread.-wrap5(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2092)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7529)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)

Resource not found

Hi,
When I try to open a mp4 file from my mobiles internal storage an error appears.

Error: Resource not found (HTTP response was: 500 internal server Error)

Please help me to figure out this problem and solve it.
Thanks.

运行本仓库代码的环境

非常感谢您贡献的开源代码!
我在运行过程中发现了一个问题,我的本地编译环境是

Android Studio AI-212.5712.43.2112.8609683
jdk 8
gradle plugin version 4.2.0
gradle 6.7.1

在投射本地视频的时候,jetty提供的网址访问出现503错误,查资料可能是版本不匹配的问题

  1. 我把jetty升级到9会出现依赖问题,cling-core依赖jetty8,但是使用jetty8又会出现503的问题
  2. 将服务器切换成nano,可以播放视频,但是播放速度又特别慢
    想请问下您的编译环境是啥样的

搜索设备的type如何传参

您好,看到您的Demo里搜索设备的时候第一个参数传的是null,这个参数应该怎么传,有什么区别?
DLNACastManager.getInstance().search(null, maxSeconds);

版本

老哥,远程依赖版本是多少?

爱奇艺等主流播放器DMC不适配

使用bilibili,爱奇艺,腾讯视频等主流播放器,能够投屏到TV接收断,但是很快显示“播放结束”,无法控制音量,进度等。

请教一下DMR相关功能该怎么使用

请教一下该怎么使用DMR的功能呢,比如怎么实现播放器相关的接口?怎么把当前设备作为播放器端暴露到网络中,让别的设备可以搜索到,然后播放其他软件投送的视频?

2个手机之间投屏失败

Renderer 端目前只能正常播放和控制 M3u8: Iphone Sample 这一个
其它的MP4, M3u8:BT, M3u8:CC 和 图片, Rendere 都不能正常播放和现实。
请问如何需要如何解决呢,期待您的回复

无法投屏本地视频

本地文件选择后的播放路径是:http://192.168.1.101:8192/storage/emulated/0/yyy/ppppp.mp4
1.投屏播放网络文件是可以的
2.发现有报错
W/System.err: java.lang.RuntimeException: Null or empty XML
W/System.err: at org.fourthline.cling.support.lastchange.LastChangeParser.parse(LastChangeParser.java:108)
W/System.err: at com.android.cast.dlna.dmc.control.CastSubscriptionCallback.eventReceived(CastSubscriptionCallback.java:72)
W/System.err: at org.fourthline.cling.controlpoint.SubscriptionCallback$2.eventReceived(SubscriptionCallback.java:223)
W/System.err: at org.fourthline.cling.model.gena.RemoteGENASubscription.receive(RemoteGENASubscription.java:114)
W/System.err: at org.fourthline.cling.protocol.sync.ReceivingEvent$2.run(ReceivingEvent.java:131)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:929)
W/System.err: java.lang.RuntimeException: Null or empty XML
W/System.err: at org.fourthline.cling.support.lastchange.LastChangeParser.parse(LastChangeParser.java:108)
W/System.err: at com.android.cast.dlna.dmc.control.CastSubscriptionCallback.eventReceived(CastSubscriptionCallback.java:72)
W/System.err: at org.fourthline.cling.controlpoint.SubscriptionCallback$2.eventReceived(SubscriptionCallback.java:223)
W/System.err: at org.fourthline.cling.model.gena.RemoteGENASubscription.receive(RemoteGENASubscription.java:114)
W/System.err: at org.fourthline.cling.protocol.sync.ReceivingEvent$2.run(ReceivingEvent.java:131)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:929)
您能帮忙看下是哪里的问题吗?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.