Taro中小程序LivePlayer使用经验
自疫情爆发以来,直播行业似乎越来越平凡的出现在各大APP、网页、小程序上,对于我们一个小开发仔来说,接触新兴行业也算是自我提升的一个很好的途径,恰巧公司最近在搞一个小程序关于直播课程的,于是乎顺利的成了我首战项目,接下来分享一下在项目中所遇到的问题,给各位小伙伴踩踩坑~
注意:直播组件优先开通实时音频和视频(小程序管理后台),并且申请对应的直播资质证书
基础直播
由于公司对接第三方推流使用rtmp格式,所以我们最开始使用最基本的直播组件LivePlayer
<LivePlayer
id="liveVideo"
ref={player}
className={style.player}
src={url}
mode="RTC"
autoplay
onFullScreenChange={fullScreenChange}
onStateChange={liveStaChange}
>
复制代码
常规使用,没有任何处理,也没有任何业务牵扯,基本可以满足大部分需求,但是,在一定情况下会出现一个bug!!!!
常见问题
(一)、如果用户是重新下载微信,此时的用户没有拨打过语音、视频,也没有授权系统的访问摄像头和麦克风,此时我们拉流rtmp会出现insertLivePlayer:fail:access denied
(二)、产品定制需求,需要自定义封面,封面上有倒计时,并且横屏时候也需要~ 此时ios、android会有不同表现
如何解决
解决问题一,既然用户拒绝给微信授权麦克风和摄像头,那么首先想到看能不能在直播点击开始之前,做一个兼容处理,如果用户已经授权,正常播放,否则跳转系统授权页面(提示用户),巧了,在新版本中微信出了一个
getAppAuthorizeSetting
获取系统授权信息的api,并且还支持跳转,如下:
/**
* 获取系统权限状态
* 0 用户已开通对应权限
* -1 获取系统权限失败
* 1001 当前微信版本过低,部分功能无法使用~
* 100 打开系统授权页成功
* 101 打开系统授权页失败
* 403 用户点击取消
* 401 权限没打开
* */
export const getSystemInfo = (keys: Tkey[], content = '') => {
return new Promise((resolve) => {
// 判断微信是否支持api
const canUseSta = Taro.canIUse('getAppAuthorizeSetting');
if (!canUseSta) {
return resolve({ code: 1001, msg: '当前微信版本过低,部分功能无法使用~' });
}
// 会返回授权具体信息 https://developers.weixin.qq.com/miniprogram/dev/api/base/system/wx.getAppAuthorizeSetting.html
// 获取系统授权信息 返回 [key]:undefined | denied | authorized(权限已打开)
const systemInfo = wx.getAppAuthorizeSetting();
if (!systemInfo) {
return resolve({ code: -1, msg: '获取系统权限失败~' });
}
keys.forEach((item) => {
if (systemInfo[item] !== 'authorized') {
Taro.showModal({
content,
success: (res) => {
if (res.confirm) {
// 跳转系统授权页
wx.openAppAuthorizeSetting({
success: () => {
return resolve({ code: 100, msg: '打开系统授权页成功~' });
},
fail: () => {
return resolve({ code: 101, msg: '打开系统授权页失败~' });
}
});
} else {
return resolve({ code: 403, msg: '用户点击取消~' });
}
}
});
return resolve({ code: 401, msg: '权限没打开~' });
}
});
return resolve({ code: 0, msg: '用户已开通对应权限~' });
});
};
// 调用promise
// 获取系统权限
const res: any = await getSystemInfo(
['cameraAuthorized', 'microphoneAuthorized'],
'检测到您没有打开麦克风和相机权限,部分功能将没法使用~'
);
复制代码
问题(二)如何解决ios和android定制化的封面和封面加入的倒计时呢? 既然是定制化,首先想到微信小程序现在加入的同层渲染,具有覆盖小程序原生组件的能力或者使用CoverView、CoverImage
同屏渲染问题
在竖屏情况下,原生覆盖能力ios和android表现形式还是不错的,但是,如果在直播全屏横屏的情况下,此时android会出现覆盖不了的情况,因此建议还是用覆盖组件
<LivePlayer
id="liveVideo"
ref={player}
className={style.player}
src={url}
mode="RTC"
autoplay
onFullScreenChange={fullScreenChange}
onStateChange={liveStaChange}
>
<CoverView className={style['cover-main']}>
<CoverView className={style['cover-main']}>
<CoverView className={style['live-control']} onClick={showTips}></CoverView>
{/*水印*/}
{url && teachStatus && startStatus && (
<CoverView className={style['watermark']} style={waterP}>
{waterMaskTxt}
</CoverView>
)}
{fullScreenFlag && (
<>
{/*广告*/}
<Curtain />
{/* 封面*/}
<CoverView className={style.cannot_see}>
{livePostUrl && (
<CoverImage
className={style.cannot_see_img}
src={livePostUrl}
></CoverImage>
)}
{liveLoading && startStatus && teachStatus && (
<CoverView className={style.loading}>
<CoverImage
src={LoadingIcon}
className={style['loading-icon']}
></CoverImage>
<CoverView className={style['loading-txt']}>加载中...</CoverView>
</CoverView>
)}
</CoverView>
{/* 倒计时*/}
{time >= 1800 ? <CountDown time={time} /> : null}
</>
)}
{/*控制*/}
<CoverView
className={`${style.control} ${tips ? style['up-ani'] : style['down-ani']}`}
>
<CoverView className={style.info}>
<CoverView>直播</CoverView>
</CoverView>
<CoverView className={style['full-screen']} onClick={handleFullScreen}>
<CoverImage
className={style.icon}
src={fullScreenFlag ? tuichuquanping : quanping}
></CoverImage>
<CoverView>{fullScreenFlag ? '小屏播放' : '全屏播放'}</CoverView>
</CoverView>
</CoverView>
{/*顶部标题和返回*/}
{fullScreenFlag && (
<CoverView
className={`${style.head} ${tips ? style['up-ani'] : style['down-ani']}`}
>
<CoverImage
src={BackIcon}
className={style['back-icon']}
onClick={handleFullScreen}
></CoverImage>
<CoverView className={style['title']}>
{courseName || '书画院直播间'}
</CoverView>
</CoverView>
)}
</CoverView>
</CoverView>
</LivePlayer>
复制代码
tips:
在覆盖组件的情况下,如果是全屏
还需要注意,在LivePlayer下的顶层容器和直接子节点需要设置 visiblity:visible;position:relative;z-index:99999; 必须得处理,不然android 的CoverView依然覆盖不了原生直播组件。
.cover-main{
position: absolute;
visibility: visible;
z-index: 999999;
}
原文链接:https://juejin.cn/post/7054860337018830885