接入 flv.js

最近更新时间:2023-09-27 15:04:32

我的收藏
此文档介绍了如何将 sdk 集成到 flv.js.

步骤1 根据 flv.js 的规范编写 loader

loader 在 flv.js 中是下载 flv 数据的模块, 我们需要实现一个类似的 loader, 从 p2p sdk 中接收数据

代码如下, 代码中 todo 需要您来实现
/**
* XP2P loader, 对接flv.js
*/
class QVBP2PLoader extends flvjs.BaseLoader {
/**
* 确定当前环境是否支持sdk
* @returns {boolean}
*/
static isSupported() {
return window.QVBP2P && window.QVBP2P.isSupported();
}

constructor(seekHander, config) {
super();
this._qvbp2p = null;
// flv.js成员,非sdk必须
this._receivedLength = 0;
this._config = config;
}

/**
* @public
*/
destroy() {
this._destroyQVBP2P();
super.destroy();
}

/**
* 通过p2p sdk播放一个url
* @public
* @param {object} dataSource
* @param {string} dataSource.url
*/
open(dataSource) {
// 初始化sdk实例
this._createQVBP2P();

// 监听sdk事件
this._qvbp2p.listen(
window.QVBP2P.ComEvents.STATE_CHANGE,
this._onQVBP2PStateChange.bind(this),
);

// 绑定video元素到sdk, 需要替换为客户实际的videoEl
const videoEl = document.getElementById(this._config.videoId);
this._qvbp2p.setMediaElement(videoEl);

// 开始拉流, 注意对于一个sdk实例,loadSource不能重复调用
const config = {
src: dataSource.url,
};
this._qvbp2p.loadSource(config);
}

/**
* @public
*/
abort() {
this._destroyQVBP2P();
}

/**
* 接收sdk抛出的事件,针对不同事件类型有不同的处理
*
* 详细事件名称见 `QVBP2P.ComCodes`
* @param {string} event 事件名称
* @param {*} data
*/
_onQVBP2PStateChange(event, data) {
const { ComCodes } = window.QVBP2P;
const { code } = data;
switch (code) {
case ComCodes.RECEIVE_BUFFER:
this._receiveBuffer_need_to_implement(data.payload);
break;
case ComCodes.ROLLBACK:
this._rollback_need_to_implement();
break;
default:
break;
}
}

/**
* 接收sdk下载回来的flv chunk数据, 送给播放器
*
* @todo 如果您使用的不是flv.js, 则此处需要客户根据播放器情况自行实现
*
* @param {ArrayBuffer} chunk flv chunk
*/
_receiveBuffer_need_to_implement(chunk) {
const byteStart = this._receivedLength;
this._receivedLength += chunk.byteLength;
if (this._onDataArrival) {
this._onDataArrival(chunk, byteStart, this._receivedLength);
}
}

/**
* 当sdk发生错误或不能继续播放时, 会抛出此事件, 需要客户使用原来的flv流程重新播放
*
* @todo 此处需要客户根据播放器情况自行实现
*/
_rollback_need_to_implement() {
window.player.loadWithoutQVBP2P();
}

/**
* 创建sdk实例
*/
_createQVBP2P() {
if (this._qvbp2p) {
this._destroyQVBP2P();
}
this._qvbp2p = new window.QVBP2P.create(this._config.xp2pConfig);
window.qvbp2p = this._qvbp2p;
}

/**
* 销毁sdk实例
*/
_destroyQVBP2P() {
if (this._qvbp2p) {
this._qvbp2p.destroy();
this._qvbp2p = null;
window.qvbp2p = null;
}
}
}

步骤2 在flv.js中使用P2P

此步骤需要您根据播放器实际情况来实现, 此处为示例
/**
* 封装了flv.js的调用, 根据配置选择是否开启XP2P
*/
class Player {
constructor() {
this.flvjsPlayer = null;
}

config({ useP2P, url, xp2pConfig }) {
this.flvjsConfig = {
mediaDataSource: {
type: 'flv',
url,
isLive: true,
},
optionalConfig: {
enableWorker: false,
videoId: 'videoId', // 必填, <video>标签的id
xp2pConfig,
},
};
// 此处关键步骤, 如果需要使用P2P, 则需要替换 `flvjsConfig.optionalConfig.customLoader`为我们步骤1中实现的p2p loader
this.flvjsConfig.optionalConfig.customLoader = useP2P
? QVBP2PLoader
: undefined;
}

/**
* 关闭P2P, 并且下次播放不再使用P2P
*/
loadWithoutQVBP2P() {
this.dispose();
// 这里将customLoader置为空, 则控制flv.js不使用P2P loader
this.flvjsConfig.optionalConfig.customLoader = undefined;
this.play();
}

play() {
if (this.flvjsPlayer) {
this.dispose();
}
this.flvjsPlayer = flvjs.createPlayer(
this.flvjsConfig.mediaDataSource,
this.flvjsConfig.optionalConfig,
);
const element = document.getElementById(this.flvjsConfig.optionalConfig.videoId);
this.flvjsPlayer.attachMediaElement(element);
this.flvjsPlayer.load();
}

dispose() {
this.flvjsPlayer.pause();
this.flvjsPlayer.unload();
this.flvjsPlayer.detachMediaElement();
this.flvjsPlayer.destroy();
this.flvjsPlayer = null;
}
}

// 创建
const player = new Player();
// 配置
player.config({
useP2P: true,
url: '需要自行替换为flv url',
xp2pConfig: {
// 调试 start
debug: false,
// 调试 end
tencentCloudAppId: 按邮件填写,
bizId: '按邮件填写',
xp2pAppId: '按邮件填写',
xp2pPackage: '按邮件填写',
xp2pPlayDomain: '按邮件填写或参考文档',
xp2pAppKey: '按邮件填写或参考文档',
authMode: '按邮件填写或参考文档',
localSecKey: '按邮件填写或参考文档',
},
});
// 启动
window.player.play();