微信小程序直播组件的运用(live-player),截屏保存,滑动详解

1,966 阅读4分钟

前置操作

1.小程序的直播功能必须把微信公众平台中的服务类目给加一个直播权限才能使用。
2.在申请账号的时候必须是企业账号,个人小程序没有开通这个权限。
3.添加类目的时候一定要按照文档中的加.不然就开通不了权限

具体步骤:微信公众平台->登录->设置->基本设置->服务类目(右侧详情)->添加类目->审核通过以后->开发管理->接口设置->实时播放音视频流打开 image.png

image.png

image.png

!!!注意,live-player在微信开发者工具上是用不了的,只有在真机调试上才能看出效果

image.png

live-player官方文档: developers.weixin.qq.com/miniprogram…

接下来就可以在项目中编写代码(最基础的版本)

<live-player class="myLivePlayer" src="{{livePlayerUrl}}" mode="live" object-fit="contain" autoplay muted="true">
</live-player>
live-player仅支持 flv, rtmp 格式
autoplay: 自动播放
object-fit :contain 图像长边填满屏幕,短边区域会被填充⿊⾊。
mode:live 直播 。RTC 实时通话,该模式时延更低  这里要明确说明直播一定要用live否则视频会超级卡很不流畅
muted: 是否静音

这个时候只要你的livePlayerUrl正确,视频已经自动播放了

加上截屏功能

 onReady() {
        this.ctx = wx.createLivePlayerContext('player')
 },
 
 //截屏方法1(先检查是否有权限)
 screenShoot(e) {
        console.log("开始截屏")
        wx.showToast({
            icon: "loading",
            title: "正在截屏"
        });
        // livePlayerContext.snapshot('raw');
        let that = this
        //获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的[权限]
        wx.getSetting({
            success(res) {
                if (res.authSetting['scope.writePhotosAlbum']) {
                    that.saveImg();
                } else if (res.authSetting['scope.writePhotosAlbum'] === undefined) {
                    wx.authorize({
                        scope: 'scope.writePhotosAlbum',
                        success() {
                            //保存图片
                            that.saveImg();
                        },
                        fail() {
                             //未开启授权
                            that.authConfirm()
                        }
                    })
                } else {
                    //未开启授权
                    that.authConfirm()
                }
            }
        })

  },
   //保存图片
    saveImg() {
        //调用live-player的api进行截屏
        //compressed:截屏的图片为压缩模式 (不传默认为原图模式)
        this.ctx.snapshot('compressed')
            .then(data => {
                if (data) {
                     wx.saveImageToPhotosAlbum({
                         filePath: data.tempImagePath,
                         success(res) {
                             console.log("保存成功", res)
                             wx.showToast({
                                 title: '截图已保存至手机相册',
                                 icon: 'none',
                             })
                         }
                     })
                }
            })
            .catch(err => {
                console.log("err", err);
            })
    },
  // 授权拒绝后,再次授权提示弹窗
  authConfirm() {
        let that = this
        wx.showModal({
            content: '您没打开保存图片权限,是否去设置打开?',
            confirmText: "确认",
            cancelText: "取消",
            success: function (res) {
                if (res.confirm) {
                    wx.openSetting({
                        success: (res) => {
                            if (res.authSetting['scope.writePhotosAlbum']) {
                                //保存图片
                                that.saveImg();
                            } else {
                                wx.showToast({
                                    title: '您没有授权,无法保存到相册',
                                    icon: 'none'
                                })
                            }
                        }
                    })
                } else {
                    wx.showToast({
                        title: '您没有授权,无法保存到相册',
                        icon: 'none'
                    })
                }
            }
        });
  },

全屏与关闭全屏api

我是挂载在直播组件的点击事件中,在live-player中加上catchtap="onVideoTap"

注意:
全屏切换时屏幕会有一点卡顿,经排查发现是因页面有除live-player外的dom节点,得出的解决办法就是当执行全屏操作
或者关闭全屏操作时,先隐藏页面的其他dom节点.操作结束后再恢复即可
    //点击视频区, 变成全屏或收起全屏
    onVideoTap(e) {
        console.log("点击视频");
        const {
            fullScreen,
        } = this.data;
        this.setData({
            fullScreen: true,
        })
        if (!fullScreen) {
            this.bindFullScreen()
        } else {
            this.unfullScreen()
        }
    },
    //关闭全屏
    unfullScreen() {
        this.ctx.exitFullScreen({
            success: () => {
                this.setData({
                    fullScreen: false,
                })
            }
        });
        console.log("关闭全屏");
    },
    //开启全屏
    bindFullScreen() {
        this.ctx.requestFullScreen({
            direction: 90,
            success: () => {
                this.setData({
                    fullScreen: true,
                })
            }
        });
        console.log("开启全屏");
    },

播放与停止播放api

    onHide() {
        //在页面隐藏时一定要记得停止视频.不然会出现离开页面了视频还继续播放的bug
        this.bindStop()
    },
    //停止视频
    bindStop() {
        this.ctx.stop({
            success: res => {
                this.setData({
                    livePlayerUrl: null
                })
                console.log('stop success')
            },
            fail: res => {
                console.log('stop fail')
            }
        })
    },
    //播放视频
    bindPlay() {
        this.ctx.play({
            success: res => {
                console.log('play success')
            },
            fail: res => {
                console.log('play fail')
            }
        })
    },

live-player滑动切换直播源

 <live-player capture-bind:touchstart='onTouchStart' capture-catch:touchend='onTouchEnd' src="{{livePlayerUrl}}" mode="live" object-fit="contain" >
  </live-player>
  
livePlayerUrl:当前视频播放源
liveUrlList:视频播放源数组
livePlayerIndex:当前视频播放源在数组中的下标
 
 
 

//直播组件滑动开始
onTouchStart: function (e) {
    this.setData({
        movingX: e.changedTouches[0].clientX,
        movingY: e.changedTouches[0].clientY
    })
    console.log('start', e.changedTouches[0]);
},
//直播组件滑动结束
onTouchEnd: function (e) {
    console.log('End', e.changedTouches[0]);
    let {
        clientX,
        clientY
    } = e.changedTouches[0];
    let {
        movingX,
        movingY,
        liveUrlList,
        livePlayerIndex
    } = this.data;
    let key = ''
    //如果当前X坐标点比滑动开始时的X坐标点大. 并且不止大50(自行设置滑动距离) .
    //并且当前直播源不是第一个直播源则为左滑
    if (clientX > movingX && clientX - movingX > 50 && livePlayerIndex !== 0 ) {
        key = 'left';
    } else if (movingX > clientX && movingX - clientX > 50 && liveUrlList.length && livePlayerIndex !== liveUrlList.length-1) {
    //如果滑动开始时的X坐标点比当前X坐标点大. 并且不止大50(自行设置滑动距离) .
    //并且当前直播源不是最后一个直播源则为右滑
        key = 'right'
    }else{
        return 
    }

    console.log(' obj.currentTarget.dataset.key ', obj.currentTarget.dataset.key );
    this.switchLive(key)
},

//切换直播源事件
switchLive(key) {
    let {
        livePlayerUrl,
        liveUrlList,
        livePlayerIndex
    } = this.data;
    this.setData({
        livePlayerUrl: null,
    })
    wx.showToast({
        icon: "loading",
        title: "切换视频",
        duration: 2000,
        mask: true
    });
    if (key === 'left') {
        console.log('left');
        this.setData({
            livePlayerUrl: liveUrlList[livePlayerIndex - 1],
            livePlayerIndex: livePlayerIndex - 1
        })
    } else {
        console.log('right');
        this.setData({
            livePlayerUrl: liveUrlList[livePlayerIndex + 1],
            livePlayerIndex: livePlayerIndex + 1
        })
    }
},