更新记录

1.0.0(2024-10-28)

uts版本投屏插件


平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 4.18,Android:8.0,iOS:不支持,HarmonyNext:不确定 × × × × × ×
钉钉小程序 快手小程序 飞书小程序 京东小程序
× × × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
× × × × × × × × ×

lyzml-dlna-uts

开发文档

<template>
    <view>
        <view class="df dfr aic jcc" v-for="(tv,idx) in tvList" :key="idx" @tap="onTvSelected(tv,idx)">
            <view class="tv-name-wrapper bsr1">
                <text class="tv-name" :class="{'selected':selectedTVUdn==tv.udn}">{{tv.name}}|{{tv.udn}}</text>
            </view>
        </view>

        <view class="lyzml-btn df dfr aic jcc" @tap="startSearch">开始搜索</view>
        <view class="lyzml-btn df dfr aic jcc" @tap="setPlayMonitor">设置监听</view>
        <view class="lyzml-btn df dfr aic jcc" @tap="getTransportState">获取播放状态</view>
        <view class="lyzml-btn df dfr aic jcc" @tap="getMediaDuration">获取总时长</view>
        <view class="lyzml-btn df dfr aic jcc" @tap="getPlayPosition">获取播放进度</view>
        <view class="lyzml-btn df dfr aic jcc" @tap="getCurrVolumeValue">获取当前音量</view>
        <view class="lyzml-btn df dfr aic jcc" @tap="getLocalIp">获取本机IP</view>
        <view class="df dfr">
            <view class="lyzml-btn df dfr aic jcc" style="width: 210rpx;" @tap="playOrPause">
                <text v-if="isPlaying">暂停</text>
                <text v-else>播放</text>
            </view>
            <view class="lyzml-btn df dfr aic jcc" style="width: 210rpx;" @tap="stopVideo">结束播放</view>
            <view class="lyzml-btn df dfr aic jcc" style="width: 210rpx;" @tap="playVideo">投屏</view>
        </view>
        <view class="df dfr">
            <view class="lyzml-btn df dfr aic jcc" style="width: 330rpx;" @tap="volumeDown">音量减</view>
            <view class="lyzml-btn df dfr aic jcc" style="width: 330rpx;" @tap="volumeUp">音量加</view>
        </view>

        <view class="df dfr">
            <view class="lyzml-btn df dfr aic jcc" style="width: 330rpx;" @tap="seekBack">快退10秒</view>
            <view class="lyzml-btn df dfr aic jcc" style="width: 330rpx;" @tap="seekForward">快进10秒</view>
        </view>

        <view class="lyzml-btn df dfr aic jcc" @tap="getSearchResult">获取设备列表</view>
    </view>
</template>

<script>
    import * as LyzmlDlnaUtsUts from "@/uni_modules/lyzml-dlna-uts";
    import { TVClass } from "@/uni_modules/lyzml-dlna-uts";

    export default {
        data() {
            return {
                currTimeSecond: 0 as Int,
                currTimeStr: "00:00",
                durationSecond: 0 as Int,
                durationStr: "00:00",
                selectedTVUdn: "",
                currVolume: 0 as Int,
                currVideoUrl: "https://sf1-cdn-tos.huoshanstatic.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-360p.mp4",
                isPlaying: false,
                isMute: false,
                currPlayState: "",
                tvList: [] as TVClass[]
            }
        },
        methods: {
            onTvSelected(tv : TVClass, idx : number) {
                console.log("====onTvSelected====", tv);
                this.selectedTVUdn = tv.udn;
                this.connectDevice(this.selectedTVUdn);
            },
            startSearch() {
                this.tvList = [];
                LyzmlDlnaUtsUts.startSearch((resp : UTSJSONObject) => {
                    console.log("====startSearch====", resp);
                    if (resp["code"] as number == 0) {
                        uni.showToast({
                            icon: "none",
                            title: "开始搜索"
                        });
                    } else if (resp["code"] as number == 1) {
                        this.tvList = resp["result"] as TVClass[];
                    } else if (resp["code"] as number == 2) {
                        uni.showToast({
                            icon: "none",
                            title: "搜索完成"
                        });
                    }
                });
            },
            connectDevice(udn : string) {
                console.log("===connectDevice====", udn);
                LyzmlDlnaUtsUts.connectDevice(udn, (resp : UTSJSONObject) => {
                    console.log("====connectDevice====", resp);
                });
            },
            setPlayMonitor() {
                console.log("====setPlayMonitor====");
                LyzmlDlnaUtsUts.setPlayMonitor((resp) => {
                    console.log("====setPlayMonitor resp====", resp);
                    let code = resp.getNumber("code");
                    switch (code) {
                        case 1:
                            //onGetTransportState,获取传输状态回调,
                            //参考项目中共有STOPPED、PLAYING、TRANSITIONING、PAUSED_PLAYBACK、PAUSED_RECORDING、RECORDING、NO_MEDIA_PRESENT、ERR
                            //目前测试只发现以下3种状态,其他的不知道啥场景会触发,而且有很多设备不会返回这个状态
                            let status = resp.getString("result");
                            this.currPlayState = status!=null?status:"";
                            if ("PLAYING" == status) {
                                this.isPlaying = true;
                            } else if ("PAUSED_PLAYBACK" == status || "STOPPED" == status) {
                                this.isPlaying = false;
                            }
                            break;
                        case 2: //onGetMediaDuration,获取视频时长回调
                            let result = resp.getNumber("result");
                            if (result != null) {
                                this.durationSecond = result.toInt();
                            }
                            break;
                        case 3: //onPlay,开始播放回调
                            this.isPlaying = true;
                            break;
                        case 4: //onPause,暂停播放回调
                            this.isPlaying = false;
                            break;
                        case 5: //onStop,结束播放回调
                            this.isPlaying = false;
                            break;
                        case 6: //d,音量变化回调
                            let result = resp.getNumber("result");
                            if (result != null) {
                                this.currVolume = result.toInt();
                            }
                            break;
                        case 7: //Updated,播放进度回调 
                            let result = resp.getNumber("result");
                            if (result != null) {
                                this.currTimeSecond = result.toInt();
                            }
                            break;
                        case 8: //Complete,快进快退回调
                            this.getTransportState();
                            break;
                        case 9: //onError,调用发生错误时的回调,可以打印出来看看,调试的时候可以看看,有时候莫名奇妙会不停回调错误
                            break;
                        default:
                            break;
                    }
                });
            },
            getTransportState() {
                LyzmlDlnaUtsUts.getTransportState();
            },
            getMediaDuration() {
                LyzmlDlnaUtsUts.getMediaDuration();
            },
            getPlayPosition() {
                LyzmlDlnaUtsUts.getPositionInfo()
            },
            getCurrVolumeValue() {
                LyzmlDlnaUtsUts.getVolume();
            },
            getLocalIp() {
                LyzmlDlnaUtsUts.getIpAddress((retStr : String) => {
                    console.log("====getLocalIp===", retStr);
                });
            },
            playOrPause() {
                if (this.isPlaying) {
                    LyzmlDlnaUtsUts.pauseVideo();
                } else {
                    LyzmlDlnaUtsUts.resumeVideo(this.currTimeSecond);
                }
            },
            playVideo() {
                LyzmlDlnaUtsUts.playVideo({
                    udn: this.selectedTVUdn,
                    mediaURL: this.currVideoUrl
                }, (resp : UTSJSONObject) => {
                    if (0 == resp.getNumber("code")) {
                        uni.showToast({
                            icon: "none",
                            title: "投屏成功"
                        });
                    } else {
                        uni.showToast({
                            icon: "none",
                            title: "若投屏失败,请尝试重新扫描"
                        });
                    }
                });
            },
            stopVideo() {
                LyzmlDlnaUtsUts.stopVideo();
            },
            volumeDown() {
                let volume = this.currVolume - 1;
                console.log("===volumeDown====", volume);
                if (volume < 0) {
                    volume = 0;
                }
                LyzmlDlnaUtsUts.setVolume(volume);
            },
            volumeUp() {
                let volume = this.currVolume + 1;
                console.log("===volumeUp====", volume);
                if (volume > 100) {
                    volume = 100;
                }
                LyzmlDlnaUtsUts.setVolume(volume);
            },
            seekBack() {
                let p = this.currTimeSecond - 10;
                console.log("===seekBack====", p);
                if (p < 0) {
                    p = 0;
                }
                LyzmlDlnaUtsUts.seek(p);
            },
            seekForward() {
                let p = this.currTimeSecond + 10;
                console.log("===seekForward====", p);
                if (p > this.durationSecond) {
                    p = this.durationSecond;
                }
                LyzmlDlnaUtsUts.seek(p);
            },
            getSearchResult(){
                LyzmlDlnaUtsUts.getSearchResult((resp)=>{
                    console.log("====getSearchResult====",resp);
                });
            }
        }
    }
</script>

<style>
    .lyzml-btn {
        width: 690rpx;
        height: 60rpx;
        margin: 10rpx 0rpx 10rpx 30rpx;
        border: solid 1px;
        background-color: #CCCCCC;
        border-radius: 30rpx;
    }

    .tv-name-wrapper {
        width: 650rpx;
        height: 80rpx;
        overflow: hidden;
    }

    .tv-name {
        font-size: 32rpx;
        font-weight: 400;
        line-height: 80rpx;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        color: #000000;
    }

    .tv-name.selected {
        color: green;
    }
</style>

隐私、权限声明

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

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

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

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问