veplayer-live-mp-wx
v1.0.2-rc.0
Published
## 协议支持
Readme
SDK 简介
协议支持
VeLivePlayerSDK 支持以下协议:
- FLV: 支持 H.264 和 H.265 编码,音频支持 AAC 编码。
- RTMP: 支持 H.264 和 H.265 编码,音频支持 AAC 编码。
功能支持
VeLivePlayerSDK 支持以下功能:
- 播放器尺寸设置
- 封面设置
- 自动播放
- 多实例播放
- 全屏
- 视频旋转
- 静音/取消静音
- 画中画(部分支持)
- H.264 和 H.265 编码播放
- 日志上报
- RTMP 拉流
- SEI 监听
接入方式
- 安装 SDK
npm i veplayer-live-mp-wx- 引入组件
// index.json
{
"usingComponents": {
"ve-live-player": "veplayer-live-mp-wx/ve-live-player/ve-live-player"
}
}- 使用组件
<!-- index.wxml -->
<ve-live-player autoplay src="{{src}}" />功能接入
基础使用
<!-- index.wxml -->
<ve-live-player
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536521.flv"
/>// index.js
Page({});播放控制
<!-- index.wxml -->
<view>播放控制</view>
<ve-live-player
id="player"
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536523.flv"
/>
<button bind:tap="play">播放</button>
<button bind:tap="stop">停止</button>
<button bind:tap="pause">暂停</button>
<button bind:tap="resume">继续播放</button>
<button bind:tap="retry">重新播放</button>
<button bind:tap="requestFullscreen">全屏</button>
<button bind:tap="mute">静音</button>
<button bind:tap="unmute">取消静音</button>// index.js
import { getVeLivePlayer } from 'veplayer-live-mp-wx';
Page({
onLoad() {
const veLivePlayer = getVeLivePlayer(this, '#player');
this.veLivePlayer = veLivePlayer;
},
play() {
this.veLivePlayer.play();
},
pause() {
this.veLivePlayer.pause();
},
stop() {
this.veLivePlayer.stop();
},
resume() {
this.veLivePlayer.resume();
},
retry() {
this.veLivePlayer.replay();
},
mute() {
this.veLivePlayer.mute();
},
unmute() {
this.veLivePlayer.unmute();
},
requestFullscreen() {
this.veLivePlayer.requestFullscreen({
direction: 90,
});
},
});事件监听
播放器提供两种事件监听方式,一是通过 bind 绑定事件,二是获取到播放器实例后通过 on 监听事件。同时您可以新增自定义事件进行事件触发。
<!-- index.wxml -->
<ve-live-player
class="player"
bindplay="onPlay"
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536521.flv"
/>// index.js
import { getVeLivePlayer } from 'veplayer-live-mp-wx';
Page({
onLoad() {
const veLivePlayer = getVeLivePlayer(this, '.player');
veLivePlayer.on('ok', () => {
console.log('ok');
});
veLivePlayer.emit('ok');
veLivePlayer.on('videoResize', detail => {
console.log('videoResize: ', detail);
});
},
onPlay() {
console.log('play');
},
});报错监听
直播播放器创建成功后,您可监听报错事件,针对不同的错误码区分处理。
<!-- index.wxml -->
<ve-live-player class="player" binderror="onError" autoplay src="" />// index.js
import { getVeLivePlayer } from 'veplayer-live-mp-wx';
Page({
onLoad() {
const veLivePlayer = getVeLivePlayer(this, '.player');
veLivePlayer.on('error', detail => {
console.log('error: ', detail);
});
},
onError() {
console.log('error');
},
});自适应容器
直播播放器创建成功后,可以根据视频宽度对容器进行缩放。
<!-- index.wxml -->
<text>fit width</text>
<ve-live-player
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536521.flv"
fit-video-size="fixWidth"
width="100vw"
/>
<text>fit height</text>
<ve-live-player
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536524.flv"
fit-video-size="fixHeight"
height="300px"
/>// index.js
Page({});忽略内置组件
您可以设置忽略内置组件,代码示例如下所示。
<!-- index.wxml -->
<ve-live-player
autoplay
ignores="{{ignores}}"
src="https://pull-demo.volcfcdnrd.com/live/st-4536521.flv"
/>// index.js
Page({
data: {
/**
* 忽略内置组件
* 有效值为 've-loading', 've-error', 've-poster'
*/
ignores: ['ve-loading'],
},
});日志上报
播放器默认会进行日志上报,您可以通过设置项关闭它,也可以对其进行配置。
- 关闭日志上报
<!-- index.wxml -->
<ve-live-player
autoplay
class="player"
logger="{{logger}}"
src="https://pull-demo.volcfcdnrd.com/live/st-4536521.flv"
/>// index.js
import { getVeLivePlayer } from 'veplayer-live-mp-wx';
Page({
data: {
logger: {
enable: false,
},
},
});- 配置日志上报
<!-- index.wxml -->
<ve-live-player
autoplay
class="player"
logger="{{logger}}"
src="https://pull-demo.volcfcdnrd.com/live/st-4536521.flv"
/>// index.js
import { getVeLivePlayer } from 'veplayer-live-mp-wx';
Page({
data: {
logger: {
enable: true,
appId: '742***2',
appName: 'app_name',
userId: 'u_123456',
deviceId: 'd_123456',
},
},
onLoad() {
const veLivePlayer = getVeLivePlayer(this, '.player');
},
});SEI 监听
在播放器创建完成后,您可以设置 SEI 补充增强信息监听,代码示例如下所示。
<!-- index.wxml -->
<ve-live-player
id="player"
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536521.flv"
/>// index.js
import { getVeLivePlayer } from 'veplayer-live-mp-wx';
Page({
onLoad() {
const veLivePlayer = getVeLivePlayer(this, '#player');
veLivePlayer.on('sei', e => {
console.log('sei info: ', e);
});
},
});封面图
您可以设置封面图,注意:封面图域名需要在小程序域名白名单中。
<!-- index.wxml -->
<ve-live-player poster="{{poster}}" id="player" autoplay src="" />// index.js
import { getVeLivePlayer } from 'veplayer-live-mp-wx';
Page({
data: {
poster:
'https://voddemo-cover.volcvod.com/tos-vod-cn-v-8a997967cc533b04/d3a738bc5a2b458dae1c045908118b63~tplv-vod-noop.image',
},
});最佳实践
我们通过三个播放场景来介绍如何使用播放器。在开始之前,我们首先实现两个公共组件,分别是 nav 和 message,您可以根据需要自行添加。
nav
// nav.json
{
"component": true,
"usingComponents": {
"mp-navigation-bar": "weui-miniprogram/navigation-bar/navigation-bar",
"mp-icon": "weui-miniprogram/icon/icon"
}
}<!-- nav.wxml -->
<mp-navigation-bar ext-class="nav-bar" color="{{color}}">
<view slot="center" class="center">
<view class="avatar">
<mp-icon type="field" icon="me" size="{{24}}" color="{{color}}" />
</view>
<text style="margin-left: 8px;">小 A</text>
</view>
</mp-navigation-bar>/* nav.wxss */
.center {
display: flex;
align-items: center;
}// nav.js
Component({
properties: {
color: {
type: String,
value: '#fff',
},
},
});message
// message.json
{
"component": true
}<!-- message.wxml -->
<view class="message-wrap">
<view class="message-list">
<view
class="message-list-item"
wx:for="{{list}}"
wx:key="index"
wx:for-item="item"
>
<text style="color: khaki">{{item.name}}:</text>
<text style="margin-left: 8px; color: {{item.color}}"
>{{item.content}}</text
>
</view>
<view class="message-input">
<input placeholder="聊两句..." placeholder-style="color: #fff" />
</view>
</view>
</view>/* message.wxss */
.message-wrap {
position: absolute;
left: 0;
bottom: 0;
padding: 16px 8px;
}
.message-list {
max-width: 80%;
}
.message-list-item,
.message-input {
font-size: 12px;
padding: 4px 8px;
background-color: rgba(0, 0, 0, 0.5);
border-radius: 6px;
margin-top: 8px;
width: fit-content;
}
.message-input {
color: #fff;
width: 100px;
}// message.js
Component({
data: {
list: [
{
name: '温馨提示',
color: 'khaki',
content:
'欢迎来到直播间!如直播间出现违法违规、色情低俗、抽烟喝酒、诱导欺诈行为,请及时举报。管理员 24 小时在线巡查并接受举报,感谢你与平台一起努力,守护我们共同的社区',
},
{
name: '用户B',
color: '#fff',
content: '你好,我是用户B!',
},
{
name: '主播',
color: '#fff',
content: '@用户B 欢迎来到我的直播间',
},
],
},
});竖屏播放
在竖屏场景下,直播通常有三种表现方式,全屏播放、上半屏播放和居中播放。示例如下:
上半屏播放
{
"usingComponents": {
"ve-live-player": "veplayer-live-mp-wx/ve-live-player/ve-live-player",
"nav": "../components/nav/nav",
"message": "../components/message/message",
"mp-icon": "weui-miniprogram/icon/icon"
},
"navigationStyle": "custom"
}<!-- index.wxml -->
<view class="wrap">
<image class="image" src="/assets/bg.jpeg" />
<nav color="#000" />
<ve-live-player
id="player"
ve-class="player"
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536523.flv"
width="100vw"
height="200px"
object-fit="{{objectFit}}"
fit-video-size="{{fitVideoSize}}"
>
<mp-icon
wx:if="{{fullscreen}}"
style="position: absolute; top: 12px; left: 12px"
icon="back"
color="#fff"
size="{{12}}"
bind:tap="exitFullscreen"
></mp-icon>
<mp-icon
wx:if="{{!fullscreen}}"
style="position: absolute; bottom: 4px; right: 4px;"
icon="max-window"
color="#fff"
size="{{20}}"
bind:tap="requestFullscreen"
></mp-icon>
<message wx:if="{{fullscreen}}" />
</ve-live-player>
<message wx:if="{{!fullscreen}}" />
</view>/** index.wxss */
.wrap {
width: 100vw;
height: 100vh;
overflow: hidden;
}
.image {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
object-fit: cover;
}// index.js
import { getVeLivePlayer } from 'veplayer-live-mp-wx';
Page({
data: {
fullscreen: false,
fitVideoSize: 'fixWidth',
objectFit: 'fillCrop',
},
onLoad() {
const veLivePlayer = getVeLivePlayer(this, '#player');
this.veLivePlayer = veLivePlayer;
this.veLivePlayer.on('fullscreenChange', fullscreen => {
this.setData({
fullscreen,
fitVideoSize: fullscreen ? 'fixed' : 'fixWidth',
objectFit: fullscreen ? 'contain' : 'fillCrop',
});
});
},
requestFullscreen() {
this.veLivePlayer.requestFullscreen({
direction: 90,
});
},
exitFullscreen() {
this.veLivePlayer.exitFullscreen();
},
});居中播放
{
"usingComponents": {
"ve-live-player": "veplayer-live-mp-wx/ve-live-player/ve-live-player",
"nav": "../components/nav/nav",
"message": "../components/message/message",
"mp-icon": "weui-miniprogram/icon/icon"
},
"navigationStyle": "custom"
}<!-- index.wxml -->
<view class="wrap">
<nav color="#000" />
<image class="image" src="/assets/bg.jpeg" />
<ve-live-player
class="player"
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536523.flv"
width="100vw"
height="200px"
fit-video-size="fixWidth"
/>
<message />
</view>/** index.wxss */
.wrap {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.image {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
object-fit: cover;
}
.player {
position: relative;
z-index: 1;
}// index.js
import { getVeLivePlayer } from 'veplayer-live-mp-wx';
Page({});全屏播放
{
"usingComponents": {
"ve-live-player": "veplayer-live-mp-wx/ve-live-player/ve-live-player",
"nav": "../components/nav/nav",
"message": "../components/message/message",
"mp-icon": "weui-miniprogram/icon/icon"
},
"navigationStyle": "custom"
}<!-- index.wxml -->
<view class="wrap">
<ve-live-player
ve-class="player"
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536524.flv"
object-fit="fillCrop"
>
<nav />
<message />
</ve-live-player>
</view>/** index.wxss */
.wrap {
width: 100vw;
height: 100vh;
overflow: hidden;
}
.wrap .player {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}// index.js
Page({});横屏播放
{
"usingComponents": {
"ve-live-player": "veplayer-live-mp-wx/ve-live-player/ve-live-player",
"nav": "../components/nav/nav",
"message": "../components/message/message",
"mp-icon": "weui-miniprogram/icon/icon"
},
"navigationStyle": "custom"
}<!-- index.wxml -->
<view class="wrap">
<nav color="#000" />
<ve-live-player
id="player"
ve-class="player"
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536523.flv"
width="100vw"
height="200px"
object-fit="{{objectFit}}"
fit-video-size="{{fitVideoSize}}"
>
<view class="control">
<view>
<mp-icon
icon='{{paused?"play":"pause"}}'
color="#fff"
size="{{20}}"
bind:tap="handlePlay"
></mp-icon>
<mp-icon
style="margin-left: 8px"
icon="refresh"
color="#fff"
size="{{16}}"
bind:tap="handleRefresh"
></mp-icon>
</view>
<view>
<mp-icon
icon='{{muted?"volume-off":"volume-up"}}'
color="#fff"
size="{{20}}"
bind:tap="handleMute"
></mp-icon>
<mp-icon
icon='{{fullscreen ? "close" : "max-window"}}'
color="#fff"
style="margin-left: 8px"
size="{{16}}"
bind:tap="handleFullscreen"
>
<message wx:if="{{fullscreen}}" />
<message wx:if="{{!fullscreen}}" />
</mp-icon>
</view>
</view>
</ve-live-player>
<view class="bottom">
<view class="tab-list">
<view
wx:for="{{tabList}}"
wx:key="index"
wx:for-item="item"
class="tab-item"
>{{item.text}}</view
>
</view>
<view class="content"
>火山引擎是字节跳动旗下的云服务平台,将字节跳动快速发展过程中积累的增长方法、技术能力和应用工具开放给外部企业,帮助企业在数字化升级中实现持续增长。</view
>
</view>
</view>/** index.wxss */
.wrap {
width: 100vw;
height: 100vh;
overflow: hidden;
display: flex;
flex-direction: column;
}
.image {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
object-fit: cover;
}
.control {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 4px 16px;
display: flex;
justify-content: space-between;
align-items: center;
background-color: rgba(0, 0, 0, 0.5);
}
.bottom {
flex-grow: 1;
}
.tab-list {
display: flex;
border-bottom: 1px solid #ccc;
align-items: center;
justify-content: space-between;
}
.tab-item {
width: 33.333333333%;
padding: 12px 20px;
text-align: center;
}
.tab-item:first-child {
background-color: #eee;
font-weight: bold;
}
.tab-item:not(:first-child) {
border-left: 1px solid #ccc;
}
.content {
padding: 5px 8px;
font-size: 16px;
line-height: 24px;
}// index.js
import { getVeLivePlayer } from 'veplayer-live-mp-wx';
Page({
data: {
fullscreen: false,
fitVideoSize: 'fixWidth',
objectFit: 'fillCrop',
paused: false,
muted: false,
tabList: [
{
text: 'tab1',
},
{
text: 'tab2',
},
{
text: 'tab3',
},
],
},
onLoad() {
const veLivePlayer = getVeLivePlayer(this, '#player');
this.veLivePlayer = veLivePlayer;
this.veLivePlayer.on('fullscreenChange', fullscreen => {
this.setData({
fullscreen,
fitVideoSize: fullscreen ? 'fixed' : 'fixWidth',
objectFit: fullscreen ? 'contain' : 'fillCrop',
});
});
this.veLivePlayer.on('playing', () => {
this.setData({
paused: false,
});
});
this.veLivePlayer.on('pause', () => {
this.setData({
paused: true,
});
});
},
handleFullscreen() {
if (this.data.fullscreen) {
this.veLivePlayer.exitFullscreen();
} else {
this.veLivePlayer.requestFullscreen({
direction: 90,
});
}
},
handlePlay() {
const paused = !this.data.paused;
if (paused) {
this.veLivePlayer.pause();
} else {
this.veLivePlayer.play();
}
},
handleMute() {
const muted = !this.data.muted;
if (muted) {
this.veLivePlayer.mute();
} else {
this.veLivePlayer.unmute();
}
this.setData({
muted,
});
},
handleRefresh() {
this.veLivePlayer.replay();
},
});低延迟
<!-- index.wxml -->
<ve-live-player
autoplay
src="https://pull-demo.volcfcdnrd.com/live/st-4536526.flv"
mode="RTC"
min-cache="{{0.2}}"
max-cache="{{0.8}}"
/>// index.js
Page({});