更新记录

1.0.7(2025-11-19)

  1. 修复Android播放进度校准问题

1.0.6(2025-11-19)

  1. 优化

1.0.5(2025-11-18)

  1. ios 全屏增加返回按钮
查看更多

平台兼容性

uni-app(3.6.14)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - 5.0 -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - -

uni-app x(3.6.14)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - 5.0 - -

其他

多语言 暗黑模式 宽屏模式

万能原生视频播放器,支持m3u8、mp4、rtmp、rtsp等等格式,本地远程视频

功能

  • 支持m3u8、mp4、rtmp、rtsp等多种视频格式
  • 支持本地和远程视频
  • 支持画中画小窗口播放
  • 支持播放、暂停、全屏、速率、音量等设置
  • 支持视频截图

集成步骤

  1. 拷贝demo里的AndroidManifest.xml、Info.plist、nativeResources文件到项目根目录
  2. 集成插件,集成插件步骤请参考 https://www.cnblogs.com/wenrisheng/p/18323027
  3. 如需定制或增加功能请点击插件标题下方的"进入交流群"私聊作者

文档


    import {
    UTSVideoPlayer
} from '@/uni_modules/wrs-uts-videoplayer'

组件


<!--  #ifdef  APP-HARMONY -->
<embed :style="'width:'+width+'px;height:'+height+'px;'" tag="videoplayer" :options="options"
    @onevent="onEvent"></embed>
<!--  #endif -->
<!--  #ifndef  APP-HARMONY -->
<wrs-uts-videoplayer ref='videoplayer' :params="params" :style="'width:'+width+'px;height:'+height+'px;'"
    @onEvent="onEvent"></wrs-uts-videoplayer>
<!--  #endif -->
  • 使用了该组件的页面需要用nvue或uvue
  • 属性params是json格式的字符串

data() {
    const {
        windowWidth,
        windowHeight,
        statusBarHeight
    } = uni.getSystemInfoSync();
    var height = windowWidth / (16 / 9);
    height = windowHeight / 2
    let localPath = UTSVideoPlayer.getResourcePath("/static/test.mp4")
    let urlArray = [
        localPath,
        "https://vjs.zencdn.net/v/oceans.mp4",
        "https://v2.tlkqc.com/202505/23/J2dwuThNJ074/video/index.m3u8",
        "https://vod6.bdzybf11.com/20250121/zybsAJ3L/index.m3u8",
        "https://v12.tlkqc.com/202505/23/jNCnQUVkk084/video/index.m3u8",
        "rtmp://ns8.indexforce.com/home/mystream",
        "rtsp://stream.strba.sk:1935/strba/VYHLAD_JAZERO.stream"
    ]
    let index = urlArray.length - 1
    index = 0
    let url = urlArray[index]
    // url = "http://112.18.204.171:1830/openUrl/vsigcCzHbC8fd6ca75700c14bf2b58e8/live.m3u8"
    // android:Exo2Player、SystemPlayer、IjkPlayer、AliPlayer
    // ios: SystemPlayer、IjkPlayer
    let playerCore = "SystemPlayer"
    // ios: default、aspectFit、aspectFill、fill
    // android: default、16_9、4_3、18_9、full、match_full
    let scaleMode = "default"
    let params = {}
    params.businessArray = [{
        business: "setUrl", // 设置播放地址
        params: { // 业务参数
            url: url,
            playerCore: playerCore,
            autoPlay: true,
            scaleMode: scaleMode
        }
    }]
    var isAndroid = false
    switch (uni.getSystemInfoSync().platform) {
        // android
        case 'android':
            isAndroid = true
            break;
            // ios
        default:
            isAndroid = false
            break;
    }
    let paramsStr = JSON.stringify(params)
    return {
        isAndroid: isAndroid,
        width: windowWidth,
        height: height,
        urlArray: urlArray,
        params: paramsStr,
        imageSrc: null,
        index: 0,
        msg: null,
        options: {
            params: paramsStr
        },
        title: 'Hello'
    }
},

params.businessArray数组里支持的业务对象有:

  • 设置播放地址,其他业务接口需要放到setUrl业务后面

// android:Exo2Player、SystemPlayer、IjkPlayer、AliPlayer
// ios: SystemPlayer、IjkPlayer
let playerCore = "SystemPlayer"

// ios: default、aspectFit、aspectFill、fill
// android: default、16_9、4_3、18_9、full、match_full
let scaleMode = "default"

let url = "https://xxxxxx/xx.m3u8"
// 本地视频地址如:/xxx/xxx/xxx.mp4

{
    business: "setUrl", // 设置播放地址
    params: { // 业务参数
        url: url, // 视频地址,支持本地绝对路径或远程地址
        playerCore: playerCore, // 播放器内核
        autoPlay: true, // 是否自动播放
        scaleMode: scaleMode // 画面缩放模式
    }
}
  • 自定义播放器按钮,按钮事件在onEvent
{
    business: "setMenu", // 自定义播放器的按钮,需要放到setUrl后面
    params: {
        top: { // 播放器右上角按钮
            menus: [{
                    image: UTSVideoPlayer.getResourcePath("/static/pictureinpicture.png")
                },
                {
                    image: UTSVideoPlayer.getResourcePath("/static/download.png")
                }
            ],
            width: 25,
            margin: 15
        },
        right: {// 播放器右边按钮
            menus: [{
                    image: UTSVideoPlayer.getResourcePath("/static/screencasting.png")
                },
                {
                    image: UTSVideoPlayer.getResourcePath("/static/download.png")
                }
            ]
        }
    }
}
  • 快进到第几秒
{
    business: "seekToTime", //
    params: {
        time: 10000 // 单位毫秒
    }
}
  • 设置音量
{
    business: "setVolume", //
    params: {
        volume: 0.5 // [0~1]
    }
}
  • 设置播放速度

{
    business: "setPlaybackRate", 
    params: {
        rate: 2 // 倍速,支持整数和小数
    }
}
  • 截屏,结果在onEvent回调

// 本地图片保存路径
let path = "/xxx/xx/xx.jpg"
{
    business: "getImage", // 业务
    params: {
        path: path
    }
}
  • 暂停
{
    business: "pause"
}
  • 播放
{
    business: "play"
}
  • onEvent回调事件

onEvent(e) {
    // this.showMsg("onEvent :" + JSON.stringify(e))
    let params = {}
    let detail = e.detail
    let opt = detail.opt
    switch (opt) {
        case "onTopMenuClick": {
                let index = detail.index
                console.log(JSON.stringify(detail))
                this.showToast("顶部按钮:" + index)
            }
            break;
        case "onRightMenuClick": {
                let index = detail.index
                console.log(JSON.stringify(detail))
                this.showToast("右边按钮:" + index)
            }
        break;
        case "getImage": {
            console.log("onEvent:" + JSON.stringify(detail))
            let suc = detail.flag
            if (suc) {
                let path = detail.params.path
                this.imageSrc = "file://" + path
            } else {
                this.showMsg("截图失败:" + JSON.stringify(detail))
            }
        }
        break;
        case "onReadyToPlay": {
            //开始播放
            // 毫秒
            let totalTime = detail.totalTime
            this.showMsg("开始播放 totalTime:" + totalTime)
        }
        break;
        case "": {
            // 播放进度,毫秒
            let currentTime = detail.currentTime
            let totalTime = detail.totalTime
        }
        break;
        case "onError": {
            this.showMsg("播放失败:" + JSON.stringify(detail))
        }
        break;

        case "onComplete": {
            this.showMsg("播放完成:" + JSON.stringify(detail))
        }
        break;
        default:
            break;
    }
}
  • 系统画中画小窗口播放
  1. iOS需要playerCore是SystemPlayer才支持系统系统画中画小窗口

// 先判断系统是否开启了悬浮窗权限
let hasPermission = UTSVideoPlayer.canDrawOverlays()
if (hasPermission) {
    let newParams = {}
    newParams.businessArray = [{
        business: "startPicInPic", // 
    }]

    let newParamsStr = this.formatNewParams(newParams)
    // android、ios
    this.params = newParamsStr
    // 鸿蒙
    this.options = {
        params: newParamsStr
    }
} else {
    switch (uni.getSystemInfoSync().platform) {
        // android
        case 'android':
            this.showModel("打开悬浮窗口权限?", () => {
                UTSVideoPlayer.goToOpenOverlaysSetting()
            })
            break;
        case "ios": {
            this.showMsg("机型不支持")
        }
        break;
        default:
            break;
    }
}
  • 系统画中画回到页面
    1. 如果页面还在则小窗口视频返回到页面,如果页面不在了则小窗口消失

let newParams = {}
newParams.businessArray = [{
    business: "inAppPicInPicBackToPageView", // 业务
}]

let newParamsStr = this.formatNewParams(newParams)
// android、ios
this.params = newParamsStr
// 鸿蒙
this.options = {
    params: newParamsStr
}
  • 应用内小窗口播放(仅支持iOS)
  1. 仅支持iOS
  2. 这种类型到小窗口仅在app在前台运行时显示,悬浮在所有页面上面,app在后台运行时则在不显示

let newParams = {}
newParams.businessArray = [{
    business: "startInAppPicInPic", // 业务
}]

let newParamsStr = this.formatNewParams(newParams)
// android、ios
this.params = newParamsStr
// 鸿蒙
this.options = {
    params: newParamsStr
}
  • 应用内小窗口回到页面(仅支持iOS)

let newParams = {}
newParams.businessArray = [{
    business: "inAppPicInPicBackToPageView", // 业务
}]

let newParamsStr = this.formatNewParams(newParams)
// android、ios
this.params = newParamsStr
// 鸿蒙
this.options = {
    params: newParamsStr
}

隐私、权限声明

1. 本插件需要申请的系统权限列表:

读写、网络、悬浮窗

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率: