trtc-electron-sdk 13.2.709-beta.0 → 13.3.800-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/liteav/Live/video-render.js +15 -1
- package/liteav/Renderer/VideoRenderer/index.js +6 -1
- package/liteav/index.d.ts +1 -0
- package/liteav/index.js +1 -0
- package/liteav/trtc.d.ts +2 -0
- package/liteav/trtc.js +2 -0
- package/liteav/vod_player.d.ts +212 -0
- package/liteav/vod_player.js +470 -0
- package/package.json +1 -1
|
@@ -51,7 +51,19 @@ class VideoRender {
|
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
this.pixelFormat = format;
|
|
54
|
-
|
|
54
|
+
const newLength = this.pixelFormat === trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_I420 ? 1.5 : 4;
|
|
55
|
+
if (this.pixelLength !== newLength) {
|
|
56
|
+
this.pixelLength = newLength;
|
|
57
|
+
this.videoBuffer.pixelFormat = this.pixelFormat;
|
|
58
|
+
this.videoBuffer.buffer = null;
|
|
59
|
+
this.videoBuffer.buffer = (0, util_1.allocBuffer)(this.videoBuffer.width * this.videoBuffer.height * this.pixelLength);
|
|
60
|
+
this.videoBuffer.id = (0, util_1.generateUniqueId)();
|
|
61
|
+
}
|
|
62
|
+
// 像素格式变更后重建渲染器,确保渲染器与数据格式匹配
|
|
63
|
+
if (this.videoRender !== null) {
|
|
64
|
+
this.destroyRender();
|
|
65
|
+
this.createRender();
|
|
66
|
+
}
|
|
55
67
|
}
|
|
56
68
|
setUserId(userId) {
|
|
57
69
|
this.videoBuffer.userId = userId;
|
|
@@ -85,7 +97,9 @@ class VideoRender {
|
|
|
85
97
|
this.videoBuffer.buffer = null;
|
|
86
98
|
this.videoBuffer.width = width;
|
|
87
99
|
this.videoBuffer.height = height;
|
|
100
|
+
this.videoBuffer.pixelFormat = this.pixelFormat;
|
|
88
101
|
this.videoBuffer.buffer = (0, util_1.allocBuffer)(this.videoBuffer.width * this.videoBuffer.height * this.pixelLength);
|
|
102
|
+
this.videoBuffer.id = (0, util_1.generateUniqueId)();
|
|
89
103
|
}
|
|
90
104
|
}
|
|
91
105
|
}
|
|
@@ -106,7 +106,12 @@ class VideoRenderer {
|
|
|
106
106
|
codedHeight: frameData.height,
|
|
107
107
|
timestamp: frameData.timestamp,
|
|
108
108
|
});
|
|
109
|
-
|
|
109
|
+
try {
|
|
110
|
+
yield this.writer.write(vf);
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
vf.close();
|
|
114
|
+
}
|
|
110
115
|
}
|
|
111
116
|
else {
|
|
112
117
|
throw new Error('renderer container element is null');
|
package/liteav/index.d.ts
CHANGED
package/liteav/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
15
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
16
|
__exportStar(require("./trtc_define"), exports);
|
|
17
17
|
__exportStar(require("./trtc_code"), exports);
|
|
18
|
+
__exportStar(require("./vod_player"), exports);
|
|
18
19
|
__exportStar(require("./extensions/DeviceManager"), exports);
|
|
19
20
|
__exportStar(require("./extensions/AudioEffectManager"), exports);
|
|
20
21
|
__exportStar(require("./extensions/MediaMixingManager"), exports);
|
package/liteav/trtc.d.ts
CHANGED
|
@@ -2345,6 +2345,7 @@ declare class TRTCCloud extends EventEmitter implements ITRTCCloud {
|
|
|
2345
2345
|
*
|
|
2346
2346
|
* - 调用 `setLocalVideoRenderCallback(TRTCVideoPixelFormat_Unknown, TRTCVideoBufferType_Unknown, null)` 可停止自定义渲染回调,恢复 SDK 内置渲染。
|
|
2347
2347
|
* - Electron 平台仅支持回调 `TRTCVideoPixelFormat_I420` 像素格式的视频帧。
|
|
2348
|
+
* @version v13.1.709
|
|
2348
2349
|
*
|
|
2349
2350
|
* @param {TRTCVideoPixelFormat} pixelFormat - 指定回调的像素格式
|
|
2350
2351
|
* @param {TRTCVideoBufferType} bufferType - 指定视频数据结构类型
|
|
@@ -2368,6 +2369,7 @@ declare class TRTCCloud extends EventEmitter implements ITRTCCloud {
|
|
|
2368
2369
|
*
|
|
2369
2370
|
* - 调用 `setRemoteVideoRenderCallback(userId, TRTCVideoPixelFormat_Unknown, TRTCVideoBufferType_Unknown, null)` 可停止自定义渲染回调,恢复 SDK 内置渲染。
|
|
2370
2371
|
* - Electron 平台仅支持回调 `TRTCVideoPixelFormat_I420` 像素格式的视频帧。
|
|
2372
|
+
* @version v13.1.709
|
|
2371
2373
|
*
|
|
2372
2374
|
* @param {string} userId - 远端用户标识
|
|
2373
2375
|
* @param {TRTCVideoPixelFormat} pixelFormat - 指定回调的像素格式
|
package/liteav/trtc.js
CHANGED
|
@@ -3983,6 +3983,7 @@ class TRTCCloud extends events_1.EventEmitter {
|
|
|
3983
3983
|
*
|
|
3984
3984
|
* - 调用 `setLocalVideoRenderCallback(TRTCVideoPixelFormat_Unknown, TRTCVideoBufferType_Unknown, null)` 可停止自定义渲染回调,恢复 SDK 内置渲染。
|
|
3985
3985
|
* - Electron 平台仅支持回调 `TRTCVideoPixelFormat_I420` 像素格式的视频帧。
|
|
3986
|
+
* @version v13.1.709
|
|
3986
3987
|
*
|
|
3987
3988
|
* @param {TRTCVideoPixelFormat} pixelFormat - 指定回调的像素格式
|
|
3988
3989
|
* @param {TRTCVideoBufferType} bufferType - 指定视频数据结构类型
|
|
@@ -4040,6 +4041,7 @@ class TRTCCloud extends events_1.EventEmitter {
|
|
|
4040
4041
|
*
|
|
4041
4042
|
* - 调用 `setRemoteVideoRenderCallback(userId, TRTCVideoPixelFormat_Unknown, TRTCVideoBufferType_Unknown, null)` 可停止自定义渲染回调,恢复 SDK 内置渲染。
|
|
4042
4043
|
* - Electron 平台仅支持回调 `TRTCVideoPixelFormat_I420` 像素格式的视频帧。
|
|
4044
|
+
* @version v13.1.709
|
|
4043
4045
|
*
|
|
4044
4046
|
* @param {string} userId - 远端用户标识
|
|
4045
4047
|
* @param {TRTCVideoPixelFormat} pixelFormat - 指定回调的像素格式
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { TRTCVideoRotation, TRTCVideoFillMode } from './trtc_define';
|
|
2
|
+
/**
|
|
3
|
+
* VodPlayer 播放器事件枚举
|
|
4
|
+
*/
|
|
5
|
+
export declare enum VodPlayerEvents {
|
|
6
|
+
/** 播放开始,参数:msLength(总时长,毫秒) */
|
|
7
|
+
onVodPlayerStarted = "onVodPlayerStarted",
|
|
8
|
+
/** 播放进度更新,参数:msPos(当前进度,毫秒) */
|
|
9
|
+
onVodPlayerProgress = "onVodPlayerProgress",
|
|
10
|
+
/** 播放暂停 */
|
|
11
|
+
onVodPlayerPaused = "onVodPlayerPaused",
|
|
12
|
+
/** 播放恢复 */
|
|
13
|
+
onVodPlayerResumed = "onVodPlayerResumed",
|
|
14
|
+
/** 播放停止,参数:reason(0=用户主动停止,1=文件播放完,2=视频断流) */
|
|
15
|
+
onVodPlayerStopped = "onVodPlayerStopped",
|
|
16
|
+
/** 播放错误,参数:error(错误码) */
|
|
17
|
+
onVodPlayerError = "onVodPlayerError"
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* VodPlayer 事件与回调参数的类型映射
|
|
21
|
+
*
|
|
22
|
+
* 用于 on/off 方法的类型约束,使事件名和回调参数在编译期匹配。
|
|
23
|
+
*/
|
|
24
|
+
export interface VodPlayerEventMap {
|
|
25
|
+
[VodPlayerEvents.onVodPlayerStarted]: [msLength: number];
|
|
26
|
+
[VodPlayerEvents.onVodPlayerProgress]: [msPos: number];
|
|
27
|
+
[VodPlayerEvents.onVodPlayerPaused]: [];
|
|
28
|
+
[VodPlayerEvents.onVodPlayerResumed]: [];
|
|
29
|
+
[VodPlayerEvents.onVodPlayerStopped]: [reason: number];
|
|
30
|
+
[VodPlayerEvents.onVodPlayerError]: [error: number];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* 腾讯云点播播放器
|
|
35
|
+
*
|
|
36
|
+
* 用于播放本地或在线的音视频文件,支持视频渲染、音量控制、
|
|
37
|
+
* 进度控制、TRTC 推流等功能。
|
|
38
|
+
*
|
|
39
|
+
* @version v13.4.800
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* import { VodPlayer, VodPlayerEvents } from 'trtc-electron-sdk';
|
|
43
|
+
*
|
|
44
|
+
* const player = VodPlayer.createVodPlayer('/path/to/video.mp4', false);
|
|
45
|
+
* player.on(VodPlayerEvents.onVodPlayerStarted, (msLength) => {
|
|
46
|
+
* console.log('播放开始,总时长:', msLength);
|
|
47
|
+
* });
|
|
48
|
+
* player.setView(document.getElementById('video-container')!);
|
|
49
|
+
* player.start();
|
|
50
|
+
*
|
|
51
|
+
* // 使用完毕后销毁
|
|
52
|
+
* VodPlayer.releaseVodPlayer(player);
|
|
53
|
+
*/
|
|
54
|
+
export declare class VodPlayer {
|
|
55
|
+
private nativeVodPlayer;
|
|
56
|
+
private videoRender;
|
|
57
|
+
private mediaFilePath;
|
|
58
|
+
private repeat;
|
|
59
|
+
private isStarted;
|
|
60
|
+
private isDestroyed;
|
|
61
|
+
private logger;
|
|
62
|
+
private eventEmitter;
|
|
63
|
+
/**
|
|
64
|
+
* 创建 VodPlayer 实例
|
|
65
|
+
*
|
|
66
|
+
* @param mediaFilePath - 媒体文件路径(本地路径或在线 URL)
|
|
67
|
+
* @param repeat - 是否循环播放,默认 false
|
|
68
|
+
* @returns VodPlayer 实例
|
|
69
|
+
*/
|
|
70
|
+
static createVodPlayer(mediaFilePath: string, repeat?: boolean): VodPlayer;
|
|
71
|
+
/**
|
|
72
|
+
* 销毁 VodPlayer 实例,释放相关资源
|
|
73
|
+
*
|
|
74
|
+
* @param player - 待销毁的 VodPlayer 实例
|
|
75
|
+
*/
|
|
76
|
+
static releaseVodPlayer(player: VodPlayer): void;
|
|
77
|
+
private constructor();
|
|
78
|
+
/**
|
|
79
|
+
* 销毁播放器,释放所有资源
|
|
80
|
+
*
|
|
81
|
+
* 包括:停止播放、销毁渲染器、移除所有事件监听
|
|
82
|
+
*/
|
|
83
|
+
destroy(): void;
|
|
84
|
+
/**
|
|
85
|
+
* 监听 VodPlayer 事件
|
|
86
|
+
*
|
|
87
|
+
* @param event - 事件名称,参考 {@link VodPlayerEvents}
|
|
88
|
+
* @param listener - 事件回调函数,参数类型根据事件自动推导
|
|
89
|
+
*/
|
|
90
|
+
on<K extends keyof VodPlayerEventMap>(event: K, listener: (...args: VodPlayerEventMap[K]) => void): this;
|
|
91
|
+
on(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
92
|
+
/**
|
|
93
|
+
* 取消监听 VodPlayer 事件
|
|
94
|
+
*
|
|
95
|
+
* @param event - 事件名称
|
|
96
|
+
* @param listener - 事件回调函数
|
|
97
|
+
*/
|
|
98
|
+
off<K extends keyof VodPlayerEventMap>(event: K, listener: (...args: VodPlayerEventMap[K]) => void): this;
|
|
99
|
+
off(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
100
|
+
/**
|
|
101
|
+
* 设置视频渲染的 DOM 容器
|
|
102
|
+
*
|
|
103
|
+
* @param view - HTML 元素,用于承载视频画面
|
|
104
|
+
*/
|
|
105
|
+
setView(view: HTMLElement | null): void;
|
|
106
|
+
/**
|
|
107
|
+
* 开始播放
|
|
108
|
+
*
|
|
109
|
+
*/
|
|
110
|
+
start(): void;
|
|
111
|
+
/**
|
|
112
|
+
* 停止播放
|
|
113
|
+
*
|
|
114
|
+
*/
|
|
115
|
+
stop(): void;
|
|
116
|
+
/**
|
|
117
|
+
* 暂停播放
|
|
118
|
+
*/
|
|
119
|
+
pause(): void;
|
|
120
|
+
/**
|
|
121
|
+
* 恢复播放
|
|
122
|
+
*/
|
|
123
|
+
resume(): void;
|
|
124
|
+
/**
|
|
125
|
+
* 跳转到指定播放位置
|
|
126
|
+
*
|
|
127
|
+
* @param msPos - 目标位置,单位毫秒
|
|
128
|
+
*/
|
|
129
|
+
seek(msPos: number): void;
|
|
130
|
+
/**
|
|
131
|
+
* 获取媒体文件总时长
|
|
132
|
+
*
|
|
133
|
+
* @returns 总时长,单位毫秒
|
|
134
|
+
*/
|
|
135
|
+
getDuration(): number;
|
|
136
|
+
/**
|
|
137
|
+
* 获取视频宽度
|
|
138
|
+
*
|
|
139
|
+
* @returns 视频宽度(像素)
|
|
140
|
+
*/
|
|
141
|
+
getWidth(): number;
|
|
142
|
+
/**
|
|
143
|
+
* 获取视频高度
|
|
144
|
+
*
|
|
145
|
+
* @returns 视频高度(像素)
|
|
146
|
+
*/
|
|
147
|
+
getHeight(): number;
|
|
148
|
+
/**
|
|
149
|
+
* 设置画面旋转角度
|
|
150
|
+
*
|
|
151
|
+
* @param rotation - 旋转角度,参考 TRTCVideoRotation 枚举
|
|
152
|
+
*/
|
|
153
|
+
setRenderRotation(rotation: TRTCVideoRotation): void;
|
|
154
|
+
/**
|
|
155
|
+
* 设置画面填充模式
|
|
156
|
+
*
|
|
157
|
+
* @param mode - 填充模式,参考 TRTCVideoFillMode 枚举
|
|
158
|
+
*/
|
|
159
|
+
setFillMode(mode: TRTCVideoFillMode): void;
|
|
160
|
+
/**
|
|
161
|
+
* 设置画面镜像
|
|
162
|
+
*
|
|
163
|
+
* @param mirror - 是否镜像
|
|
164
|
+
*/
|
|
165
|
+
setMirror(mirror: boolean): void;
|
|
166
|
+
/**
|
|
167
|
+
* 静音 / 取消静音
|
|
168
|
+
*
|
|
169
|
+
* @param mute - 是否静音
|
|
170
|
+
*/
|
|
171
|
+
mute(mute: boolean): void;
|
|
172
|
+
/**
|
|
173
|
+
* 设置播放音量
|
|
174
|
+
*
|
|
175
|
+
* @param volume - 音量大小,取值范围 0-100
|
|
176
|
+
*/
|
|
177
|
+
setVolume(volume: number): void;
|
|
178
|
+
/**
|
|
179
|
+
* 开始推送视频流到 TRTC
|
|
180
|
+
*/
|
|
181
|
+
publishVideo(): void;
|
|
182
|
+
/**
|
|
183
|
+
* 开始推送音频流到 TRTC
|
|
184
|
+
*/
|
|
185
|
+
publishAudio(): void;
|
|
186
|
+
/**
|
|
187
|
+
* 停止推送视频流到 TRTC
|
|
188
|
+
*/
|
|
189
|
+
unpublishVideo(): void;
|
|
190
|
+
/**
|
|
191
|
+
* 停止推送音频流到 TRTC
|
|
192
|
+
*/
|
|
193
|
+
unpublishAudio(): void;
|
|
194
|
+
/**
|
|
195
|
+
* @private
|
|
196
|
+
* 将点播播放器关联到 TRTC 实例(用于推流)
|
|
197
|
+
*/
|
|
198
|
+
private attachTRTC;
|
|
199
|
+
/**
|
|
200
|
+
* @private
|
|
201
|
+
* 将点播播放器从 TRTC 实例分离
|
|
202
|
+
*/
|
|
203
|
+
private detachTRTC;
|
|
204
|
+
private fire;
|
|
205
|
+
private _createVideoRender;
|
|
206
|
+
private _destroyVideoRender;
|
|
207
|
+
private _setVideoRenderBuffer;
|
|
208
|
+
private _addDataRenderCallback;
|
|
209
|
+
private _removeDataRenderCallback;
|
|
210
|
+
private _dataRenderCallback;
|
|
211
|
+
private _initEventCallback;
|
|
212
|
+
}
|
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VodPlayer = exports.VodPlayerEvents = void 0;
|
|
4
|
+
const events_1 = require("events");
|
|
5
|
+
const trtc_define_1 = require("./trtc_define");
|
|
6
|
+
const video_render_1 = require("./Live/video-render");
|
|
7
|
+
const logger_1 = require("./logger");
|
|
8
|
+
const NodeTRTCEngine = require('../build/Release/trtc_electron_sdk.node');
|
|
9
|
+
/**
|
|
10
|
+
* VodPlayer 播放器事件枚举
|
|
11
|
+
*/
|
|
12
|
+
var VodPlayerEvents;
|
|
13
|
+
(function (VodPlayerEvents) {
|
|
14
|
+
/** 播放开始,参数:msLength(总时长,毫秒) */
|
|
15
|
+
VodPlayerEvents["onVodPlayerStarted"] = "onVodPlayerStarted";
|
|
16
|
+
/** 播放进度更新,参数:msPos(当前进度,毫秒) */
|
|
17
|
+
VodPlayerEvents["onVodPlayerProgress"] = "onVodPlayerProgress";
|
|
18
|
+
/** 播放暂停 */
|
|
19
|
+
VodPlayerEvents["onVodPlayerPaused"] = "onVodPlayerPaused";
|
|
20
|
+
/** 播放恢复 */
|
|
21
|
+
VodPlayerEvents["onVodPlayerResumed"] = "onVodPlayerResumed";
|
|
22
|
+
/** 播放停止,参数:reason(0=用户主动停止,1=文件播放完,2=视频断流) */
|
|
23
|
+
VodPlayerEvents["onVodPlayerStopped"] = "onVodPlayerStopped";
|
|
24
|
+
/** 播放错误,参数:error(错误码) */
|
|
25
|
+
VodPlayerEvents["onVodPlayerError"] = "onVodPlayerError";
|
|
26
|
+
})(VodPlayerEvents = exports.VodPlayerEvents || (exports.VodPlayerEvents = {}));
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* 腾讯云点播播放器
|
|
30
|
+
*
|
|
31
|
+
* 用于播放本地或在线的音视频文件,支持视频渲染、音量控制、
|
|
32
|
+
* 进度控制、TRTC 推流等功能。
|
|
33
|
+
*
|
|
34
|
+
* @version v13.4.800
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* import { VodPlayer, VodPlayerEvents } from 'trtc-electron-sdk';
|
|
38
|
+
*
|
|
39
|
+
* const player = VodPlayer.createVodPlayer('/path/to/video.mp4', false);
|
|
40
|
+
* player.on(VodPlayerEvents.onVodPlayerStarted, (msLength) => {
|
|
41
|
+
* console.log('播放开始,总时长:', msLength);
|
|
42
|
+
* });
|
|
43
|
+
* player.setView(document.getElementById('video-container')!);
|
|
44
|
+
* player.start();
|
|
45
|
+
*
|
|
46
|
+
* // 使用完毕后销毁
|
|
47
|
+
* VodPlayer.releaseVodPlayer(player);
|
|
48
|
+
*/
|
|
49
|
+
class VodPlayer {
|
|
50
|
+
// ─── 构造函数 ───────────────────────────────────────────────
|
|
51
|
+
constructor(mediaFilePath, repeat = false) {
|
|
52
|
+
this.logger = new logger_1.Logger('VodPlayer');
|
|
53
|
+
this.eventEmitter = new events_1.EventEmitter();
|
|
54
|
+
this._dataRenderCallback = this._dataRenderCallback.bind(this);
|
|
55
|
+
this.nativeVodPlayer = new NodeTRTCEngine.NodeVodPlayer(mediaFilePath, repeat);
|
|
56
|
+
this.mediaFilePath = mediaFilePath;
|
|
57
|
+
this.repeat = repeat;
|
|
58
|
+
this.isStarted = false;
|
|
59
|
+
this.isDestroyed = false;
|
|
60
|
+
this.videoRender = null;
|
|
61
|
+
this._createVideoRender();
|
|
62
|
+
this._initEventCallback();
|
|
63
|
+
}
|
|
64
|
+
// ─── 静态工厂方法 ───────────────────────────────────────────
|
|
65
|
+
/**
|
|
66
|
+
* 创建 VodPlayer 实例
|
|
67
|
+
*
|
|
68
|
+
* @param mediaFilePath - 媒体文件路径(本地路径或在线 URL)
|
|
69
|
+
* @param repeat - 是否循环播放,默认 false
|
|
70
|
+
* @returns VodPlayer 实例
|
|
71
|
+
*/
|
|
72
|
+
static createVodPlayer(mediaFilePath, repeat = false) {
|
|
73
|
+
return new VodPlayer(mediaFilePath, repeat);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 销毁 VodPlayer 实例,释放相关资源
|
|
77
|
+
*
|
|
78
|
+
* @param player - 待销毁的 VodPlayer 实例
|
|
79
|
+
*/
|
|
80
|
+
static releaseVodPlayer(player) {
|
|
81
|
+
player.destroy();
|
|
82
|
+
}
|
|
83
|
+
// ─── 公开方法 ───────────────────────────────────────────────
|
|
84
|
+
/**
|
|
85
|
+
* 销毁播放器,释放所有资源
|
|
86
|
+
*
|
|
87
|
+
* 包括:停止播放、销毁渲染器、移除所有事件监听
|
|
88
|
+
*/
|
|
89
|
+
destroy() {
|
|
90
|
+
var _a, _b;
|
|
91
|
+
if (this.isDestroyed) {
|
|
92
|
+
this.logger.warn('destroy: player already destroyed');
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
this.logger.info('destroy');
|
|
96
|
+
this.stop();
|
|
97
|
+
this.isDestroyed = true;
|
|
98
|
+
this._destroyVideoRender();
|
|
99
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.setEventCallback(null);
|
|
100
|
+
(_b = this.nativeVodPlayer) === null || _b === void 0 ? void 0 : _b.setDataCallback(null);
|
|
101
|
+
this.nativeVodPlayer = null;
|
|
102
|
+
this.eventEmitter.removeAllListeners();
|
|
103
|
+
}
|
|
104
|
+
on(event, listener) {
|
|
105
|
+
this.eventEmitter.on(event, listener);
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
off(event, listener) {
|
|
109
|
+
this.eventEmitter.off(event, listener);
|
|
110
|
+
return this;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 设置视频渲染的 DOM 容器
|
|
114
|
+
*
|
|
115
|
+
* @param view - HTML 元素,用于承载视频画面
|
|
116
|
+
*/
|
|
117
|
+
setView(view) {
|
|
118
|
+
var _a;
|
|
119
|
+
if (this.isDestroyed) {
|
|
120
|
+
this.logger.warn('setView: player already destroyed');
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this.logger.info(`setView view: ${view}`);
|
|
124
|
+
(_a = this.videoRender) === null || _a === void 0 ? void 0 : _a.setRenderView(view);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* 开始播放
|
|
128
|
+
*
|
|
129
|
+
*/
|
|
130
|
+
start() {
|
|
131
|
+
var _a, _b;
|
|
132
|
+
if (this.isDestroyed) {
|
|
133
|
+
this.logger.warn('start: player already destroyed');
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
this.logger.info(`start mediaFile: ${this.mediaFilePath}`);
|
|
137
|
+
if (this.isStarted) {
|
|
138
|
+
this.logger.warn('start: already started, ignored');
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
(_a = this.videoRender) === null || _a === void 0 ? void 0 : _a.createRender();
|
|
142
|
+
this._setVideoRenderBuffer();
|
|
143
|
+
this._addDataRenderCallback();
|
|
144
|
+
this.attachTRTC();
|
|
145
|
+
(_b = this.nativeVodPlayer) === null || _b === void 0 ? void 0 : _b.start();
|
|
146
|
+
this.isStarted = true;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* 停止播放
|
|
150
|
+
*
|
|
151
|
+
*/
|
|
152
|
+
stop() {
|
|
153
|
+
var _a, _b;
|
|
154
|
+
if (this.isDestroyed) {
|
|
155
|
+
this.logger.warn('stop: player already destroyed');
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
this.logger.info('stop');
|
|
159
|
+
if (!this.isStarted) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
this.isStarted = false;
|
|
163
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.stop();
|
|
164
|
+
this.detachTRTC();
|
|
165
|
+
(_b = this.videoRender) === null || _b === void 0 ? void 0 : _b.destroyRender();
|
|
166
|
+
this._removeDataRenderCallback();
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* 暂停播放
|
|
170
|
+
*/
|
|
171
|
+
pause() {
|
|
172
|
+
var _a;
|
|
173
|
+
if (this.isDestroyed) {
|
|
174
|
+
this.logger.warn('pause: player already destroyed');
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
this.logger.info('pause');
|
|
178
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.pause();
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* 恢复播放
|
|
182
|
+
*/
|
|
183
|
+
resume() {
|
|
184
|
+
var _a;
|
|
185
|
+
if (this.isDestroyed) {
|
|
186
|
+
this.logger.warn('resume: player already destroyed');
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
this.logger.info('resume');
|
|
190
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.resume();
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* 跳转到指定播放位置
|
|
194
|
+
*
|
|
195
|
+
* @param msPos - 目标位置,单位毫秒
|
|
196
|
+
*/
|
|
197
|
+
seek(msPos) {
|
|
198
|
+
var _a;
|
|
199
|
+
if (this.isDestroyed) {
|
|
200
|
+
this.logger.warn('seek: player already destroyed');
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
this.logger.info(`seek msPos: ${msPos}`);
|
|
204
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.seek(msPos);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* 获取媒体文件总时长
|
|
208
|
+
*
|
|
209
|
+
* @returns 总时长,单位毫秒
|
|
210
|
+
*/
|
|
211
|
+
getDuration() {
|
|
212
|
+
var _a, _b;
|
|
213
|
+
if (this.isDestroyed) {
|
|
214
|
+
this.logger.warn('getDuration: player already destroyed');
|
|
215
|
+
return 0;
|
|
216
|
+
}
|
|
217
|
+
return (_b = (_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.getDuration()) !== null && _b !== void 0 ? _b : 0;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* 获取视频宽度
|
|
221
|
+
*
|
|
222
|
+
* @returns 视频宽度(像素)
|
|
223
|
+
*/
|
|
224
|
+
getWidth() {
|
|
225
|
+
var _a, _b;
|
|
226
|
+
if (this.isDestroyed) {
|
|
227
|
+
this.logger.warn('getWidth: player already destroyed');
|
|
228
|
+
return 0;
|
|
229
|
+
}
|
|
230
|
+
return (_b = (_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.getWidth()) !== null && _b !== void 0 ? _b : 0;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* 获取视频高度
|
|
234
|
+
*
|
|
235
|
+
* @returns 视频高度(像素)
|
|
236
|
+
*/
|
|
237
|
+
getHeight() {
|
|
238
|
+
var _a, _b;
|
|
239
|
+
if (this.isDestroyed) {
|
|
240
|
+
this.logger.warn('getHeight: player already destroyed');
|
|
241
|
+
return 0;
|
|
242
|
+
}
|
|
243
|
+
return (_b = (_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.getHeight()) !== null && _b !== void 0 ? _b : 0;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* 设置画面旋转角度
|
|
247
|
+
*
|
|
248
|
+
* @param rotation - 旋转角度,参考 TRTCVideoRotation 枚举
|
|
249
|
+
*/
|
|
250
|
+
setRenderRotation(rotation) {
|
|
251
|
+
var _a;
|
|
252
|
+
if (this.isDestroyed) {
|
|
253
|
+
this.logger.warn('setRenderRotation: player already destroyed');
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
this.logger.info(`setRenderRotation rotation: ${rotation}`);
|
|
257
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.setRenderRotation(rotation);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* 设置画面填充模式
|
|
261
|
+
*
|
|
262
|
+
* @param mode - 填充模式,参考 TRTCVideoFillMode 枚举
|
|
263
|
+
*/
|
|
264
|
+
setFillMode(mode) {
|
|
265
|
+
var _a, _b;
|
|
266
|
+
if (this.isDestroyed) {
|
|
267
|
+
this.logger.warn('setFillMode: player already destroyed');
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
this.logger.info(`setFillMode mode: ${mode}`);
|
|
271
|
+
(_a = this.videoRender) === null || _a === void 0 ? void 0 : _a.setVideoFillMode(mode);
|
|
272
|
+
(_b = this.nativeVodPlayer) === null || _b === void 0 ? void 0 : _b.setFillMode(mode);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* 设置画面镜像
|
|
276
|
+
*
|
|
277
|
+
* @param mirror - 是否镜像
|
|
278
|
+
*/
|
|
279
|
+
setMirror(mirror) {
|
|
280
|
+
var _a;
|
|
281
|
+
if (this.isDestroyed) {
|
|
282
|
+
this.logger.warn('setMirror: player already destroyed');
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
this.logger.info(`setMirror mirror: ${mirror}`);
|
|
286
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.setMirror(mirror);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* 静音 / 取消静音
|
|
290
|
+
*
|
|
291
|
+
* @param mute - 是否静音
|
|
292
|
+
*/
|
|
293
|
+
mute(mute) {
|
|
294
|
+
var _a;
|
|
295
|
+
if (this.isDestroyed) {
|
|
296
|
+
this.logger.warn('mute: player already destroyed');
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
this.logger.info(`mute: ${mute}`);
|
|
300
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.mute(mute);
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* 设置播放音量
|
|
304
|
+
*
|
|
305
|
+
* @param volume - 音量大小,取值范围 0-100
|
|
306
|
+
*/
|
|
307
|
+
setVolume(volume) {
|
|
308
|
+
var _a;
|
|
309
|
+
if (this.isDestroyed) {
|
|
310
|
+
this.logger.warn('setVolume: player already destroyed');
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
this.logger.info(`setVolume volume: ${volume}`);
|
|
314
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.setVolume(volume);
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* 开始推送视频流到 TRTC
|
|
318
|
+
*/
|
|
319
|
+
publishVideo() {
|
|
320
|
+
var _a;
|
|
321
|
+
if (this.isDestroyed) {
|
|
322
|
+
this.logger.warn('publishVideo: player already destroyed');
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
this.logger.info('publishVideo');
|
|
326
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.publishVideo();
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* 开始推送音频流到 TRTC
|
|
330
|
+
*/
|
|
331
|
+
publishAudio() {
|
|
332
|
+
var _a;
|
|
333
|
+
if (this.isDestroyed) {
|
|
334
|
+
this.logger.warn('publishAudio: player already destroyed');
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
this.logger.info('publishAudio');
|
|
338
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.publishAudio();
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* 停止推送视频流到 TRTC
|
|
342
|
+
*/
|
|
343
|
+
unpublishVideo() {
|
|
344
|
+
var _a;
|
|
345
|
+
if (this.isDestroyed) {
|
|
346
|
+
this.logger.warn('unpublishVideo: player already destroyed');
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
this.logger.info('unpublishVideo');
|
|
350
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.unpublishVideo();
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* 停止推送音频流到 TRTC
|
|
354
|
+
*/
|
|
355
|
+
unpublishAudio() {
|
|
356
|
+
var _a;
|
|
357
|
+
if (this.isDestroyed) {
|
|
358
|
+
this.logger.warn('unpublishAudio: player already destroyed');
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
this.logger.info('unpublishAudio');
|
|
362
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.unpublishAudio();
|
|
363
|
+
}
|
|
364
|
+
// ─── 内部方法 ───────────────────────────────────────────────
|
|
365
|
+
/**
|
|
366
|
+
* @private
|
|
367
|
+
* 将点播播放器关联到 TRTC 实例(用于推流)
|
|
368
|
+
*/
|
|
369
|
+
attachTRTC() {
|
|
370
|
+
var _a;
|
|
371
|
+
if (this.isDestroyed) {
|
|
372
|
+
this.logger.warn('attachTRTC: player already destroyed');
|
|
373
|
+
return;
|
|
374
|
+
}
|
|
375
|
+
this.logger.info('attachTRTC');
|
|
376
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.attachTRTC();
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* @private
|
|
380
|
+
* 将点播播放器从 TRTC 实例分离
|
|
381
|
+
*/
|
|
382
|
+
detachTRTC() {
|
|
383
|
+
var _a;
|
|
384
|
+
if (this.isDestroyed) {
|
|
385
|
+
this.logger.warn('detachTRTC: player already destroyed');
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
this.logger.info('detachTRTC');
|
|
389
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.detachTRTC();
|
|
390
|
+
}
|
|
391
|
+
fire(event, ...args) {
|
|
392
|
+
setImmediate(() => {
|
|
393
|
+
this.eventEmitter.emit(event, ...args);
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
_createVideoRender() {
|
|
397
|
+
if (this.videoRender !== null) {
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
this.videoRender = new video_render_1.VideoRender();
|
|
401
|
+
this.videoRender.setVideoPixelFormat(trtc_define_1.TRTCVideoPixelFormat.TRTCVideoPixelFormat_BGRA32);
|
|
402
|
+
}
|
|
403
|
+
_destroyVideoRender() {
|
|
404
|
+
if (this.videoRender) {
|
|
405
|
+
this.videoRender.destroy();
|
|
406
|
+
this.videoRender = null;
|
|
407
|
+
}
|
|
408
|
+
this._removeDataRenderCallback();
|
|
409
|
+
}
|
|
410
|
+
_setVideoRenderBuffer() {
|
|
411
|
+
var _a;
|
|
412
|
+
if (this.videoRender !== null) {
|
|
413
|
+
const videoBuffer = this.videoRender.getVideoBuffer();
|
|
414
|
+
this.logger.info(`_setVideoRenderBuffer: userId=${videoBuffer.userId}, width=${videoBuffer.width}, height=${videoBuffer.height}, bufferId=${videoBuffer.id}, pixelFormat=${videoBuffer.pixelFormat}`);
|
|
415
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.setVideoBuffer(videoBuffer.userId || '', videoBuffer.buffer, videoBuffer.streamType, videoBuffer.width, videoBuffer.height, videoBuffer.pixelFormat, videoBuffer.id);
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
_addDataRenderCallback() {
|
|
419
|
+
var _a;
|
|
420
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.setDataCallback(this._dataRenderCallback);
|
|
421
|
+
}
|
|
422
|
+
_removeDataRenderCallback() {
|
|
423
|
+
var _a;
|
|
424
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.setDataCallback(null);
|
|
425
|
+
}
|
|
426
|
+
_dataRenderCallback(args) {
|
|
427
|
+
if (this.videoRender) {
|
|
428
|
+
const [userId, type, width, height, timestamp, rotation, valid, bufferId] = args;
|
|
429
|
+
const result = this.videoRender.renderVideoData(userId, type, width, height, timestamp, rotation, valid, bufferId);
|
|
430
|
+
if (!result) {
|
|
431
|
+
this.logger.info(`_dataRenderCallback: renderVideoData returned false, re-setting video buffer`);
|
|
432
|
+
this._setVideoRenderBuffer();
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
this.logger.warn('_dataRenderCallback: videoRender is null, frame dropped');
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
_initEventCallback() {
|
|
440
|
+
var _a;
|
|
441
|
+
(_a = this.nativeVodPlayer) === null || _a === void 0 ? void 0 : _a.setEventCallback((args) => {
|
|
442
|
+
const key = args[0];
|
|
443
|
+
const data = args[1];
|
|
444
|
+
switch (key) {
|
|
445
|
+
case VodPlayerEvents.onVodPlayerStarted:
|
|
446
|
+
this.fire(VodPlayerEvents.onVodPlayerStarted, data.msLength);
|
|
447
|
+
break;
|
|
448
|
+
case VodPlayerEvents.onVodPlayerProgress:
|
|
449
|
+
this.fire(VodPlayerEvents.onVodPlayerProgress, data.msPos);
|
|
450
|
+
break;
|
|
451
|
+
case VodPlayerEvents.onVodPlayerPaused:
|
|
452
|
+
this.fire(VodPlayerEvents.onVodPlayerPaused);
|
|
453
|
+
break;
|
|
454
|
+
case VodPlayerEvents.onVodPlayerResumed:
|
|
455
|
+
this.fire(VodPlayerEvents.onVodPlayerResumed);
|
|
456
|
+
break;
|
|
457
|
+
case VodPlayerEvents.onVodPlayerStopped:
|
|
458
|
+
this.fire(VodPlayerEvents.onVodPlayerStopped, data.reason);
|
|
459
|
+
break;
|
|
460
|
+
case VodPlayerEvents.onVodPlayerError:
|
|
461
|
+
this.fire(VodPlayerEvents.onVodPlayerError, data.error);
|
|
462
|
+
break;
|
|
463
|
+
default:
|
|
464
|
+
this.logger.warn(`unknown vod player event: ${key}`);
|
|
465
|
+
break;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
exports.VodPlayer = VodPlayer;
|