@havue/solutions 1.1.1 → 1.2.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.
Files changed (28) hide show
  1. package/bc-connect/__tests__/bc-connect.spec.ts +73 -0
  2. package/bc-connect/dist/bc-connect.mjs +89 -73
  3. package/bc-connect/dist/bc-connect.umd.js +89 -73
  4. package/bc-connect/dist/types/src/manager.d.ts +72 -62
  5. package/bc-connect/package.json +1 -1
  6. package/bc-connect/src/manager.ts +103 -78
  7. package/dist/solutions.full.js +156 -127
  8. package/dist/solutions.full.min.js +4 -4
  9. package/dist/solutions.full.min.js.map +1 -1
  10. package/dist/types/bc-connect/src/manager.d.ts +72 -62
  11. package/dist/types/ws-video-manager/src/loader/websocket-loader.d.ts +13 -10
  12. package/dist/types/ws-video-manager/src/manager/index.d.ts +54 -37
  13. package/dist/types/ws-video-manager/src/render/drawer.d.ts +7 -7
  14. package/dist/types/ws-video-manager/src/render/index.d.ts +35 -19
  15. package/package.json +4 -4
  16. package/vite.config.ts +1 -1
  17. package/ws-video-manager/dist/types/src/loader/websocket-loader.d.ts +13 -10
  18. package/ws-video-manager/dist/types/src/manager/index.d.ts +54 -37
  19. package/ws-video-manager/dist/types/src/render/drawer.d.ts +7 -7
  20. package/ws-video-manager/dist/types/src/render/index.d.ts +35 -19
  21. package/ws-video-manager/dist/ws-video-manager.mjs +67 -54
  22. package/ws-video-manager/dist/ws-video-manager.umd.js +67 -54
  23. package/ws-video-manager/package.json +1 -1
  24. package/ws-video-manager/src/loader/websocket-loader.ts +15 -11
  25. package/ws-video-manager/src/manager/index.ts +57 -40
  26. package/ws-video-manager/src/render/drawer.ts +22 -20
  27. package/ws-video-manager/src/render/index.ts +61 -27
  28. package/ws-video-manager/src/render/mp4box.ts +1 -1
@@ -15,21 +15,31 @@ import { CanvasDrawer } from '../render/drawer'
15
15
 
16
16
  // #region typedefine
17
17
  export type WsVideoManaCstorOptionType = {
18
- /** 预监流连接数量限制, 移动端默认10个,pc端默认32个 */
18
+ /**
19
+ * websocket流连接数量限制, 移动端默认10个,pc端默认32个
20
+ * Limit the number of websocket streaming connections to 10 by default for mobile and 32 by default for pc
21
+ */
19
22
  connectLimit?: number
20
- /** WebSocketLoader 实例配置 */
23
+ /** WebSocketLoader configuration */
21
24
  wsOptions?: WebSocketOptionsType
22
25
  /**
23
26
  * websocket重连时,重新解析视频编码方式,
24
27
  * 默认 true
28
+ *
29
+ * When the websocket reconnects, the video encoding is reparsed.
30
+ * The default is true
25
31
  */
26
32
  reparseMimeOnReconnect?: boolean
27
33
  /** Render 实例配置 */
28
34
  renderOptions?: Partial<RenderConstructorOptionType>
29
35
  /**
30
- * 是否使用WebGL,
31
- * 默认 false,
32
- * WebGL在不同游览器,以及受限于显存,不能同时创建过多WebGL上下文,一般8-16个 */
36
+ * 是否使用WebGL,默认 false
37
+ * WebGL在不同游览器,以及受限于显存,不能同时创建过多WebGL上下文,一般8-16个
38
+ *
39
+ * Whether to use WebGL, false by default,
40
+ * WebGL can not be created too many WebGL contexts at the same time in different browsers,
41
+ * and due to the limitations of video memory, usually 8-16 WebGL contexts
42
+ */
33
43
  useWebgl?: boolean
34
44
  }
35
45
 
@@ -44,11 +54,11 @@ const DEFAULT_OPTIONS: Required<WsVideoManaCstorOptionType> = Object.freeze({
44
54
  })
45
55
 
46
56
  type WsInfoType = {
47
- /** 需要绘制的canvas列表 */
57
+ /** 需要绘制的canvas map | canvas map to be drawn */
48
58
  canvasMap: Map<HTMLCanvasElement, CanvasDrawer>
49
- /** WebSocketLoader 实例 */
59
+ /** WebSocketLoader instance */
50
60
  socket: WebSocketLoader
51
- /** socket连接渲染render实例 */
61
+ /** Render instance */
52
62
  render: Render
53
63
  }
54
64
 
@@ -72,7 +82,7 @@ export const WsVideoManagerEventEnums = Object.assign({}, EventEnums, RenderEven
72
82
  // #endregion typedefine
73
83
 
74
84
  export class WsVideoManager extends EventBus<Events> {
75
- /** socket连接 渲染相关对应信息 */
85
+ /** socket相关信息map | map of socket information */
76
86
  private _wsInfoMap: Map<string, WsInfoType> = new Map()
77
87
 
78
88
  private _option: Required<WsVideoManaCstorOptionType> = DEFAULT_OPTIONS
@@ -116,8 +126,8 @@ export class WsVideoManager extends EventBus<Events> {
116
126
  }
117
127
 
118
128
  /**
119
- * 添加socket实例
120
- * @param url socket地址
129
+ * 添加socket连接 | Adding a socket connection
130
+ * @param url socket url
121
131
  * @returns
122
132
  */
123
133
  private _addSocket(url: string, renderOptions?: Partial<RenderConstructorOptionType>) {
@@ -148,9 +158,9 @@ export class WsVideoManager extends EventBus<Events> {
148
158
  }
149
159
 
150
160
  /**
151
- * 绑定render事件
152
- * @param url 连接地址
153
- * @param render Render实例
161
+ * 绑定render事件 | Binding the render event
162
+ * @param url 连接地址 | websocket url
163
+ * @param render Render instance
154
164
  */
155
165
  private _bindRenderEvent(url: string, render: Render) {
156
166
  render.on(RenderEventsEnum.AUDIO_STATE_CHANGE, (state) => {
@@ -165,8 +175,8 @@ export class WsVideoManager extends EventBus<Events> {
165
175
  }
166
176
 
167
177
  /**
168
- * 销毁socket实例
169
- * @param url socket地址
178
+ * Destroying the socket connect
179
+ * @param url socket url
170
180
  */
171
181
  private _removeSocket(url: string) {
172
182
  const wsInfo = this._wsInfoMap.get(url)
@@ -181,9 +191,9 @@ export class WsVideoManager extends EventBus<Events> {
181
191
  }
182
192
 
183
193
  /**
184
- * 绑定socket事件
185
- * @param url 连接地址
186
- * @param socket WebSocketLoader实例
194
+ * 绑定socket事件 | Binding socket events
195
+ * @param url websocket url
196
+ * @param socket WebSocketLoader instance
187
197
  */
188
198
  private _bindSocketEvent(socket: WebSocketLoader, render: Render, url: string) {
189
199
  socket.on('close', () => {
@@ -217,8 +227,8 @@ export class WsVideoManager extends EventBus<Events> {
217
227
  }
218
228
 
219
229
  /**
220
- * url对应的 socket实例是否已存在
221
- * @param url socket地址
230
+ * url对应的 socket实例是否已存在 | Whether the socket instance for the url already exists
231
+ * @param url websocket url
222
232
  * @returns boolean
223
233
  */
224
234
  private _isSocketExist(url: string): boolean {
@@ -227,8 +237,9 @@ export class WsVideoManager extends EventBus<Events> {
227
237
 
228
238
  /**
229
239
  * 添加url对应socket,以及需要绘制的canvas元素
230
- * @param canvas canvas元素
231
- * @param url socket url地址
240
+ * Add the socket for the url and the canvas element to draw
241
+ * @param canvas canvas
242
+ * @param url websocket url
232
243
  */
233
244
  public addCanvas(canvas: HTMLCanvasElement, url: string, renderOptions?: Partial<RenderConstructorOptionType>) {
234
245
  this._addSocket(url, renderOptions)
@@ -250,8 +261,8 @@ export class WsVideoManager extends EventBus<Events> {
250
261
  }
251
262
 
252
263
  /**
253
- * 初始化canvas背景
254
- * @param canvas canvas元素
264
+ * 初始化canvas背景 | Initialize the canvas background
265
+ * @param canvas canvas
255
266
  * @returns
256
267
  */
257
268
  // private _setupCanvas(canvas: HTMLCanvasElement) {
@@ -264,8 +275,8 @@ export class WsVideoManager extends EventBus<Events> {
264
275
  // }
265
276
 
266
277
  /**
267
- * 删除canvas元素
268
- * @param canvas canvas元素
278
+ * 删除canvas元素 || Remove the canvas element
279
+ * @param canvas canvas
269
280
  */
270
281
  public removeCanvas(canvas: HTMLCanvasElement) {
271
282
  const entries = this._wsInfoMap.entries()
@@ -284,8 +295,8 @@ export class WsVideoManager extends EventBus<Events> {
284
295
  }
285
296
 
286
297
  /**
287
- * 返回canvas是否已经添加过
288
- * @param canvas canvas元素
298
+ * 获取canvas是否已经添加过 | Gets whether the canvas has already been added
299
+ * @param canvas canvas
289
300
  * @returns boolean
290
301
  */
291
302
  public isCanvasExist(canvas: HTMLCanvasElement): boolean {
@@ -295,14 +306,14 @@ export class WsVideoManager extends EventBus<Events> {
295
306
  })
296
307
  }
297
308
 
298
- /** 设置全部render静音状态 */
309
+ /** 设置全部render静音状态 | Mute all render */
299
310
  public setAllVideoMutedState(muted: boolean) {
300
311
  this._wsInfoMap.forEach((wsInfo) => {
301
312
  wsInfo.render.muted = muted
302
313
  })
303
314
  }
304
315
 
305
- /** 更新单个render实例的配置 */
316
+ /** 更新单个render实例的配置 | Update the configuration of a single render instance */
306
317
  public updateRenderOptions(url: string, options?: Partial<RenderConstructorOptionType>) {
307
318
  if (options) {
308
319
  const wsInfo = this._wsInfoMap.get(url)
@@ -311,9 +322,9 @@ export class WsVideoManager extends EventBus<Events> {
311
322
  }
312
323
 
313
324
  /**
314
- * 设置单个render静音状态
325
+ * 设置单个render静音状态 | Set a single render to be silent
315
326
  * @param url
316
- * @param muted boolean 是否静音
327
+ * @param {boolean} muted 是否静音 | Muted or not
317
328
  */
318
329
  public setOneMutedState(url: string, muted: boolean) {
319
330
  const wsInfo = this._wsInfoMap.get(url)
@@ -325,7 +336,8 @@ export class WsVideoManager extends EventBus<Events> {
325
336
 
326
337
  /**
327
338
  * 获取url对应render video元素是否静音
328
- * @param url socket地址
339
+ * Gets whether the render video element of the url is muted
340
+ * @param url websocket url
329
341
  */
330
342
  public getOneMutedState(url: string) {
331
343
  const wsInfo = this._wsInfoMap.get(url)
@@ -337,7 +349,8 @@ export class WsVideoManager extends EventBus<Events> {
337
349
 
338
350
  /**
339
351
  * 单个解除静音,其他未静音的变成静音,只播放一个
340
- * @param url socket地址
352
+ * Unmute a single video and mute all other videos
353
+ * @param url websocket url
341
354
  */
342
355
  public playOneAudio(url: string) {
343
356
  this.setAllVideoMutedState(true)
@@ -346,6 +359,7 @@ export class WsVideoManager extends EventBus<Events> {
346
359
 
347
360
  /**
348
361
  * 设置单个render是否继续处理ws数据
362
+ * Sets whether a single render continues to process ws data
349
363
  * @param url
350
364
  */
351
365
  public setOneVideoPausedState(url: string, paused: boolean) {
@@ -356,7 +370,7 @@ export class WsVideoManager extends EventBus<Events> {
356
370
  wsInfo.render.paused = paused
357
371
  }
358
372
 
359
- /** 设置全部render是否继续处理ws数据 */
373
+ /** 设置全部render是否继续处理ws数据 | Sets whether all render continues to process ws data */
360
374
  public setAllVideoPausedState(paused: boolean) {
361
375
  this._wsInfoMap.forEach((wsInfo) => {
362
376
  wsInfo.render.paused = paused
@@ -364,8 +378,9 @@ export class WsVideoManager extends EventBus<Events> {
364
378
  }
365
379
 
366
380
  /**
367
- * 获取url对应render video元素是否继续播放
368
- * @param url socket地址
381
+ * 获取url对应render video元素的播放状态
382
+ * Get the playback status of the render video element corresponding to the url
383
+ * @param url websocket url
369
384
  */
370
385
  public getOneVideoPausedState(url: string) {
371
386
  const wsInfo = this._wsInfoMap.get(url)
@@ -377,7 +392,8 @@ export class WsVideoManager extends EventBus<Events> {
377
392
 
378
393
  /**
379
394
  * 单个视频继续播放,其他暂停处理数据
380
- * @param url socket地址
395
+ * A single video continues to play while others pause to process data
396
+ * @param url websocket url
381
397
  */
382
398
  public playOneVideo(url: string) {
383
399
  this.setAllVideoPausedState(true)
@@ -386,6 +402,7 @@ export class WsVideoManager extends EventBus<Events> {
386
402
 
387
403
  /**
388
404
  * 刷新socket,以及播放时间
405
+ * Refresh the socket, and the playback time
389
406
  */
390
407
  public refresh(url?: string) {
391
408
  if (url) {
@@ -407,7 +424,7 @@ export class WsVideoManager extends EventBus<Events> {
407
424
  }
408
425
 
409
426
  /**
410
- * 销毁
427
+ * 销毁 | Destroy
411
428
  */
412
429
  public destroy() {
413
430
  this._wsInfoMap.forEach((wsInfo) => {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * 绘制视频到canvas中
2
+ * 绘制视频到canvas中 | Draw video into canvas
3
3
  */
4
4
  class CanvasDrawer {
5
5
  private _canvas: HTMLCanvasElement | null = null
@@ -36,12 +36,12 @@ class CanvasDrawer {
36
36
  }
37
37
 
38
38
  /**
39
- * 初始化 webgl
39
+ * 初始化 webgl | Initialize webgl
40
40
  */
41
41
  private initGl() {
42
42
  if (!this._canvas) return
43
43
 
44
- // 初始化 gl
44
+ // 初始化 gl | Initialize gl
45
45
  this._gl = this._canvas.getContext('webgl') || this._canvas.getContext('webgl2')
46
46
  if (!this._gl) {
47
47
  console.error('WebGL not supported')
@@ -61,17 +61,17 @@ class CanvasDrawer {
61
61
 
62
62
  if (!program) return
63
63
 
64
- // 坐标缓冲
64
+ // 坐标缓冲 | Position buffer
65
65
  const positionBuffer = gl.createBuffer()
66
66
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
67
67
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW)
68
68
 
69
- // 纹理坐标缓冲
69
+ // 纹理坐标缓冲 | Texture coordinate buffer
70
70
  const texCoordBuffer = gl.createBuffer()
71
71
  gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer)
72
72
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1]), gl.STATIC_DRAW)
73
73
 
74
- // 纹理
74
+ // 纹理 | Texture
75
75
  const texture = gl.createTexture()
76
76
  gl.bindTexture(gl.TEXTURE_2D, texture)
77
77
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
@@ -79,12 +79,12 @@ class CanvasDrawer {
79
79
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
80
80
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
81
81
 
82
- // 着色器变量的引用
82
+ // 着色器变量的引用 | References to shader variables
83
83
  const positionLocation = gl.getAttribLocation(program, 'a_position')
84
84
  const texCoordLocation = gl.getAttribLocation(program, 'a_texCoord')
85
85
  const textureLocation = gl.getUniformLocation(program, 'u_texture')
86
86
 
87
- // 缓存数据
87
+ // 缓存数据 | Caching data
88
88
  this._program = program
89
89
  this._positionBuffer = positionBuffer
90
90
  this._texCoordBuffer = texCoordBuffer
@@ -93,15 +93,15 @@ class CanvasDrawer {
93
93
  this._texCoordLocation = texCoordLocation
94
94
  this._textureLocation = textureLocation
95
95
 
96
- // 设置标志
96
+ // 设置标志 | gl is Ready
97
97
  this._glReady = true
98
98
  }
99
99
 
100
100
  /**
101
- * 创建着色器源码
101
+ * 创建着色器源码 | Create shader source code
102
102
  */
103
103
  private createShaderSource(gl: WebGLRenderingContext, type: number) {
104
- // 顶点着色器
104
+ // 顶点着色器 | Vertex shaders
105
105
  const vertexShaderSource = `
106
106
  attribute vec2 a_position;
107
107
  attribute vec2 a_texCoord;
@@ -112,7 +112,7 @@ class CanvasDrawer {
112
112
  }
113
113
  `
114
114
 
115
- // 片段着色器
115
+ // 片段着色器 | Fragment shader
116
116
  const fragmentShaderSource = `
117
117
  precision mediump float;
118
118
  varying vec2 v_texCoord;
@@ -130,7 +130,7 @@ class CanvasDrawer {
130
130
  }
131
131
 
132
132
  /**
133
- * 创建着色器
133
+ * 创建着色器 | Create shaders
134
134
  */
135
135
  private createShader(gl: WebGLRenderingContext, type: number, source: string) {
136
136
  const shader = gl.createShader(type)
@@ -154,7 +154,7 @@ class CanvasDrawer {
154
154
  }
155
155
 
156
156
  /**
157
- * 创建着色器程序
157
+ * 创建着色器程序 | Create program
158
158
  */
159
159
  private createProgram(gl: WebGLRenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader) {
160
160
  const program = gl.createProgram()
@@ -179,7 +179,7 @@ class CanvasDrawer {
179
179
  }
180
180
 
181
181
  /**
182
- * 绘制
182
+ * 绘制 | draw
183
183
  */
184
184
  public draw(video: HTMLVideoElement) {
185
185
  if (this._useGl) {
@@ -193,22 +193,23 @@ class CanvasDrawer {
193
193
  const texCoordLocation = this._texCoordLocation
194
194
  const textureLocation = this._textureLocation!
195
195
 
196
- // 更新视口区域
196
+ // 更新视口区域 | Update the viewport area
197
197
  gl.viewport(0, 0, this._canvas.width, this._canvas.height)
198
198
 
199
199
  if (video.readyState < HTMLMediaElement.HAVE_CURRENT_DATA) return
200
200
 
201
- // 更新纹理
201
+ // 更新纹理 | Update texture
202
202
  gl.bindTexture(gl.TEXTURE_2D, texture)
203
203
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video)
204
204
 
205
- // 清理画布
205
+ // 清理画布 | Clean the canvas
206
206
  gl.clear(gl.COLOR_BUFFER_BIT)
207
207
 
208
- // 使用着色器程序
208
+ // 使用着色器程序 | Use shader programs
209
209
  gl.useProgram(program)
210
210
 
211
211
  // 设置着色器变量对应的 buffer 数据
212
+ // Set the buffer corresponding to the shader variable
212
213
  gl.enableVertexAttribArray(positionLocation)
213
214
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
214
215
  gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0)
@@ -220,6 +221,7 @@ class CanvasDrawer {
220
221
  gl.uniform1i(textureLocation, 0)
221
222
 
222
223
  // 绘制(两个三角形六个顶点, 组成一个矩形)
224
+ // Draw (two triangles with six vertices, forming a rectangle)
223
225
  gl.drawArrays(gl.TRIANGLES, 0, 6)
224
226
  } else {
225
227
  const ctx = this._ctx2d
@@ -234,7 +236,7 @@ class CanvasDrawer {
234
236
  }
235
237
 
236
238
  /**
237
- * 销毁
239
+ * 销毁 | Destroy
238
240
  */
239
241
  public destroy() {
240
242
  this._canvas = null
@@ -3,11 +3,21 @@ import { EventBus } from '@havue/shared'
3
3
 
4
4
  // #region typedefine
5
5
  export type RenderConstructorOptionType = {
6
- /** 当前播放currentTime和最新视频时长最多相差 秒数,默认0.3s */
6
+ /**
7
+ * 当前播放currentTime和最新视频时长最多相差 秒数,默认0.3s
8
+ * The delay of currentTime relative to the latest video duration is 0.3s by default
9
+ */
7
10
  liveMaxLatency: number
8
- /** 最多缓存ws传输的未处理的buffer数据大小, 默认200kb */
11
+ /**
12
+ * 最多缓存ws传输的未处理的buffer数据大小, 默认200kb。
13
+ * The maximum amount of unprocessed buffer data to be cached for websocket transfers.
14
+ * 200kb by default
15
+ */
9
16
  maxCacheBufByte: number
10
- /** 最多存储的时间,用于清除在currentTime之前x秒时间节点前的buffer数据, 默认10s */
17
+ /**
18
+ * 最多存储的时间,用于清除在currentTime之前x秒时间节点前的buffer数据, 默认10s
19
+ * The maximum amount of time used to clear the buffer before a time node x seconds before currentTime (default 10s)
20
+ */
11
21
  maxCache: number
12
22
  }
13
23
 
@@ -52,32 +62,35 @@ export type RenderEvents = {
52
62
  // let curPosY = 0
53
63
 
54
64
  export class Render extends EventBus<RenderEvents> {
55
- /** video元素 */
65
+ /** video元素 | videw element */
56
66
  private _videoEl: HTMLVideoElement | undefined = undefined
57
- /** mp4box 实例 */
67
+ /** mp4box file */
58
68
  private _mp4box: MP4Box = MP4Box.createFile()
59
- /** mp4box onFragment获取的视频数据buffer数组 */
69
+ /**
70
+ * mp4box onFragment获取的视频数据buffer数组
71
+ * mp4box onFragment gets a buffer array of audio and video data
72
+ */
60
73
  private _audioBufsQueue: ArrayBuffer[] = []
61
74
  private _videoBufsQueue: ArrayBuffer[] = []
62
- /** MediaSource 实例 */
75
+ /** MediaSource instance */
63
76
  private _mediaSource: MediaSource | undefined
64
- /** SourceBuffer 实例 */
77
+ /** SourceBuffer instance */
65
78
  private _audioSourceBuffer: SourceBuffer | undefined
66
79
  private _videoSourceBuffer: SourceBuffer | undefined
67
80
 
68
81
  private _audioTrackId: number | undefined
69
82
  private _videoTrackId: number | undefined
70
- /** 用于MediaSource的mimeType */
83
+ /** 用于MediaSource的mimeType | mime type of the video */
71
84
  private _mimeType: string = ''
72
85
  private _audioMimeType: string = ''
73
86
  private _videoMimeType: string = ''
74
- /** 是否暂停播放 */
87
+ /** 是否暂停播放 | Pause or not */
75
88
  private _paused: boolean = false
76
89
  private _options: RenderConstructorOptionType
77
90
 
78
91
  private _cacheAnimationID: number | undefined = undefined
79
92
 
80
- /** fmp4初始化片段是否已经添加 */
93
+ /** fmp4初始化片段是否已经添加 | fmp4 Initializes whether the fragment has been added */
81
94
  private _isAudioInitSegmentAdded: boolean = false
82
95
  private _isVideoInitSegmentAdded: boolean = false
83
96
  private _offset: number = 0
@@ -122,7 +135,7 @@ export class Render extends EventBus<RenderEvents> {
122
135
  return this._videoEl
123
136
  }
124
137
 
125
- /** 更新实例配置 */
138
+ /** 更新实例配置 | Update configuration */
126
139
  public updateOptions(option: Partial<RenderConstructorOptionType> = {}) {
127
140
  Object.assign(this._options, {
128
141
  ...option
@@ -130,7 +143,7 @@ export class Render extends EventBus<RenderEvents> {
130
143
  }
131
144
 
132
145
  /**
133
- * 添加视频流buffer数据
146
+ * 添加视频流buffer数据 | Add video stream buffer data
134
147
  * @param buf
135
148
  */
136
149
  public appendMediaBuffer(bufs: Array<ArrayBuffer & { fileStart: number }>) {
@@ -146,8 +159,8 @@ export class Render extends EventBus<RenderEvents> {
146
159
  }
147
160
 
148
161
  /**
149
- * mp4box解析完成
150
- * @param info mp4box解析信息
162
+ * mp4box解析完成 | handle Mp4box onReady
163
+ * @param info mp4box解析信息 | mp4box parses the information
151
164
  */
152
165
  private _onMp4boxReady(info: any) {
153
166
  console.log('onMp4boxReady', info)
@@ -206,7 +219,7 @@ export class Render extends EventBus<RenderEvents> {
206
219
  }
207
220
  const sourceBuffer = isVideo ? this._videoSourceBuffer : this._audioSourceBuffer
208
221
  bufQueue.push(buffer)
209
- // 清除已使用的samples
222
+ // 清除已使用的samples | Clear the used samples
210
223
  this._mp4box.releaseUsedSamples(id, sampleNumber)
211
224
  this._mp4box.removeUsedSamples(id)
212
225
  const segmentAdded = isAudio ? this._isAudioInitSegmentAdded : this._isVideoInitSegmentAdded
@@ -230,7 +243,7 @@ export class Render extends EventBus<RenderEvents> {
230
243
  }
231
244
 
232
245
  /**
233
- * 初始化视频元素
246
+ * 初始化视频元素 | Initialize the video element
234
247
  */
235
248
  private _setupVideo() {
236
249
  this._videoEl = document.createElement('video')
@@ -269,11 +282,19 @@ export class Render extends EventBus<RenderEvents> {
269
282
  })
270
283
 
271
284
  /**
272
- * bug: 因预监画面播放一段时间后,
285
+ * @bug : 因预监画面播放一段时间后,
273
286
  * 虽然视频时间在走,但video的画面会暂停,
274
287
  * 发现将视频元素添加到视口中,画面就不会暂停,
275
288
  * 可能与浏览器的资源优化策略有关,先将video标签添加到视口中,
276
289
  * 后面有时间寻找一下是否有其他解决方案
290
+ *
291
+ * @bug :After the pre-monitoring screen plays for a period of time,
292
+ * although the video time is running, the video screen will pause.
293
+ * It is found that the video element is added to the viewport,
294
+ * and the screen will not pause.
295
+ * This may be related to the resource optimization strategy of the browser,
296
+ * so the video tag will be added to the viewport first,
297
+ * and then we have time to find out whether there are other solutions
277
298
  */
278
299
  // this._videoEl.controls = true
279
300
  document.body.appendChild(this._videoEl)
@@ -314,6 +335,7 @@ export class Render extends EventBus<RenderEvents> {
314
335
 
315
336
  /**
316
337
  * 是否支持Media Source Extention
338
+ * whether Media Source Extention is supported
317
339
  * @returns boolean
318
340
  */
319
341
  public isSupportMSE() {
@@ -321,7 +343,7 @@ export class Render extends EventBus<RenderEvents> {
321
343
  }
322
344
 
323
345
  /**
324
- * 初始化MSE
346
+ * 初始化MSE | Init MSE
325
347
  * @returns
326
348
  */
327
349
  private _setupMSE(): void {
@@ -346,14 +368,14 @@ export class Render extends EventBus<RenderEvents> {
346
368
  return
347
369
  }
348
370
 
349
- // 音频轨
371
+ // 音频轨 | Audio track
350
372
  if (this._audioMimeType) {
351
373
  this._audioSourceBuffer = this._mediaSource.addSourceBuffer(this._audioMimeType)
352
374
  this._audioSourceBuffer.mode = 'sequence'
353
375
  this._setupSourceBuffer(this._audioSourceBuffer, false)
354
376
  }
355
377
 
356
- // 视频轨
378
+ // 视频轨 | Video track
357
379
  if (this._videoMimeType) {
358
380
  this._videoSourceBuffer = this._mediaSource.addSourceBuffer(this._videoMimeType)
359
381
  this._videoSourceBuffer.mode = 'sequence'
@@ -379,13 +401,22 @@ export class Render extends EventBus<RenderEvents> {
379
401
 
380
402
  if (sourceBuffer.buffered.length > 0) {
381
403
  let bufferedLen = sourceBuffer.buffered.length
382
- /** 是否需要删除sourceBuffer中的buffer段 */
404
+ /**
405
+ * 是否需要删除sourceBuffer中的buffer段
406
+ * Whether the buffer section in sourceBuffer should be removed
407
+ */
383
408
  const needDelBuf = bufferedLen > 1
384
409
  /**
385
410
  * sourceBuffer中有多个buffered,时间不连续
386
411
  * 导致视频播放到其中一个buffer最后就暂停了
387
412
  * 如果出现多个buffered,删除之前有的buffer
388
413
  * 使用最新的视频buffer进行播放
414
+ *
415
+ * There are multiple buffers in the sourceBuffer,
416
+ * and the time is not continuous,
417
+ * so the video playback will be paused at the end of one of the buffers.
418
+ * If there are multiple buffers,
419
+ * delete the previous buffers and use the latest video buffer to play
389
420
  */
390
421
  if (needDelBuf && currentTime) {
391
422
  const lastIndex = bufferedLen - 1
@@ -411,12 +442,12 @@ export class Render extends EventBus<RenderEvents> {
411
442
  const end = sourceBuffer.buffered.end(bufferedLen - 1)
412
443
 
413
444
  if (isVideo) {
414
- // 设置开始时间
445
+ // 设置开始时间 | Set the start time
415
446
  if (!currentTime && start) {
416
447
  this._videoEl.currentTime = start
417
448
  }
418
449
 
419
- // 限制最低延迟时间
450
+ // 限制最低延迟时间 | Limit the minimum latency
420
451
  if (this._options.liveMaxLatency) {
421
452
  const offsetMaxLatency = this._options.liveMaxLatency
422
453
 
@@ -426,7 +457,8 @@ export class Render extends EventBus<RenderEvents> {
426
457
  }
427
458
  }
428
459
 
429
- // 移除当前时间之前的buffer
460
+ // 移除最大缓存时间之前的buffer
461
+ // Remove buffers before the maximum cache time
430
462
  if (!sourceBuffer!.updating && currentTime - start > this._options.maxCache) {
431
463
  sourceBuffer?.remove(0, currentTime - this._options.maxCache / 2)
432
464
  }
@@ -436,6 +468,7 @@ export class Render extends EventBus<RenderEvents> {
436
468
 
437
469
  /**
438
470
  * 将_bufsQueue中的数据添加到SourceBuffer中
471
+ * Add the data from _bufsQueue to the SourceBuffer
439
472
  * @returns
440
473
  */
441
474
  private _cache(isVideo: boolean = false) {
@@ -491,6 +524,7 @@ export class Render extends EventBus<RenderEvents> {
491
524
 
492
525
  /**
493
526
  * 刷新播放时间为最新
527
+ * Refresh the playback time to the latest
494
528
  */
495
529
  public refresh() {
496
530
  if (this._videoEl && this._videoEl.buffered.length) {
@@ -499,7 +533,7 @@ export class Render extends EventBus<RenderEvents> {
499
533
  }
500
534
  }
501
535
 
502
- /** 重置解析的视频mime type */
536
+ /** 重置解析的视频mime type | Reset the parsed video mime type */
503
537
  public resetMimeType() {
504
538
  this.destroyMp4box()
505
539
  this.destroyMediaSource()
@@ -553,7 +587,7 @@ export class Render extends EventBus<RenderEvents> {
553
587
  }
554
588
 
555
589
  /**
556
- * 销毁
590
+ * 销毁 | Destroy
557
591
  */
558
592
  public destroy() {
559
593
  if (this._videoEl) {
@@ -2,7 +2,7 @@ import MP4Box from 'mp4box'
2
2
 
3
3
  function ExtendMp4box() {
4
4
  const MP4BoxFile = MP4Box.createFile().constructor
5
- // 清空samples
5
+ // 清空samples | Clear samples
6
6
  MP4BoxFile.prototype.removeUsedSamples = function (id: number) {
7
7
  const track = this.getTrackById(id)
8
8
  const samples = track.samples