UNPKG

trtc-electron-sdk

Version:

trtc electron sdk

377 lines (376 loc) 14.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.V2LivePlayer = void 0; const events_1 = require("events"); const live_define_1 = require("../live_define"); const video_render_1 = require("../video-render"); const converter_1 = require("../converter"); const logger_1 = require("../../logger"); const NodeTRTCEngine = require('../../../build/Release/trtc_electron_sdk.node'); /** * 腾讯云直播播放器 * * @example * * // 创建/销毁 V2LivePlayer 对象,以及回调事件监听。 * * import { V2LivePlayer } from 'trtc-electron-sdk'; * const livePlayer = V2LivePlayer.createV2LivePlayer(); * * subscribeEvents = (livePlayer) => { * livePlayer.on('onError', (errcode, errmsg) => { * console.info('livePlayer_demo: onError :' + errcode + " msg" + errmsg); * }); * }; * * V2LivePlayer.releaseV2livePlayer(livePlayer); * */ class V2LivePlayer { constructor() { this.livePlayer = new NodeTRTCEngine.NodeV2LivePlayer(); this.initObserver(); this.playerVideoRender = null; this.pixelFormat = live_define_1.V2LivePixelFormat.V2LivePixelFormatI420; this.eventEmitter = new events_1.EventEmitter(); this.logger = new logger_1.Logger(`V2LivePlayer`); this._playerVideoRenderCallback = this._playerVideoRenderCallback.bind(this); this._createPlayerRender(); } /** * 创建 V2LivePlayer 实例 * * @return {V2LivePlayer} - 播放器实例 */ static createV2LivePlayer() { return new V2LivePlayer(); } /** * 析构 V2LivePlayer 对象 * * @param {V2LivePlayer} livePlayer - 推流器实例 */ static releaseV2LivePlayer(livePlayer) { livePlayer.destroy(); } destroy() { this._destroyPlayerRender(); this.livePlayer.destroy(); this.livePlayer = null; } /** * 监听 LivePlayer 对象事件。 * * @param {V2LivePlayerEvent} event - 事件名称。 * @param {Function} listener - 事件回调函数。 */ on(event, listener) { this.eventEmitter.on(event, listener); } /** * 取消监听 LivePlayer 对象事件。 * * @param {V2LivePlayerEvent} event - 事件名称。 * @param {Function} listener - 事件回调函数。 */ off(event, listener) { this.eventEmitter.off(event, listener); } ///////////////////////////////////////////////////////////////////////////////// // // (一)LivePlayer相关接口函数 // ///////////////////////////////////////////////////////////////////////////////// /** * 设置播放器的视频渲染 View, 播放器的视频最终会显示到传入的 View 上。 * * @param {HTMLElement | null} view - 播放器的视频渲染 View。 */ setRenderView(view) { var _a; this.logger.debug(`setRenderView view:${view}`); (_a = this.playerVideoRender) === null || _a === void 0 ? void 0 : _a.setRenderView(view); } /** * 设置播放器画面的旋转角度, 默认不旋转。 * * @param {V2LiveRotation} rotation - 播放器画面的旋转角度, 参考 V2LiveRotation 的定义。 * @return {Number} - 参考 V2LiveCode 的定义 */ setRenderRotation(rotation) { var _a; this.logger.debug(`setRenderRotation rotation:${rotation}`); return (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.setRenderRotation(rotation); } /** * 设置画面的填充模式 * * @param {V2LiveFillMode} mode - 画面填充模式,参考 V2LiveFillMode 的定义。 * @return {Number} - 参考 V2LiveCode 的定义 */ setRenderFillMode(mode) { var _a, _b; this.logger.debug(`setRenderFillMode mode:${mode}`); (_a = this.playerVideoRender) === null || _a === void 0 ? void 0 : _a.setVideoFillMode((0, converter_1.convertFillModeFromLive)(mode)); return (_b = this.livePlayer) === null || _b === void 0 ? void 0 : _b.setRenderFillMode(mode); } /** * 开始播放音视频流 * * @param {String} url - 音视频流地址 * @return {Number} - 参考 V2LiveCode 的定义 */ startPlay(url) { var _a, _b; this.logger.debug(`startPlay url:${url}`); (_a = this.playerVideoRender) === null || _a === void 0 ? void 0 : _a.createRender(); this._setVideoRenderBuffer(); this._addVideoRenderCallback(); this.enableObserveVideoFrame(true, this.pixelFormat, live_define_1.V2LiveBufferType.V2LiveBufferTypeByteBuffer); return (_b = this.livePlayer) === null || _b === void 0 ? void 0 : _b.startPlay(url); } /** * 停止播放音视频流 * * @return {Number} - 参考 V2LiveCode 的定义 */ stopPlay() { var _a, _b; this.logger.debug(`stopPlay`); (_a = this.playerVideoRender) === null || _a === void 0 ? void 0 : _a.destroyRender(); this._removeVideoRenderCallback(); this.enableObserveVideoFrame(false, this.pixelFormat, live_define_1.V2LiveBufferType.V2LiveBufferTypeByteBuffer); return (_b = this.livePlayer) === null || _b === void 0 ? void 0 : _b.stopPlay(); } /** * 播放器是否正在播放中 * * @return {Number} - 是否正在播放中, 1 表示正在播放中, 0 表示未在播放中 */ isPlaying() { var _a; this.logger.debug(`isPlaying`); return (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.isPlaying(); } /** * 暂停播放器的音频流 * * @return {Number} - 参考 V2LiveCode 的定义 */ pauseAudio() { var _a; this.logger.debug(`pauseAudio`); return (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.pauseAudio(); } /** * 恢复播放器的音频流 * * @return {Number} - 参考 V2LiveCode 的定义 */ resumeAudio() { var _a; this.logger.debug(`resumeAudio`); return (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.resumeAudio(); } /** * 暂停播放器的视频流 * * @return {Number} - 参考 V2LiveCode 的定义 */ pauseVideo() { var _a; this.logger.debug(`pauseVideo`); return (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.pauseVideo(); } /** * 恢复播放器的视频流 * * @return {Number} - 参考 V2LiveCode 的定义 */ resumeVideo() { var _a; this.logger.debug(`resumeVideo`); return (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.resumeVideo(); } /** * 设置播放器音量 * * @param {Number} volume - 音量大小,取值范围0 - 100。【默认值】: 100 * @return {Number} - 参考 V2LiveCode 的定义 */ setPlayoutVolume(volume) { var _a; this.logger.debug(`setPlayoutVolume volume:${volume}`); return (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.setPlayoutVolume(volume); } /** * 设置播放器缓存自动调整的最小和最大时间 * * @param {Number} minTime - 缓存自动调整的最小时间,取值需要大于0。【默认值】:1 * @param {Number} maxTime - 缓存自动调整的最大时间,取值需要大于0。【默认值】:5 * @return {Number} - 参考 V2LiveCode 的定义 */ setCacheParams(minTime, maxTime) { var _a; this.logger.debug(`setCacheParams minTime:${minTime}, maxTime:${maxTime}`); return (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.setCacheParams(minTime, maxTime); } /** * 直播流无缝切换,支持 FLV 和 LEB * * @param {String} url - 新的拉流地址 * @return {Number} - 参考 V2LiveCode 的定义 */ switchStream(newUrl) { var _a; this.logger.debug(`switchStream newUrl:${newUrl}`); return (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.switchStream(newUrl); } /** * 启用播放音量大小提示 * * @param {Number} intervalMs - onPlayoutVolumeUpdate 回调的触发间隔,单位为ms,最小间隔为100ms,如果小于等于0则会关闭回调,建议设置为300ms;【默认值】:0,不开启。 * @return {Number} - 参考 V2LiveCode 的定义 */ enableVolumeEvaluation(intervalMs) { var _a; this.logger.debug(`enableVolumeEvaluation intervalMs:${intervalMs}`); return (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.enableVolumeEvaluation(intervalMs); } //////////////////////////////////////////////////////////////////////////////// // // 内部接口 // //////////////////////////////////////////////////////////////////////////////// enableObserveVideoFrame(enable, pixelFormat, bufferType) { var _a; this.logger.debug(`enableObserveVideoFrame enable:${enable}, pixelFormat:${pixelFormat}, bufferType:${bufferType}`); (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.enableObserveVideoFrame(enable, pixelFormat, bufferType); } _createPlayerRender() { if (this.playerVideoRender !== null) { return; } this.playerVideoRender = new video_render_1.VideoRender(); const trtcPixelFormat = (0, converter_1.convertPixelFormatFromLive)(this.pixelFormat); this.playerVideoRender.setVideoPixelFormat(trtcPixelFormat); } _destroyPlayerRender() { if (this.playerVideoRender) { this.playerVideoRender.destroy(); this.playerVideoRender = null; } this._removeVideoRenderCallback(); this.enableObserveVideoFrame(false, this.pixelFormat, live_define_1.V2LiveBufferType.V2LiveBufferTypeByteBuffer); } _setVideoRenderBuffer() { var _a; if (this.playerVideoRender !== null) { const videoBuffer = this.playerVideoRender.getVideoBuffer(); (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.setVideoRenderBuffer(videoBuffer.buffer, videoBuffer.width, videoBuffer.height, this.pixelFormat, videoBuffer.id); } } _addVideoRenderCallback() { var _a; (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.addVideoRenderCallback(this._playerVideoRenderCallback); } _removeVideoRenderCallback() { var _a; (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.removeVideoRenderCallback(); } _playerVideoRenderCallback(args) { if (this.playerVideoRender) { const [userId, type, width, height, timestamp, rotation, valid, bufferId] = args; const result = this.playerVideoRender.renderVideoData(userId, type, width, height, timestamp, rotation, valid, bufferId); if (!result) { this._setVideoRenderBuffer(); } } } initObserver() { var _a; (_a = this.livePlayer) === null || _a === void 0 ? void 0 : _a.setObserver((args) => { const key = args[0]; const data = args[1]; switch (key) { case 'onError': this.handleOnError(data.errCode, data.errMsg); break; case 'onWarning': this.handleOnWarning(data.warningCode, data.warningMsg); break; case 'onVideoResolutionChanged': this.handleOnVideoResolutionChanged(data.width, data.height); break; case 'onConnected': this.handleOnConnected(); break; case 'onVideoPlaying': this.handleOnVideoPlaying(data.firstPlay); break; case 'onAudioPlaying': this.handleOnAudioPlaying(data.firstPlay); break; case 'onVideoLoading': this.handleOnVideoLoading(); break; case 'onAudioLoading': this.handleOnAudioLoading(); break; case 'onPlayoutVolumeUpdate': this.handleOnPlayoutVolumeUpdate(data.volume); break; case 'onStatisticsUpdate': this.handleOnStatisticsUpdate(data.statistics); break; case 'onStreamSwitched': this.handleOnStreamSwitched(data.url, data.code); break; default: this.logger.error(`unknown event: ${key}`); break; } }); } // Event Handler define fire(event, ...args) { setImmediate(() => { var _a; (_a = this.eventEmitter) === null || _a === void 0 ? void 0 : _a.emit(event, ...args); }); } handleOnError(errCode, errMsg) { this.fire('onError', errCode, errMsg); } handleOnWarning(warningCode, warningMsg) { this.fire('onWarning', warningCode, warningMsg); } handleOnVideoResolutionChanged(width, height) { this.fire('onVideoResolutionChanged', width, height); } handleOnConnected() { this.fire('onConnected'); } handleOnVideoPlaying(firstPlay) { this.fire('onVideoPlaying', firstPlay); } handleOnAudioPlaying(firstPlay) { this.fire('onAudioPlaying', firstPlay); } handleOnVideoLoading() { this.fire('onVideoLoading'); } handleOnAudioLoading() { this.fire('onAudioLoading'); } handleOnPlayoutVolumeUpdate(volume) { this.fire('onPlayoutVolumeUpdate', volume); } handleOnStatisticsUpdate(statistics) { this.fire('onStatisticsUpdate', statistics); } handleOnStreamSwitched(url, code) { this.fire('onStreamSwitched', url, code); } } exports.V2LivePlayer = V2LivePlayer;