更新记录
1.0.0(2026-06-14)
发布1.0.0,基于腾讯云直播推拉流SDK封装的直播推流与拉流组件
平台兼容性
uni-app x(4.87)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | 5.0 | 12 | × | × |
jinyu-txlive
jinyu-txlive 是基于腾讯云 LiteAVSDK Live / V2TXLive 封装的 uni-app x UTS 原生组件插件,提供推拉流直播播放和直播推流能力。
插件当前包含两个可直接在页面中使用的组件:
txlive-player:直播播放组件,底层封装V2TXLivePlayertxlive-pusher:直播推流组件,底层封装V2TXLivePusher
同时提供 API:
installTxLive(licenceURL, licenceKey):初始化腾讯云直播 LicenserequestPusherPermissions(onGranted):申请推流需要的相机和麦克风权限createPlayerContent(element):创建播放器原生对象,通常由组件内部使用createPusherContent(element):创建推流器原生对象,通常由组件内部使用
平台支持
| 平台 | 状态 | 说明 |
|---|---|---|
| Android App | 支持 | |
| iOS App | 支持 | |
| Harmony | 暂未实现 | |
| Web / 小程序 | 不支持 | 原生直播 SDK 仅用于 App 端 |
初始化 License
使用播放或推流前,先调用 installTxLive 设置腾讯云直播 License。
建议在 App.uvue、应用启动页,或直播页面进入前执行一次。
import { installTxLive } from '@/uni_modules/jinyu-txlive'
installTxLive(
'你的 licenceURL',
'你的 licenceKey'
)
说明:
onLicenceLoaded中result == 0表示 License 加载成功,非 0 表示失败- License 参数为空时,插件会直接返回,不会调用 SDK 初始化
播放直播
页面中使用 txlive-player 组件,并通过 ref 调用播放方法。
<template>
<view class="page">
<txlive-player
ref="playerRef"
class="player"
:keep-screen-always-on="true"
@event="onPlayerEvent"
/>
<button class="button" @click="startPlay">开始播放</button>
<button class="button" @click="stopPlay">停止播放</button>
</view>
</template>
<script setup lang="uts">
import { installTxLive } from '@/uni_modules/jinyu-txlive'
import { TxLiveEvent } from '@/uni_modules/jinyu-txlive/utssdk/interface.uts'
const playerRef = ref<any | null>(null)
const playUrl = 'https://example.com/live.flv'
installTxLive('你的 licenceURL', '你的 licenceKey')
const startPlay = () : void => {
playerRef.value?.startLivePlay(playUrl)
}
const stopPlay = () : void => {
playerRef.value?.stopPlay()
}
const onPlayerEvent = (event : TxLiveEvent) : void => {
console.log('player event: ' + event.type)
if (event.type == 'error') {
console.log('播放错误 code=' + event.code + ' msg=' + event.msg)
}
}
</script>
<style>
.page {
flex: 1;
flex-direction: column;
}
.player {
width: 100%;
height: 420px;
}
.button {
margin-top: 16px;
}
</style>
播放器方法
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
startLivePlay(playUrl) |
string |
number |
开始播放直播流 |
stopPlay() |
- | number |
停止播放 |
isPlaying() |
- | number |
1 表示正在播放,0 表示未播放 |
pauseAudio() |
- | number |
暂停音频 |
resumeAudio() |
- | number |
恢复音频 |
pauseVideo() |
- | number |
暂停视频 |
resumeVideo() |
- | number |
恢复视频 |
setRenderRotation(angle) |
0 / 90 / 180 / 270 |
number |
设置画面旋转 |
setRenderFillMode(model) |
0 / 1 / 2 |
number |
设置填充模式 |
setRenderMirrorMode(isMirror) |
boolean |
number |
设置播放画面镜像 |
setPlayoutVolume(volume) |
0 - 100 |
number |
设置播放音量 |
setCacheParams(minTime, maxTime) |
number, number |
number |
设置播放缓存,单位秒 |
switchStream(url) |
string |
number |
无缝切换直播流,支持 FLV / LEB |
enableVolumeEvaluation(intervalMs) |
number |
number |
开启音量回调 |
snapshot() |
- | number |
截取当前播放画面 |
enableReceiveSeiMessage(enable, payloadType) |
boolean, number |
number |
开启或关闭 SEI 消息接收 |
showDebugView(show) |
boolean |
void |
显示或隐藏 SDK 调试浮层 |
setProperty(key, value) |
string, any \| null |
number |
调用 SDK 高级属性接口 |
startLocalRecording(filePath, recordMode, interval) |
string, number, number |
number |
开始本地录制 |
stopLocalRecording() |
- | void |
停止本地录制 |
destroy() |
- | void |
销毁播放器 |
setRenderFillMode(model) 参数说明:
0:Fill,铺满容器,可能裁剪画面1:Fit,完整显示,可能有黑边2:ScaleFill,拉伸铺满
推流直播
推流前建议先申请相机和麦克风权限。
<template>
<view class="page">
<txlive-pusher
ref="pusherRef"
class="pusher"
:keep-screen-always-on="true"
@event="onPusherEvent"
/>
<button class="button" @click="startPush">开始推流</button>
<button class="button" @click="stopPush">停止推流</button>
<button class="button" @click="switchCamera">切换摄像头</button>
</view>
</template>
<script setup lang="uts">
import { installTxLive, requestPusherPermissions } from '@/uni_modules/jinyu-txlive'
import { TxLiveEvent } from '@/uni_modules/jinyu-txlive/utssdk/interface.uts'
const pusherRef = ref<any | null>(null)
const pushUrl = 'rtmp://example.com/live/stream'
installTxLive('你的 licenceURL', '你的 licenceKey')
const startPush = () : void => {
requestPusherPermissions(() : void => {
pusherRef.value?.startCamera(0)
pusherRef.value?.startMicrophone()
pusherRef.value?.startPush(pushUrl)
})
}
const stopPush = () : void => {
pusherRef.value?.stopPush()
pusherRef.value?.stopCamera()
pusherRef.value?.stopMicrophone()
}
const switchCamera = () : void => {
pusherRef.value?.switchCamera(null)
}
const onPusherEvent = (event : TxLiveEvent) : void => {
console.log('pusher event: ' + event.type)
if (event.type == 'error') {
console.log('推流错误 code=' + event.code + ' msg=' + event.msg)
}
}
</script>
<style>
.page {
flex: 1;
flex-direction: column;
}
.pusher {
width: 100%;
height: 420px;
}
.button {
margin-top: 16px;
}
</style>
推流器方法
| 方法 | 参数 | 返回值 | 说明 |
|---|---|---|---|
startPush(pushUrl) |
string |
number |
开始推流 |
stopPush() |
- | number |
停止推流 |
isPushing() |
- | number |
1 表示正在推流,0 表示未推流 |
startCamera(behind) |
number |
number |
打开摄像头,1 为后置,否则前置 |
stopCamera() |
- | number |
关闭摄像头 |
switchCamera(behind) |
number \| null |
number |
切换摄像头,null 表示自动切换 |
startMicrophone() |
- | number |
打开麦克风 |
stopMicrophone() |
- | number |
关闭麦克风 |
enableMirror() |
- | number |
开启本地预览镜像 |
disableMirror() |
- | number |
关闭本地预览镜像 |
setRenderRotation(angle) |
0 / 90 / 180 / 270 |
number |
设置本地预览旋转 |
setRenderFillMode(model) |
0 / 1 |
number |
设置本地预览填充模式 |
pauseAudio() |
- | number |
暂停推流音频 |
resumeAudio() |
- | number |
恢复推流音频 |
pauseVideo() |
- | number |
暂停推流视频 |
resumeVideo() |
- | number |
恢复推流视频 |
startScreenCapture() |
- | number |
开启屏幕采集 |
stopScreenCapture() |
- | number |
关闭屏幕采集 |
startVirtualCamera(url) |
string |
number |
开启图片推流 |
stopVirtualCamera() |
- | number |
关闭图片推流 |
destroy() |
- | void |
销毁推流器 |
事件回调
txlive-player 和 txlive-pusher 都通过 @event 向页面派发事件。
事件类型定义:
export type TxLiveEvent = {
type : string,
code ?: number,
msg ?: string,
descriptionInfo ?: string,
data ?: UTSJSONObject
}
播放事件
| type | data | 说明 |
|---|---|---|
connected |
- | 已连接服务器 |
videoPlaying |
{ firstPlay } |
视频开始播放或恢复播放 |
audioPlaying |
{ firstPlay } |
音频开始播放或恢复播放 |
videoLoading |
- | 视频加载中 |
audioLoading |
- | 音频加载中 |
videoResolutionChanged |
{ width, height } |
视频分辨率变化 |
playoutVolumeUpdate |
{ volume } |
播放音量回调 |
statisticsUpdate |
统计信息 | 播放统计信息 |
snapshotComplete |
{ hasImage } |
截图完成 |
receiveSeiMessage |
{ payloadType, dataLength } |
收到 SEI 消息 |
streamSwitched |
{ url, code } |
切流完成 |
localRecordBegin |
{ storagePath, code } |
本地录制开始 |
localRecording |
{ durationMs, storagePath } |
本地录制进度 |
localRecordComplete |
{ storagePath, code } |
本地录制完成 |
warning |
code / msg / descriptionInfo |
SDK 警告 |
error |
code / msg / descriptionInfo |
SDK 错误 |
推流事件
| type | data | 说明 |
|---|---|---|
pushStatusUpdate |
{ status, msg } |
推流状态变化 |
captureFirstAudioFrame |
- | 采集到首帧音频 |
captureFirstVideoFrame |
- | 采集到首帧视频 |
microphoneVolumeUpdate |
{ volume } |
麦克风音量回调 |
statisticsUpdate |
统计信息 | 推流统计信息 |
snapshotComplete |
{ hasImage } |
截图完成 |
screenCaptureStarted |
- | 屏幕采集开始 |
screenCaptureStopped |
{ reason } |
屏幕采集停止 |
localRecordBegin |
{ code, storagePath } |
本地录制开始 |
localRecording |
{ durationMs, storagePath } |
本地录制进度 |
localRecordComplete |
{ code, storagePath } |
本地录制完成 |
voiceActivityDetectionUpdate |
{ active } |
人声检测状态 |
warning |
code / msg / descriptionInfo |
SDK 警告 |
error |
code / msg / descriptionInfo |
SDK 错误 |
返回值说明
大多数方法直接返回腾讯云 V2TXLive SDK 的状态码。
插件额外约定:
0:调用成功或当前状态无需重复操作-1:传入参数为空,例如播放地址或推流地址为空-999:原生播放器或推流器对象尚未创建,通常是组件还没有触发native-view @init
如果调用方法返回 -999,通常需要确认:
- 组件是否已经渲染
- 是否通过
ref在组件初始化后调用方法 - 播放器或推流器是否已经被
destroy()
权限与打包配置
Android
插件会通过 requestPusherPermissions 申请:
android.permission.CAMERAandroid.permission.RECORD_AUDIO
Android 最低版本为 minSdkVersion 21。
iOS
iOS 推流需要相机和麦克风权限。请确保项目配置了权限描述:
NSCameraUsageDescriptionNSMicrophoneUsageDescription
iOS 最低版本为 12.0。
生命周期建议
播放页面离开时建议停止播放或销毁播放器:
onUnload(() => {
playerRef.value?.destroy()
})
推流页面离开时建议停止推流、关闭摄像头和麦克风:
onUnload(() => {
pusherRef.value?.destroy()
})
组件默认 keepScreenAlwaysOn = true,页面加载时会保持屏幕常亮状态,卸载时会自动恢复屏幕常亮状态。
常见问题
1. 为什么调用播放或推流返回 -999?
说明原生对象还没有创建。
播放器组件已支持 startLivePlay 的延迟播放:如果初始化前调用,会先缓存播放地址,初始化完成后自动播放。其他方法建议在页面渲染完成后调用。
2. License 加载成功怎么判断?
onLicenceLoaded(result, reason) 中 result == 0 表示成功,非 0 表示失败。失败时请检查 licenceURL、licenceKey、包名或 Bundle ID 是否和腾讯云控制台配置一致。
3. 直播播放成功应该看哪个事件?
建议以 videoPlaying 作为视频真正开始渲染的判断依据。connected 只表示连接建立,不代表已经有视频画面。
4. 推流前必须调用哪些方法?
普通摄像头推流的推荐顺序:
installTxLiverequestPusherPermissionsstartCamerastartMicrophonestartPush
停止推流的推荐顺序:
stopPushstopCamerastopMicrophonedestroy

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 48
赞赏 1
下载 12240296
赞赏 1921
赞赏
京公网安备:11010802035340号