使用微信小程序播放视频直播

观众端使用live-player进行直播视频的播放,live-player组件从视频云拉流,并用于实时音视频播放。live-player支持两种模式:Live和RTC,前者用于直播播放,后者用于实时音视频通话。在使用live-player组件实现直播播放前先看看live-player组件的属性以及方法。

属性定义

  • Src
    用于音视频下行的播放URL,支持RTMP协议(URL 以rtmp://打头)和 FLV 协议(URL 以http://打头且以.flv结尾)。
    live-player标签不支持 HLS(m3u8)协议,因为 已经支持 HLS(m3u8)播放协议了。但直播观看不推荐使用 HLS(m3u8)协议,延迟要比RTMP和FLV协议高一个数量级。
  • mode
    live 模式主要用于直播类场景,例如赛事直播、在线教育、远程培训等等。该模式下,小程序内部的模块会优先保证观看体验的流畅,通过调整 min-cache 和 max-cache 属性,您可以调节观众(播放)端所感受到的时间延迟的大小。
    RTC 则主要用于双向视频通话或多人视频通话场景,例如金融开会、在线客服、车险定损、培训会议等等。在此模式下,对 min-cache 和 max-cache 的设置不会起作用,因为小程序内部会自动将延迟控制在一个很低的水平(500ms左右)。
  • min-cache 和 max-cache
    这两个参数分别用于指定观看端的最小缓冲时间和最大缓冲时间。所谓缓冲时间,是指播放器为了缓解网络波动对观看流畅度的影响而引入的一个“蓄水池”,当来自网络的数据包出现卡顿甚至停滞的时候,“蓄水池”里的紧急用水可以让播放器还能坚持一小段时间,只要在这个短暂的时间内网速恢复正常,播放器就可以源源不断地渲染出流畅而平滑的视频画面。“蓄水池”里的水越多,抗网络波动的能力就越强,但代价就是观众端的延迟就越大,所以要在不同的场景下,使用不同的配置来达到体验上的平衡:
    1) 码率比较低(1Mbps左右,画面以人物为主)的直播流,min-cache = 1,max-cache = 3 较合适。
    2) 码率比较高(2Mbps - 3Mbps的高清游戏画面为主)的直播流,min-cache = 3,max-cache = 5 较合适。
    3) RTC 模式下这两个参数是无效的。
  • orientation
    画面渲染角度,horizontal 代表是原始画面方向,vertical 代表向右旋转 90度。
  • object-fit
    画面填充模式,contain 代表把画面显示完成,但如果视频画面的宽高比和live-player标签的宽高比不一致,那么您将看到黑边。fillCrop 代表把屏幕全部撑满,但如果视频画面的宽高比和 标签的宽高比不一致,那么画面中多余的部分会被裁剪掉。
  • background-mute
    微信切到后台以后是否继续播放声音,用于避免锁屏对于当前小程序正在播放的视频内容的影响。
  • sound-mode
    设置播放模式,可设值为:ear与speaker,ear代表使用听筒播放,speaker代表使用扬声器,默认为扬声器。

对象操作

  • wx.createLivePlayerContext()
    通过wx.createLivePlayerContext()可以将live-player标签和javascript 对象关联起来,之后即可操作该对象。
  • play
    开始播放,如果live-player的autoplay属性设置为false(默认值),那么就可以使用play来手动启动播放。
  • stop
    停止播放。
  • pause
    暂停播放,停留在最后画面。
  • resume
    继续播放,与 pause 成对使用。
  • mute
    设置静音。
  • requestFullScreen
    进入全屏幕。
  • exitFullScreen
    退出全屏幕。

内部事件

通过 live-player 标签的 bindstatechange 属性可以绑定一个事件处理函数,该函数可以监听推流模块的内部事件和异常通知。

  • 关键事件
    2001 PLAY_EVT_CONNECT_SUCC 已经连接到云端服务器
    2002 PLAY_EVT_RTMP_STREAM_BEGIN 服务器开始传输音视频数据
    2003 PLAY_EVT_RCV_FIRST_I_FRAME 网络接收到首段音视频数据
    2004 PLAY_EVT_PLAY_BEGIN 视频播放开始,可以在收到此事件之前先用默认图片代表等待状态
    2006 PLAY_EVT_PLAY_END 视频播放结束
    2007 PLAY_EVT_PLAY_LOADING 进入缓冲中状态,此时播放器在等待或积攒来自服务器的数据
    -2301 PLAY_ERR_NET_DISCONNECT 网络连接断开,且重新连接亦不能恢复,播放器已停止播放
  • 警告事件
    内部警告并非不可恢复的错误,小程序内部的音视频 SDK 会启动相应的恢复措施,警告的目的主要用于提示开发者或者最终用户
    2101 PLAY_WARNING_VIDEO_DECODE_FAIL 当前视频帧解码失败
    2102 PLAY_WARNING_AUDIO_DECODE_FAIL 当前音频帧解码失败
    2103 PLAY_WARNING_RECONNECT 网络断连,已启动自动重连恢复(重连超过三次就直接抛送 PLAY_ERR_NET_DISCONNECT 了)
    2104 PLAY_WARNING_RECV_DATA_LAG 视频流不太稳定,可能是观看者当前网速不充裕
    2105 PLAY_WARNING_VIDEO_PLAY_LAG 当前视频播放出现卡顿
    2106 PLAY_WARNING_HW_ACCELERATION_FAIL 硬解启动失败,采用软解
    2107 PLAY_WARNING_VIDEO_DISCONTINUITY 当前视频帧不连续,视频源可能有丢帧,可能会导致画面花屏
    3001 PLAY_WARNING_DNS_FAIL DNS解析失败(仅播放 RTMP:// 地址时会抛送)
    3002 PLAY_WARNING_SEVER_CONN_FAIL 服务器连接失败(仅播放 RTMP:// 地址时会抛送)
    3003 PLAY_WARNING_SHAKE_FAIL 服务器握手失败(仅播放 RTMP:// 地址时会抛送)

示例代码

接下来我们实现观众端的直播播放页面,在直播播放页面中我们将live-player的url参数设置为Nginx的拉流地址,并将mode设置为“live”。以下是直播播放页面的相关代码:
live_play.wxml

<view>
  <view>
    <live-player id="player" src="rtmp://......" mode="live" autoplay bindstatechange="statechange" binderror="error" />
    <view>
      <button bindtap="bindPlay"type="primary">播放</button>
      <button bindtap="bindPause" type="primary">暂停</button>
      <button bindtap="bindStop" type="primary">停止</button>
      <button bindtap="bindResume" type="primary">恢复</button>
      <button bindtap="bindMute" type="primary">静音</button>
    </view>
  </view>
</view>

live_play.js

Page({
    
    
  onReady(res) {
    
    
    this.ctx = wx.createLivePlayerContext('player')
  },
  stateChange(e) {
    
    
    console.log('live-player code:', e.detail.code)
  },
  error(e) {
    
    
    console.error('live-player error:', e.detail.errMsg)
  },
  bindPlay() {
    
    
    this.ctx.play({
    
    
      success: res => {
    
    },
      fail: res => {
    
    }
    })
  },
  bindPause() {
    
    
    this.ctx.pause({
    
    
      success: res => {
    
    },
      fail: res => {
    
    }
     })
  },
  bindStop() {
    
    
    this.ctx.stop({
    
    
      success: res => {
    
    },
      fail: res => {
    
    }
     })
  },
  bindResume() {
    
    
    this.ctx.resume({
    
    
      success: res => {
    
    },
      fail: res => {
    
    }
     })
  },
  bindMute() {
    
    
    this.ctx.mute({
    
    
      success: res => {
    
    },
      fail: res => {
    
    }
     })
  }
})

猜你喜欢

转载自blog.csdn.net/gz_hm/article/details/127044904