
简体中文
uni直播是DCloud与七牛云合作推出的直播服务,七牛云直播依托云边一体化架构和海量节点资源,构建高效的流媒体服务。通过多维度的节点监控与弹性的节点调度管理,确保高质量服务与成本效益的完美平衡。
live-player
组件是uni直播服务中的拉流(播放)组件,在 Android/iOS 平台使用需要申请绑定包名/Bundle ID(AppID),详情咨询
实时音视频播放
Web | 微信小程序 | Android | iOS | HarmonyOS |
---|---|---|---|---|
x | 4.41 | 4.81 | 4.81 | x |
名称 | 类型 | 默认值 | 兼容性 | 描述 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
src | string(string.VideoURIString) | - | 音视频地址。微信小程序支持 flv, rtmp 格式,app平台支持 rtmp, hls 协议 | |||||||||||||
mode | string | - | live(直播),RTC(实时通话) | |||||||||||||
| ||||||||||||||||
autoplay | boolean | false | 自动播放 | |||||||||||||
muted | boolean | false | 是否静音 | |||||||||||||
orientation | string | "vertical" | 画面方向,可选值有 vertical,horizontal | |||||||||||||
| ||||||||||||||||
object-fit | string | "contain" | 填充模式,可选值有 contain,fillCrop | |||||||||||||
| ||||||||||||||||
background-mute | boolean | false | 进入后台时是否静音 | |||||||||||||
min-cache | string | - | 最小缓冲区,单位s | |||||||||||||
max-cache | string | - | 最大缓冲区,单位s | |||||||||||||
@statechange | (event: UniLivePlayerStatechangeEvent) => void | - | 播放状态变化事件,event.detail = {code} | |||||||||||||
@fullscreenchange | (event: UniLivePlayerFullscreenchangeEvent) => void | - | 全屏变化事件,event.detail = {direction, fullScreen} | |||||||||||||
@error | (event: UniLivePlayerErrorEvent) => void | - | 错误事件,event.detail = {errCode, errMsg} | |||||||||||||
@netstatus | (event: UniEvent) => void | - | 网络状态通知,detail = {info} | |||||||||||||
sound-mode | string | - | (string) 声音输出方式 | |||||||||||||
| ||||||||||||||||
auto-pause-if-navigate | boolean | - | (boolean) 当跳转到本小程序的其他页面时,是否自动暂停本页面的实时音视频播放 | |||||||||||||
auto-pause-if-open-native | boolean | - | (boolean) 当跳转到其它微信原生页面时,是否自动暂停本页面的实时音视频播放 | |||||||||||||
picture-in-picture-mode | string/Array | - | (string/Array) 设置小窗模式: push, pop,空字符串或通过数组形式设置多种模式(如: ["push", "pop"] | |||||||||||||
| ||||||||||||||||
picture-in-picture-init-position= | string | - | (string) 小窗模式下小窗的初始显示位置,格式为 (alignment, y),其中 alignment 表示小窗吸附屏幕左侧还是右侧,可选值为 left、right,y 代表小窗最顶部所在的屏幕高度百分比 | |||||||||||||
enable-auto-rotation | boolean | - | (boolean) 是否开启手机横屏时自动全屏,当系统设置开启自动旋转时生效 | |||||||||||||
referrer-policy | string | - | (string) 格式固定为 https://servicewechat.com/{appid}/{version}/page-frame.html ,其中 {appid} 为小程序的 appid,{version} 为小程序的版本号,版本号为 0 表示为开发版、体验版以及审核版本,版本号为 devtools 表示为开发者工具,其余为正式版本; | |||||||||||||
| ||||||||||||||||
enable-casting | boolean | - | (boolean) 是否支持投屏。开启后,可以通过 LivePlayerContext 上相关方法进行操作。 | |||||||||||||
@audiovolumenotify | eventhandler | - | (eventhandler) 播放音量大小通知,detail = {} | |||||||||||||
@enterpictureinpicture | eventhandler | - | (eventhandler) 播放器进入小窗 | |||||||||||||
@leavepictureinpicture | eventhandler | - | (eventhandler) 播放器退出小窗 | |||||||||||||
@castinguserselect | eventhandler | - | (eventhandler) 用户选择投屏设备时触发 detail = { state: "success"/"fail" } | |||||||||||||
@castingstatechange | eventhandler | - | (eventhandler) 投屏成功/失败时触发 detail = { type, state: "success"/"fail" } | |||||||||||||
@castinginterrupt | eventhandler | - | (eventhandler) 投屏被中断时触发 |
播放状态变化事件
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
detail | UniLivePlayerStatechangeEventDetail | 是 | - | - | - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bubbles | boolean | 是 | - | - | - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cancelable | boolean | 是 | - | - | - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type | string | 是 | - | - | - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
target | UniElement | 否 | - | - | - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
currentTarget | UniElement | 否 | - | - | - | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
timeStamp | Long | 是 | - | - | - |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
stopPropagation | () => void | 是 | - | - | - |
preventDefault | () => void | 是 | - | - | - |
全屏事件
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
detail | UniLivePlayerFullscreenchangeEventDetail | 是 | - | - | - | ||||||||||||||||||
| |||||||||||||||||||||||
bubbles | boolean | 是 | - | - | - | ||||||||||||||||||
cancelable | boolean | 是 | - | - | - | ||||||||||||||||||
type | string | 是 | - | - | - | ||||||||||||||||||
target | UniElement | 否 | - | - | - | ||||||||||||||||||
currentTarget | UniElement | 否 | - | - | - | ||||||||||||||||||
timeStamp | Long | 是 | - | - | - |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
stopPropagation | () => void | 是 | - | - | - |
preventDefault | () => void | 是 | - | - | - |
错误事件
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
detail | UniLivePlayerError | 是 | - | - | - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bubbles | boolean | 是 | - | - | - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cancelable | boolean | 是 | - | - | - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type | string | 是 | - | - | - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
target | UniElement | 否 | - | - | - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
currentTarget | UniElement | 否 | - | - | - | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
timeStamp | Long | 是 | - | - | - |
名称 | 类型 | 必填 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
stopPropagation | () => void | 是 | - | - | - |
preventDefault | () => void | 是 | - | - | - |
示例为hello uni-app x alpha分支,与最新HBuilderX Alpha版同步。与最新正式版同步的master分支示例另见
该 API 不支持 Web,请运行 hello uni-app x 到 App 平台体验
<template>
<view class="uni-flex-item">
<live-player id="live-player" class="live-player" :src="src" :autoplay="autoplay" :muted="muted"
:object-fit="objectFit" :background-mute="backgroundMute" :sound-mode="soundMode" :orientation="orientation"
@statechange="statechange" @fullscreenchange="fullscreenchange" @error="error">
</live-player>
<scroll-view class="uni-padding-wrap uni-common-mt uni-flex-item">
<view class="uni-title">
<text class="uni-title-text">API示例</text>
</View>
<view class="uni-btn-v">
<button type="primary" @click="play" :disabled="playState">播放</button>
</view>
<view class="uni-btn-v">
<button type="primary" @click="pause" :disabled="!playState">暂停</button>
</view>
<view class="uni-btn-v">
<button type="primary" @click="resume" :disabled="initState || playState || stopState">恢复</button>
</view>
<view class="uni-btn-v">
<button type="primary" @click="stop" :disabled="!playState">停止</button>
</view>
<view class="uni-btn-v">
<button type="primary" @click="mute" :disabled="!playState">静音</button>
</view>
<view class="uni-btn-v">
<button type="primary" @click="requestFullScreen" :disabled="!playState">进入全屏</button>
</view>
<view class="uni-btn-v">
<button type="primary" @click="exitFullScreen" :disabled="!playState">退出全屏</button>
</view>
<view class="uni-title">
<text class="uni-title-text">属性示例</text>
</view>
<input class="input margin-10" type="string" placeholder="设置播放地址" @confirm="onSrcComfirm"></input>
<boolean-data title="设置是否自动播放" :defaultValue="autoplay" @change="onAutoplayChange"></boolean-data>
<boolean-data title="设置是否静音" :defaultValue="muted" @change="onMutedChange"></boolean-data>
<boolean-data title="设置进入后台时是否静音" :defaultValue="backgroundMute" @change="onBackgroundMuteChange"></boolean-data>
<enum-data title="设置填充模式" :items="objectFitItemTypes" @change="onObjectFitChange"></enum-data>
<enum-data title="设置声音输出方式" :items="soundModeItemTypes" @change="onSoundModeChange"></enum-data>
<enum-data title="设置画面方向" :items="orientationItemTypes" @change="onOrientationChange"></enum-data>
</scroll-view>
</view>
</template>
<script setup>
import { ItemType } from '@/components/enum-data/enum-data-types';
const context = ref(null as LivePlayerContext | null);
const src = ref("");
const autoplay = ref(false);
const muted = ref(false);
const objectFit = ref("contain");
const backgroundMute = ref(false);
const soundMode = ref("speaker");
const orientation = ref("vertical");
const initState = ref(true);
const playState = ref(false);
const stopState = ref(false);
onReady(() => {
context.value = uni.createLivePlayerContext("live-player", getCurrentInstance()!.proxy);
});
const statechange = (e : UniLivePlayerStatechangeEvent) => {
console.log("statechange", e);
switch (e.detail.code) {
case 10004:
initState.value = false;
playState.value = true;
stopState.value = false;
break;
case 10009:
stopState.value = true;
case 10006:
case 10007:
case 10010:
case 10011:
playState.value = false;
break;
}
};
const fullscreenchange = (e : UniLivePlayerFullscreenchangeEvent) => {
console.log("fullscreenchange", e);
};
const error = (e : UniLivePlayerErrorEvent) => {
console.log("error", e);
};
const isSrcValid = () : boolean => {
const length = src.value.length;
if (length <= 0) {
uni.showToast({
title: "请输入播放地址",
icon: "none"
});
}
return length > 0;
};
const play = () => {
if (!isSrcValid()) return;
context.value?.play({
success: (res) => {
console.log("play", JSON.stringify(res));
},
fail: (err) => {
console.log("play", JSON.stringify(err));
},
complete: (res) => {
console.log("play", JSON.stringify(res));
}
});
};
const pause = () => {
if (!isSrcValid()) return;
context.value?.pause({
success: (res) => {
console.log("pause", JSON.stringify(res));
},
fail: (err) => {
console.log("pause", JSON.stringify(err));
},
complete: (res) => {
console.log("pause", JSON.stringify(res));
}
});
};
const resume = () => {
if (!isSrcValid()) return;
context.value?.resume({
success: (res) => {
console.log("resume", JSON.stringify(res));
},
fail: (err) => {
console.log("resume", JSON.stringify(err));
},
complete: (res) => {
console.log("resume", JSON.stringify(res));
}
});
};
const stop = () => {
if (!isSrcValid()) return;
context.value?.stop({
success: (res) => {
console.log("stop", JSON.stringify(res));
},
fail: (err) => {
console.log("stop", JSON.stringify(err));
},
complete: (res) => {
console.log("stop", JSON.stringify(res));
}
});
};
const mute = () => {
if (!isSrcValid()) return;
context.value?.mute({
success: (res) => {
console.log("mute", JSON.stringify(res));
},
fail: (err) => {
console.log("mute", JSON.stringify(err));
},
complete: (res) => {
console.log("mute", JSON.stringify(res));
}
});
};
const requestFullScreen = () => {
if (!isSrcValid()) return;
context.value?.requestFullScreen({
success: (res) => {
console.log("requestFullScreen", JSON.stringify(res));
},
fail: (err) => {
console.log("requestFullScreen", JSON.stringify(err));
},
complete: (res) => {
console.log("requestFullScreen", JSON.stringify(res));
}
});
};
const exitFullScreen = () => {
if (!isSrcValid()) return;
context.value?.exitFullScreen({
success: (res) => {
console.log("exitFullScreen", JSON.stringify(res));
},
fail: (err) => {
console.log("exitFullScreen", JSON.stringify(err));
},
complete: (res) => {
console.log("exitFullScreen", JSON.stringify(res));
}
});
};
const objectFitItemTypes = [{ "value": 0, "name": "contain" }, { "value": 1, "name": "fillCrop" }] as ItemType[];
const objectFitItems = ["contain", "fillCrop"];
const soundModeItemTypes = [{ "value": 0, "name": "speaker" }, { "value": 1, "name": "ear" }] as ItemType[];
const soundModeItems = ["speaker", "ear"];
const orientationItemTypes = [{ "value": 0, "name": "vertical" }, { "value": 1, "name": "horizontal" }] as ItemType[];
const orientationItems = ["vertical", "horizontal"];
const onSrcComfirm = (event : UniInputConfirmEvent) => {
let value = event.detail.value;
if (value == '') return;
src.value = value;
console.log("src ->", value);
};
const onAutoplayChange = (value : boolean) => {
autoplay.value = value;
console.log("autoplay ->", autoplay.value);
};
const onMutedChange = (value : boolean) => {
muted.value = value;
console.log("muted ->", muted.value);
};
const onBackgroundMuteChange = (value : boolean) => {
backgroundMute.value = value;
console.log("background-mute ->", backgroundMute.value);
};
const onObjectFitChange = (value : number) => {
objectFit.value = objectFitItems[value];
console.log("object-fit ->", objectFit.value);
};
const onSoundModeChange = (value : number) => {
soundMode.value = soundModeItems[value];
console.log("sound-mode ->", soundMode.value);
};
const onOrientationChange = (value : number) => {
orientation.value = orientationItems[value];
console.log("orientation ->", orientation.value);
};
</script>
<style>
.live-player {
width: 100%;
height: 40%;
}
.input {
height: 40px;
background: #FFF;
padding: 8px 13px;
}
.margin-10 {
margin: 10px;
}
</style>