【免费】Android / iOS / 鸿蒙 DLNA 投屏插件,一套 API 推到电视播放
插件 ID:
msh-dlna-cast
形态:UTS 插件 · 免费 · Vue3 App
适用:把手机里的视频 / 图片推到同一 Wi-Fi 下的电视、盒子播放
做短视频、教育、相册类 App 时,经常会被问一句:「能不能投到电视上看?」
以前要自己啃 DLNA / SSDP / SOAP,Android、iOS、鸿蒙还各写一套。现在用 msh-dlna-cast,三端同一套 JavaScript 接口,搜索设备 → 选中 → 播放 → 暂停 / 进度 / 音量,业务代码只写一份。
插件市场搜索:msh-dlna-cast(或点文末链接)
能做什么
| 能力 | 说明 |
|---|---|
| 搜设备 | 局域网 SSDP 搜索;iOS 同时搜 AirPlay |
| 推媒体 | http / https 地址,或手机本地文件(插件自建临时 HTTP,不用先上传) |
| 播控 | 播放、暂停、继续、从头播、停止 |
| 进度 | 查询时长 / 进度,seek,快进 / 快退 10 秒 |
| 音量 | 0–100 绝对音量、静音 |
| 状态 | onStateChange 实时回调状态、进度、音量 |
平台:Android 5.0+ · iOS 15+ · 鸿蒙 NEXT(API 12+)
协议:三端都支持 DLNA;iOS 额外支持 AirPlay
不支持:屏幕镜像、Miracast、Chromecast、小程序 / H5 / uni-app x
5 分钟接入
1. 导入插件
从插件市场导入,或把 uni_modules/msh-dlna-cast 放进工程。uni_modules 会自动识别,不必在 manifest.json 里勾选本地插件。
2. 做自定义调试基座(必做)
插件带原生配置(权限、引擎),标准基座无效。HBuilderX 会提示:
uts插件[msh-dlna-cast]依赖的原生配置或三方SDK在运行至标准基座时不能生效
路径:运行 → 运行到手机或模拟器 → 制作自定义调试基座 → 用该基座真机跑。
模拟器收不到组播,请用真机。
3. 写代码
import * as dlna from '@/uni_modules/msh-dlna-cast'
// 发现设备(同一 id 重复发现会覆盖并再次回调)
dlna.onDeviceFound((res) => {
if (res.code !== 0) return
console.log(res.data.name, res.data.protocol) // DLNA / AIRPLAY
})
// 状态变化
dlna.onStateChange((res) => {
if (res.code !== 0) return
const { state, position, duration, volume, mute } = res.data
console.log(state, position, duration, volume, mute)
})
// 开始搜索(timeout 默认 8000ms)
dlna.startSearch({ timeout: 8000 }, (res) => {
if (res.code === 0) console.log('搜索已启动')
if (res.code === 1001) console.log('超时未发现设备')
})
// 选中设备后播放
dlna.selectDevice({ id: deviceId }, (res) => {
if (res.code !== 0) return
dlna.play({
url: 'https://player.alicdn.com/video/aliyunmedia.mp4',
title: '示例视频',
mimeType: 'video/mp4'
}, (playRes) => {
console.log(playRes.code, playRes.data.url)
})
})
// 常用控制
dlna.pause(() => {})
dlna.resume(() => {})
dlna.seek({ position: 30000 }, () => {}) // 毫秒
dlna.setVolume({ volume: 30 }, () => {})
dlna.setMute({ mute: true }, () => {})
dlna.stop(() => {})
回调统一为 { code, message, data },成功时 code === 0。
Android 请开启明文 HTTP(电视控制地址多为 HTTP):
{
"app-plus": {
"android": {
"usesCleartextTraffic": true
}
}
}
本地视频怎么投
play 的 url 传本地绝对路径(以 / 开头,不要带 file://)。插件在手机上起临时 HTTP,回调里的 data.url 就是电视能访问的地址。
uni.chooseVideo({
sourceType: ['album'],
compressed: false,
success: (res) => {
let path = res.tempFilePath || ''
if (typeof plus !== 'undefined' && plus.io?.convertLocalFileSystemURL) {
path = plus.io.convertLocalFileSystemURL(path)
}
if (path.indexOf('file://') === 0) path = path.substring(7)
dlna.play({ url: path, title: '本地视频' }, (r) => {
if (r.code === 0) console.log('终端地址', r.data.url)
})
}
})
Demo 怎么跑通
仓库 / 插件包里附带 dlna-cast-demo,界面大致如下:
- 确认顶部本机 IP 已显示(说明连上 Wi-Fi)
- 点「搜索设备」,列表里选中电视
- 用「示例视频」或粘贴自己的地址,点「播放」
- 试暂停、进度条、快进快退、音量、静音
示例素材(国内可直连):
- 视频:
https://player.alicdn.com/video/aliyunmedia.mp4 - 图片:
https://www.w3school.com.cn/i/eg_tulip.jpg
发帖时可附 Demo 截图:顶部 IP、搜索按钮、播放控件、最近回调。
iOS 特别说明(DLNA vs AirPlay)
| DLNA | AirPlay | |
|---|---|---|
| 选中后 | 直接连上,可 play |
先点系统投屏按钮,选好接收端,再 play |
| 音量 | setVolume |
走系统音量;接收端不跟随时中间音量返回 1009 |
首次运行务必允许「本地网络」。iOS 16+ 搜不到设备,常见原因是缺组播能力:向 Apple 申请 Multicast Networking,描述文件具备后再写入 UTS.entitlements,并重新做自定义基座。
AirPlay 是推媒体,不是屏幕镜像。
使用前 checklist
- [ ] 手机与电视同一 Wi-Fi,路由器未开 AP 隔离
- [ ] 电视已开启 DLNA / 媒体渲染(或对应投屏开关)
- [ ] 已用自定义基座真机运行
- [ ] Android 已开
usesCleartextTraffic - [ ] iOS 已允许本地网络
常见问题速查
| 现象 | 怎么处理 |
|---|---|
1001 一台都没有 |
同一 Wi-Fi?AP 隔离关了?电视 DLNA 开了? |
| 提示标准基座不能生效 | 制作自定义调试基座 |
1008 |
iOS 本地网络 / 组播;Android 组播权限 |
1007 |
手机没连 Wi-Fi |
1010 |
换过网络,重新搜索并选设备 |
| 本地文件电视打不开 | 电视访问不到手机临时 HTTP,再查同一 Wi-Fi |
AirPlay 调音量 1009 |
用接收端自身音量 |
完整错误码、接口表见插件 readme / 使用手册。
本期边界(避免踩坑)
不做:屏幕镜像、字幕、播放列表、多机同时播、倍速。
系统 DLNA 的 Play 只保证 1 倍速,多数电视会忽略其他 Speed。
获取方式
- 插件市场搜索:msh-dlna-cast
- 插件链接:(上架后填入)
https://ext.dcloud.net.cn/plugin?id=29885 - 免费,无广告,不采集、不上传个人数据;网络行为只发生在局域网
有问题欢迎评论区留言,请尽量带上:平台版本、手机与电视型号、完整 { code, message, data } 回调。祝投屏顺利 📺
0 个评论
要回复文章请先登录或注册