设备视频播放、对讲封装 Webrtc 与 平台接口关系
use npm
npm i rtcvideo-webrtc-player
use yarn
yarn add rtcvideo-webrtc-player
视频
import {
PuPlayer,
IPuPlayerProps,
IPuPlayerInstance,
clearAllDialog,
} from "rtcvideo-webrtc-player";
import "rtcvideo-webrtc-player/dist/main.es.css";
const { instance } = PuPlayer({
// (可选) 容器节点 注意一个容器内只能存在一个实例 当container为假值(包括false、null、undefined)时 将返回实例引用的dom节点 容器必须指定高度 参考高德地图
container: document.getElementById("player_container"),
// 必填 设备选项
puOption: {
// 设备id
id: "PU_123456",
// 设备通道号
index: 0,
},
// 必填 用户授权令牌
token: "Y3UrQ1VfYWRtestYDHYUAStest",
// (可选) peer connection 连接媒体配置
defaultMediaOption: {
// 启用音频
audio: true,
// 启用视频
video: true,
},
// (可选) 传输协议
type: "webrtc" | "ws-bvrtc" | "auto";
// (可选) 是否静音
muted: false,
// (可选) 指定video如何适应容器 (fill: 填充容器 ; contain :保持视频比例适应容器)
videoFit: "fill",
// (可选) 指定请求url路径前缀 可使用protocol+host 如:http://192.168.88.11:9780
apiPrefix: "/test_api/prefix",
// (可选) 用于测试播放视频 (存在时优先使用url播放,为浏览器直接播放)
// testUrl: "https://cdn.plyr.io/static/demo/View_From_A_Blue_Moon_Trailer-576p.mp4",
// (可选) 连接建立后回调
onConnected: () => {},
// (可选) 连接建立失败时的回调
onConnectedFailed: () => {},
// (可选) 连接断开后回调
onDisConnected: () => {},
// (可选) token 失效回调
onTokenFail: () => void,
// (可选) 双击是否全屏
fullScreenOnDblclick: true,
// (可选) 启用控制器
enableController: false,
// (可选) 禁用控制器的控制项 下面示例中禁用了云台控制
disabledControls: ["ptzControl"],
// (可选) 设置最大重连间隔(s),默认不自动重连,setDefaultProps设置的maxReconnectInterval高于props
maxReconnectInterval: 30,
// (可选) 设置webrtc下视频预览,当没有视频时有音频情况下,是否展示音频波形
noVideoRendeAudioWaveform: false,
// (可选) 设置语言支持中文zh、英文en,默认中文
locale: "zh",
// (可选) bvrtc配置
bvrtcConfig: {
// (可选) 是否启用webcodecs解码,默认启用
enableWebcodes: boolean,
// (可选) 设置解码实时性 范围 0-10, 0 -- 流畅性最大, 10 -- 实时性最大
realTimeLevel: number
}
});
// setVideoFit 更改videoFit
instance.setVideoFit("contain");
// setToken 更改请求时的token
instance.setToken("newTTTTToken");
// setPuOption 更改请求的设备信息
instance.setPuOption({
id: "PU_12345test",
index: 123,
});
// setApiPrefix 更改请求时的url前缀
instance.setApiPrefix("/测试改前缀");
// open 的可选参数muted如果为undefined, 是否静音将使用之前的状态
// open 异步 先关闭再开始建立连接 (可选参数: muted:boolean = false 是否静音打开,可选参数: protocol = type 选择协议(type = "auto" | "webrtc" | "ws-bvrtc") 不填默认为auto)
instance.open();
// close 异步 释放dialog 并关闭 当前的 peer connection
instance.close();
// destroy 执行close 并从dom移除PuPlayer节点
instance.destroy();
// moveTo 将节点移动至新的容器
instance.moveTo(document.getElementById("new_player_container"));
// getCurrentContainer 获得当前所在的容器
instance.getCurrentContainer();
// hidden 隐藏 异步 (可选参数: muted?:boolean 是否静音 可不传)
instance.hidden(true);
// display 显示 (可选参数: muted?:boolean 是否静音 可不传)
instance.display();
// play 播放 异步
instance.play();
// mute 切换静音 (可选参数: muted:boolean = false 是否静音)
instance.mute(true);
// 获取puPlayer的div
instance.getPlayerElement();
// 获取内部引用的video元素
instance.getVideoElement();
//播放器状态
instance.playerStatus : {
// 全屏状态管理
fullscreen: {
// 获取全屏状态
Get(): boolean,
// 设置全屏状态
Set(boolean): void;
// 添加事件监听
addEventListener(handle: ((bFullscreen: boolean) => void)):void;
// 移除事件监听
removeEventListener(handle: ((bFullscreen: boolean) => void)):void;
},
volume: {
// 获取音量 0 - 1 之间
Get(): number,
// 设置音量 0 - 1 之间
Set(volume: number): void;
// 添加事件监听
addEventListener(handle: ((volume: number) => void)):void;
// 移除事件监听
removeEventListener(handle: ((volume: number) => void)):void;
},
information: {
// 获取信息窗口显示状态,是否显示
Get(): boolean,
// 设置信息窗口显示状态,是否显示
Set(bShow: boolean): void;
// 添加事件监听
addEventListener(handle: ((bShow: boolean) => void)):void;
// 移除事件监听
removeEventListener(handle: ((bShow: boolean) => void)):void;
},
record:{
// 获取录像状态,是否在录像
//"recordStart" 录像已经开始
//"recordStop" 录像已结束
Get(): {type: "recordStart" | "recordStop"},
// 设置录像状态
Set(status: {type: "recordStart" | "recordStop"}): void;
// 添加事件监听, type == "recordStop" recordInfo 才有值
addEventListener(handle: ((status: {
type: "recordStart" | "recordStop",
recordInfo?: {
data: Blob; // 数据
startTime: number; // 录像开始时间 utc ms
endTime: number; // 录像结束时间 utc ms
duration: number; // 录像时长 ms
fileName: string; // 文件名
puOptions: {
id: string; // 设备名称
index: number; // 通道ID
name?: string; //设备名称,用于内部UI显示
indexName?: string; //通道名称,用于内部UI显示
},
//调用将取消自动下载,返回下载函数
cancelAutoDownload: () => {
//调用该接口,浏览器下载文件, filename 不填为默认的文件名,否则为[filename].webm
download(filename?: string): void;
}
}
}) => void)):void;
// 移除事件监听
removeEventListener(handle: ((status: {
type: "recordStart" | "recordStop",
recordInfo?: {
data: Blob; // 数据
startTime: number; // 录像开始时间 utc ms
endTime: number; // 录像结束时间 utc ms
duration: number; // 录像时长 ms
fileName: string; // 文件名
puOptions: {
id: string; // 设备名称
index: number; // 通道ID
name?: string; //设备名称,用于内部UI显示
indexName?: string; //通道名称,用于内部UI显示
},
//调用将取消自动下载,返回下载函数
cancelAutoDownload: () => {
//调用该接口,浏览器下载文件, filename 不填为默认的文件名,否则为[filename].webm
download(filename?: string): void;
}
}
}) => void)):void;
},
rotate: {
// 获取旋转状态,顺时针方向
// "Rotate0" 0度
// "Rotate90" 90度
// "Rotate180" 180度
// "Rotate270" 270度
Get(): {type: "Rotate0" | "Rotate90" | "Rotate180" | "Rotate270"},
// 设置画面旋转状态
Set(status: {type: "Rotate0" | "Rotate90" | "Rotate180" | "Rotate270"}): void;
// 添加事件监听
addEventListener(handle: ((status: {type: "Rotate0" | "Rotate90" | "Rotate180" | "Rotate270"}) => void)):void;
// 移除事件监听
removeEventListener(handle: ((status: {type: "Rotate0" | "Rotate90" | "Rotate180" | "Rotate270"}) => void)):void;
},
ptzControl: {
// 获取云台控制面板显示状态,是否显示
Get(): {show?: boolean},
// 设置云台控制面板显示状态
Set(status: {show?: boolean}): void;
// 添加事件监听
addEventListener(handle: ((status: {show: boolean})) => void)):void;
// 移除事件监听
removeEventListener(handle: ((status: {show: boolean})) => void)):void;
},
mike: {
// 获取对讲状态,是否在对讲
Get(): {talking?: boolean},
// 设置对讲状态
Set(status: {talking?: boolean}): void;
// 添加事件监听
addEventListener(handle: ((status: {talking?: boolean})) => void)):void;
// 移除事件监听
removeEventListener(handle: ((status: {talking?: boolean})) => void)):void;
},
screenshot:{
//进行截图
exec(): void;
// 添加事件监听,获取截图结果,
// cancelAutoDownload 函数,调用会取消掉下载图片
addEventListener(handle: ((
status: {
img?: Blob,
fileName?: string,
cancelAutoDownload?: ()=>{
download(fileName?: string): void //下载图片
}
})) => void)):void;
// 移除事件监听
removeEventListener(handle: ((
status: {
img?: Blob,
fileName?: string,
cancelAutoDownload?: ()=>{
download(fileName?: string): void //下载图片
}
})) => void)):void;
},
informationGet: () => Promise<{
//音频统计信息
audio?: {
//编码相关
codec: {
//https://developer.mozilla.org/en-US/docs/Web/API/RTCCodecStats/channels
channels?: number; //通道数
//https://developer.mozilla.org/en-US/docs/Web/API/RTCCodecStats/clockRate
clockRate: number; //时钟频率
//https://developer.mozilla.org/en-US/docs/Web/API/RTCCodecStats/mimeType
mimeType: string; //mimetype
//https://developer.mozilla.org/en-US/docs/Web/API/RTCCodecStats/sdpFmtpLine
sdpFmtpLine?: string;
};
//传输相关
rtp: {
sampleRates: string; //采样率
bitRate: number; //bit速率
packageLostTotal: number; //丢包总数
avaragePackageLostRate: number; //平均丢包率
packageLostRate: number; //瞬时丢包率
};
};
//视频统计信息
video?: {
//编码相关
codec: {
type: string; //编码类型 video/H264 video/H265 (webcodec)
sampleRates: number; //采样率
width: number; //视频宽度
height: number; //视频高度
};
//传输相关
rtp: {
sampleRates: number; //视频采样率
bitRate: number; //bit 率
packageLostTotal: number; //总丢包数
avaragePackageLostRate: number; //平均丢包率
packageLostRate: number; //瞬时丢包率
};
};
// 播放相关
meta: {
lastSeconds: number; //持续时间 秒数
transType: "webrtc" | "bvrtc"; //传输方式
};
}>
}
// clearAllDialog 异步 释放全部打开的dialog 不管是音视频还是对讲
clearAllDialog();
- Controls 控制项列表
// 全部控制项
[
"fullscreen",
"ptzControl",
"rotate",
"record",
"screenshot",
"volumeSlider",
"volume",
"mike",
"information"
];
// 在创建实例时 传入参数disabledControls数组 可关闭相关功能
// 如不使用全屏按钮、云台控制器
disabledControls: ["fullscreen", "ptzControl"];
对讲
import {
Intercom,
IIntercomProps,
IIntercomInstance,
} from "rtcvideo-webrtc-player";
import "rtcvideo-webrtc-player/dist/main.es.css";
const { instance } = Intercom({
// 必填 设备选项
puOption: {
// 设备id
id: "PU_123456",
// 设备通道号
index: 0,
},
// 必填 用户授权令牌
token: "Y3UrQ1VfYWRtestYDHYUAStest",
// (可选) 连接建立后回调
onConnected: () => {},
// (可选) 连接建立失败时的回调
onConnectedFailed: () => {},
// (可选) 连接断开后回调
onDisConnected: () => {},
//(可选) 无法获取用户麦克风时
onGetUserMediaFailed: () => {},
// (可选) 指定请求url的前缀 方便代理请求
apiPrefix: "/test_api/prefix",
});
// open 异步 先关闭再开始建立连接 (可选参数: protocol = type 选择协议(type = "auto" | "webrtc" | "ws-bvrtc") 不填默认为auto)
install.open(type);
会议
import {
Conference,
IConferenceProps,
IConferenceInstance,
} from "rtcvideo-webrtc-player";
import "rtcvideo-webrtc-player/dist/main.es.css";
const { instance } = Conference({
// 必填 设备选项
confOption: {
// 会议id
id: "test89312",
// 会议成员ID
index: 0,
},
// 必填 用户授权令牌
token: "Y3UrQ1VfYWRtestYDHYUAStest",
// (可选) 连接建立后回调
onConnected: () => {},
// (可选) 连接建立失败时的回调
onConnectedFailed: () => {},
// (可选) 连接断开后回调
onDisConnected: () => {},
//(可选) 无法获取用户麦克风时
onGetUserMediaFailed: () => {},
// (可选) 指定请求url的前缀 方便代理请求
// apiPrefix: "/test_api/prefix",
});
// open 异步 先关闭再开始建立连接 (可选参数: protocol = type 选择协议(type = "auto" | "webrtc" | "ws-bvrtc") 不填默认为auto)
install.open(type);
Vue 示例
<template>
<div ref="testRef" class="container"></div>
<div ref="test2Ref" class="container2"></div>
<button @click="close">关闭</button>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref } from "vue";
import { PuPlayer, IPuPlayerInstance } from "rtcvideo-webrtc-player";
import "rtcvideo-webrtc-player/dist/main.es.css";
export default defineComponent({
name: "Test",
props: {
// 设备id号
puId: {
type: String,
required: true,
},
// 设备通道号
index: {
type: Number,
required: true,
},
},
setup(props) {
const testRef = ref(null);
const test2Ref = ref(null);
const instanceRef = ref<IPuPlayerInstance | null>(null);
const init = async () => {
const { instance } = PuPlayer({
container: testRef.value,
puOption: { id: props.puId, index: props.index },
token:
"Y3UrQ1VfYWRtaW4rYWRtaW4rMTQzOSsxOTMwMTUrMTYyNTIwMjU3OCthN2I0Y2JiZDliMzkwZWUy",
});
console.log("初始化播放器完成:", instance);
instanceRef.value = instance;
try {
await instance.open();
} catch (e) {}
setTimeout(() => {
// 测试移动到另一个容器内
console.log("移动节点");
instance.moveTo(test2Ref.value);
}, 5000);
};
onMounted(() => {
init();
});
return {
testRef,
test2Ref,
close: () => instanceRef.value?.close(),
};
},
});
</script>
<style lang="scss" scoped>
.container {
height: 300px;
}
</style>
特别说明
-
项目是原生 JS、JQuery 写的,项目中没有导入导出功能的,可以使用暴露出来的"bvPlayer"实例对象进行使用
-
在项目中引入 besovideo/webrtc-player dist 文件夹下面的"main.browser.css"和"main.browser.js"两个文件
<!DOCTYPE html>
<html lang="en">
<head>
<link href="./main.browser.css" type="text/css" rel="stylesheet" />
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="./main.browser.js"/>
<title>Document</title>
</head>
<body>
</body>
<script>
const playerEle = document.createElement("div")
playerEle.style.height = "300px"
playerEle.style.width = "300px"
playerEle.style.backgroundColor = "black"
document.body.appendChild(playerEle);
const {instance} = window.bvPlayer.PuPlayer({
// (可选) 容器节点 注意一个容器内只能存在一个实例 当container为假值(包括false、null、undefined)时 将返回实例引用的dom节点 容器必须指定高度 参考高德地图
container: playerEle,
// 必填 设备选项
puOption: {
// 设备id
id: "PU_123456",
// 设备通道号
index: 0,
},
// 必填 用户授权令牌
token: "Y3UrQ1VfYWRtestYDHYUAStest",
});
instance.open()
</script>
</html>
yarn upgrade rtcvideo-webrtc-player@latest
# 开发运行
yarn
yarn start
# 打包和发布(可直接使用 make publish )
# npm login / yarn login
yarn version
yarn build
yarn publish
# 版本号按照 Major.Minor.Patch 规范
# 可参考https://www.jianshu.com/p/c675121a8bfd