跳到主要内容

音视频播放

更新时间:2025-11-26 15:20:44

音视频播放器,包括:视频直播,暂停、销毁等功能。

接口与类型定义详见sdk中dist目录下index.d.ts文件


/**
* 对外Web播放器接口
* @public
*/
declare interface IRTCXWebPlayer {
/**
* 销毁播放器
*/
destroy(): Promise<void> | void;
/**
* 播放直播
*/
play(): Promise<void> | void;
/**
* 暂停播放
*/
pause(): Promise<void> | void;

/**
* 播放回看
* @param seekParams - 回看参数
*/
seek(seekParams: RTCXWebPlayerTypes.ISeekParam): Promise<void> | void;

/**
* 当前是否正在播放回看
*/
get isPlayback(): boolean;
/**
* 当前是否正在播放设备存储卡回看
*/
get isPlaySDCard(): boolean;

/**
* 添加播放器事件监听
* @param event - 事件
* @param listener - 回调
*/
on(event: RTCXWebPlayerTypes.RTCXWebPlayerEventEnum, listener: (...args: any[]) => void): void;
/**
* 移除播放器事件监听
* @param event - 事件
* @param listener - 回调
*/
off(event: RTCXWebPlayerTypes.RTCXWebPlayerEventEnum, listener: (...args: any[]) => void): void;


/**
* 获取指定插件
* @param pluginName - 插件名称
*/
getPlugin(pluginName: string | RTCXWebPlayerTypes.PlayerPluginEnum): IPlayerPlug | undefined;

}

播放器创建

/**
* web播放器初始化选项
* @public
*/
declare interface IRTCXWebPlayerOption {
/**
* 播放器所在父容器(需要有高宽),播放器自适应父容器高度,宽度
*/
videoWrapper: string | HTMLMediaElement;
/**
* 播放设备信息,由设备列表接口返回
*/
deviceInfo: PlayDeviceInfo;
/**
* 调试日志开关
*/
debug?: boolean;
/**
* 无数据最大等待时长,超时上抛error。单位毫秒
*/
bufferWaitTimeMS?: number;
/**
* 流类型,播放主码流或子码流
*/
streamType?: StreamTypeEnum;
/**
* 镜头id 仅当多目设备播放时使用
*/
lensId?: number;
}


/**
* 错误用法: const rtcxWebPlayer = ref<RTCXWebPlayer>()
* 不使用 ref 或改为使用 shallowRef
*/
let rtcxWebPlayer: RTCXWebPlayer | null = null
const deviceInfo: RTCXDeviceMgrTypes.PlayDeviceInfo = {...}
rtcxWebPlayer = new RTCXWebPlayer({
videoWrapper: '.player-display-area',
deviceInfo: deviceInfo,
})

直播【流转发和P2P】

播放器创建后,收到 RTCXWebPlayerTypes.RTCXWebPlayerEventEnum.inited事件可播放

import { RTCXDeviceMgrTypes, RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'

rtcxWebPlayer?.on(RTCXWebPlayerTypes.RTCXWebPlayerEventEnum.inited, () => {
console.info('rtcxWebPlayer inited')
rtcxWebPlayer?.play()
})

暂停

rtcxWebPlayer?.pause()

销毁播放器

rtcxWebPlayer?.destroy()

回看

rtcxWebPlayer?.seek(seekParam: RTCXWebPlayerTypes.ISeekParam)

播放示例

基础播放示例

import { RTCXDeviceMgrTypes, RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'
const isLive = ref<boolean>(true)
const isPause = ref<boolean>(false)
/**
* 错误用法: const rtcxWebPlayer = ref<RTCXWebPlayer>()
* 不能使用 ref 或改为使用 shallowRef
*/
let rtcxWebPlayer: RTCXWebPlayer | null = null
function initPlayer(deviceInfo: RTCXDeviceMgrTypes.PlayDeviceInfo) {
rtcxWebPlayer?.destroy()

rtcxWebPlayer = new RTCXWebPlayer({
videoWrapper: '.player-display-area',
deviceInfo: deviceInfo,
// disableCMS: true
})

rtcxWebPlayer.on(RTCXWebPlayerTypes.RTCXWebPlayerEventEnum.inited, () => {
console.info('rtcxWebPlayer inited')
rtcxWebPlayer.play()
isPause.value = false
})


rtcxWebPlayer.on(RTCXWebPlayerTypes.RTCXWebPlayerEventEnum.error, (...args) => {
console.info('rtcxWebPlayer error', args)
})

rtcxWebPlayer.on(RTCXWebPlayerTypes.RTCXWebPlayerEventEnum.pause, (...args) => {
console.info('rtcxWebPlayer pause', args)
isPause.value = true
})
}

const isPause = ref<boolean>(false)

function onPlayPause() {
if (!rtcxWebPlayer) return
if (isPause.value) {
rtcxWebPlayer.play()
} else {
rtcxWebPlayer.pause()
}
isPause.value = !isPause.value
}

//回看
const seekParams: RTCXWebPlayerTypes.ISeekParam = {
beginTime, //回看开始utc时间戳 单位:毫秒
endTime, //回看结束utc时间戳 单位:毫秒
isSDCard: true, //true: sd卡回看 false:云回看
}
function onSeekAction(seekParam: RTCXWebPlayerTypes.ISeekParam) {
isLive.value = false
rtcxWebPlayer?.seek(seekParam)
}

低功耗设备播放示例

根据 RTCXDeviceMgrTypes.PlayDeviceInfo.deviceWorkMode返回设备工作模式区分不同设备。工作模式为XS_IOT_WORK_MODE_LOWPOWER_KEEPLIVE时需要先唤醒设备,设备上线后再正常播放

/**
* 设备工作模式
* @public
*/
declare enum DeviceWorkModeEnum {
/**
* 低功耗设备,代理模式,注意只有支持低功耗保活连接的设备才需要设置此模式,设置了此模式之后必须和wifi 芯片上的 lowPwrSDK配合才能工作
*/
XS_IOT_WORK_MODE_LOWPOWER_PROXY = "1",
/**
* 长上电设备,正常链接模式(iotsdk和streamsdk运行在一个进程中)
*/
XS_IOT_WORK_MODE_LONG_TIME_POWER = "2",
/**
* 低功耗设备,iotsdk和streamsdk分离模式,iotsdk运行在wifi或4g芯片上维持信令长连接,streamsdk运行在主控芯片上
*/
XS_IOT_WORK_MODE_LOWPOWER_SEPARATE = "3",
/**
* 低功耗设备,iotsdk和streamsdk运行在主控芯片上,wifi或4g芯片上仅维持简单心跳保活,支持远程唤醒
*/
XS_IOT_WORK_MODE_LOWPOWER_KEEPLIVE = "4"
}

唤醒接口


/**
* 低功耗设备唤醒
* @public
*/
export declare class RTCXDeviceWakeUpMgr {
/**
*
* @param iotId - 设备唯一ID
* @param wakeupTimeout - 超时时长 单位:毫秒 默认30_000
* @param checkStatusInterval - 轮询设备状态频率 单位:毫秒 默认1000
*/
constructor(iotId: string, wakeupTimeout?: number, checkStatusInterval?: number);
/**
* 唤醒设备,等待设备上线
*/
wakeup(): Promise<void>;
/**
* 结束唤醒流程
*
*/
stop(): void;
}

示例

import { RTCXThingModelPanel, RTCXDeviceWakeUpMgr } from '@rtcx/websdk'

let deviceWakeUpMgr: RTCXDeviceWakeUpMgr | null = null

async function playDevice(deviceInfo: RTCXDeviceMgrTypes.PlayDeviceInfo){
//判断设备是否是低功耗设备
if (
deviceInfo.deviceWorkMode ===
RTCXDeviceMgrTypes.DeviceWorkModeEnum.XS_IOT_WORK_MODE_LOWPOWER_KEEPLIVE
) {
deviceWakeUpMgr?.stop()
deviceWakeUpMgr = new RTCXDeviceWakeUpMgr(deviceInfo.iotId,30_000, 1000)
try{
await deviceWakeUpMgr.wakeup()
}catch(e){
//处理超时等异常情况,可根据业务自行处理
//示例:重新走一次唤醒流程
playDevice(deviceInfo)
return
}
}
initPlayer(deviceInfo) //见基础播放示例
}



当设备不再播放时,设备会进入休眠,应用可以通过物模型发信令通知设备不要休眠

以下仅为示例,需要设备与应用自行定义协议并实现

import {RTCXDeviceMgrTypes, RTCXThingModelTypes, RTCXThingModelPanel} from '@rtcx/websdk'


let thingModelPanel: RTCXThingModelPanel | undefined
function getThingModelPanel() {
const deviceInfo = currentDeviceInfo.value
if (!deviceInfo) return console.warn('getThingModelPanel: no device')
if (thingModelPanel && thingModelPanel.deviceInfo.iotId != deviceInfo.iotId) {
thingModelPanel.destroy()
thingModelPanel = undefined
}

if (!thingModelPanel) {
thingModelPanel = new RTCXThingModelPanel(deviceInfo)
thingModelPanel.subscribe(panelEventCallback)
}
return thingModelPanel
}
/**
* 定时通知设备不要休眠
*/
function startHeartbeat(){
const heartbeatIntervalSecond = 10; //秒
const thingPanel = getThingModelPanel()
const params:Record<string,number> = {
//通知设备Interval秒后进入休眠
Interval: heartbeatIntervalSecond
};
setTimeout(()=>{
thingPanel.invokeService("WakeupHeartbeat", params)
startHeartbeat()
}(heartbeatIntervalSecond-1) * 1000)

}

截图

获取截图插件

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'
let rtcxWebPlayer: RTCXWebPlayer | null = null
const snapshotPlugin = rtcxWebPlayer?.getPlugin(
RTCXWebPlayerTypes.PlayerPluginEnum.SnapshotPlugin
)

调用截图方法

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'
await snapshotPlugin?.callMethod<string>(
RTCXWebPlayerTypes.SnapshotPluginMethodEnum.snapshot
)

示例

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'
const snapshotImg = ref('')
async function onSnapshotClick() {
const snapshotPlugin = rtcxWebPlayer?.getPlugin(
RTCXWebPlayerTypes.PlayerPluginEnum.SnapshotPlugin
)
const base64Url = await snapshotPlugin?.callMethod<string>(
RTCXWebPlayerTypes.SnapshotPluginMethodEnum.snapshot
)
if (base64Url) {
snapshotImg.value = base64Url
} else {
ElNotification.error('截图失败')
}
}
<img :src="snapshotImg" width="640" height="360" />

缩放旋转

获取缩放插件

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'
let rtcxWebPlayer: RTCXWebPlayer | null = null

const zoomPlugin = rtcxWebPlayer?.getPlugin(RTCXWebPlayerTypes.PlayerPluginEnum.ZoomPlug)

画面缩放

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'
zoomPlugin?.callMethod<string>(RTCXWebPlayerTypes.ZoomPluginMethodEnum.setScale, value as number)

示例

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'

const videoZoomRate = ref(1)

function onZoomChange(value: Arrayable<number>) {
console.info('onZoomChange', value, videoZoomRate.value)
const zoomPlugin = rtcxWebPlayer?.getPlugin(RTCXWebPlayerTypes.PlayerPluginEnum.ZoomPlug)
zoomPlugin?.callMethod<string>(RTCXWebPlayerTypes.ZoomPluginMethodEnum.setScale, value as number)
}
<el-slider
style="width: 200px"
v-model="videoZoomRate"
:min="1"
:max="5"
:step="0.1"
@input="onZoomChange"
/>

画面旋转

支持旋转度数 0, 90, 180, 270

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'
const deg = 90
zoomPlugin?.callMethod<string>(RTCXWebPlayerTypes.ZoomPluginMethodEnum.setRotate, deg)

示例

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'

const allowRotateDegs = [0, 90, 180, 270]
let currentRotateIndex = 0
const currentRotateText = ref('')

function onRotateClick() {
const zoomPlugin = rtcxWebPlayer?.getPlugin(RTCXWebPlayerTypes.PlayerPluginEnum.ZoomPlug)
currentRotateIndex = (currentRotateIndex + 1) % allowRotateDegs.length
const deg = allowRotateDegs[currentRotateIndex]
currentRotateText.value = deg > 0 ? deg + '度' : ''
zoomPlugin?.callMethod<string>(RTCXWebPlayerTypes.ZoomPluginMethodEnum.setRotate, deg)
}
<el-button type="primary" @click="onRotateClick()">
旋转{{ currentRotateText }}
</el-button>

全屏窗口

declare class RTCXWebPlayer{
/**
* 全屏
*
* @param domElement - Dom元素
* @public
*/
static requestFullscreen(domElement: Element): void;
/**
* 判断当前是否全屏
* @public
*/
static isFullscreen(): boolean;
/**
* 浏览器退出全屏
* @public
*/
static exitFullscreen(): void;
/**
* 监听全屏状态变化
* @param listener - 加调
*/
static onFullscreenChange(listener: Listener): void;
/**
* 移除监听全屏状态变化
* @param listener - 加调
*/
static offFullscreenChange(listener: Listener): void;
}

进入全屏

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'
const playerAreaRef = document.querySelector('.xxxx_web_player_wrapper')
RTCXWebPlayer.requestFullscreen(playerAreaRef)

退出全屏

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'

RTCXWebPlayer.exitFullscreen()

当前是否全屏

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'

RTCXWebPlayer.isFullscreen()

全屏事件

//监听事件
RTCXWebPlayer.onFullscreenChange(onFullscreenChangeListener)
//移除监听
RTCXWebPlayer.offFullscreenChange(onFullscreenChangeListener)

示例

import { RTCXWebPlayer, RTCXWebPlayerTypes } from '@rtcx/websdk'
import { ref, onMounted, onUnmounted } from 'vue'

const playerAreaRef = ref()
const isFullscreen = ref(false)

function changeFullscreen() {
console.info(playerAreaRef)
if (!RTCXWebPlayer.isFullscreen()) {
RTCXWebPlayer.requestFullscreen(playerAreaRef.value)
} else {
RTCXWebPlayer.exitFullscreen()
}
}

function onFullscreenChangeListener() {
isFullscreen.value = RTCXWebPlayer.isFullscreen()
console.info('onFullscreenChangeListener=' + isFullscreen.value)
}

onMounted(() => {
RTCXWebPlayer.onFullscreenChange(onFullscreenChangeListener)
})

onUnmounted(() => {
RTCXWebPlayer.offFullscreenChange(onFullscreenChangeListener)
})