@havue/solutions 1.1.0 → 1.1.2

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.
@@ -7238,6 +7238,57 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7238
7238
  }
7239
7239
  })(mp4box_all);
7240
7240
  const MP4Box = /* @__PURE__ */ getDefaultExportFromCjs(mp4box_all);
7241
+ function ExtendMp4box() {
7242
+ const MP4BoxFile = MP4Box.createFile().constructor;
7243
+ MP4BoxFile.prototype.removeUsedSamples = function(id) {
7244
+ const track = this.getTrackById(id);
7245
+ const samples = track.samples;
7246
+ const lastSample = samples[samples.length - 1];
7247
+ lastSample.data = null;
7248
+ lastSample.description = null;
7249
+ lastSample.alreadyRead = 0;
7250
+ track.samples = [];
7251
+ track.samples.push(lastSample);
7252
+ track.nextSample = track.samples.length;
7253
+ this.boxes = [];
7254
+ this.mdats = [];
7255
+ this.moofs = [];
7256
+ this.lastMoofIndex = 0;
7257
+ };
7258
+ MP4BoxFile.prototype.destroy = function() {
7259
+ if (this.stream) {
7260
+ this.stream.buffers = [];
7261
+ this.stream.bufferIndex = -1;
7262
+ this.stream = null;
7263
+ }
7264
+ this.boxes = [];
7265
+ this.mdats = [];
7266
+ this.moofs = [];
7267
+ this.isProgressive = false;
7268
+ this.moovStartFound = false;
7269
+ this.onMoovStart = null;
7270
+ this.moovStartSent = false;
7271
+ this.onReady = null;
7272
+ this.readySent = false;
7273
+ this.onSegment = null;
7274
+ this.onSamples = null;
7275
+ this.onError = null;
7276
+ this.sampleListBuilt = false;
7277
+ this.fragmentedTracks = [];
7278
+ this.extractedTracks = [];
7279
+ this.isFragmentationInitialized = false;
7280
+ this.sampleProcessingStarted = false;
7281
+ this.nextMoofNumber = 0;
7282
+ this.itemListBuilt = false;
7283
+ this.onSidx = null;
7284
+ this.sidxSent = false;
7285
+ this.moov = null;
7286
+ this.ftyp = null;
7287
+ this.items = [];
7288
+ this.entity_groups = [];
7289
+ };
7290
+ }
7291
+ ExtendMp4box();
7241
7292
  const WS_VIDEO_RENDER_DEFAULT_OPTIONS = Object.freeze({
7242
7293
  liveMaxLatency: 0.3,
7243
7294
  maxCacheBufByte: 200 * 1024,
@@ -7266,24 +7317,33 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7266
7317
  super();
7267
7318
  /** video元素 */
7268
7319
  __publicField(this, "_videoEl");
7269
- /** pixi.js 实例 */
7270
- // private _pixiApp: Application | null = null
7271
7320
  /** mp4box 实例 */
7272
7321
  __publicField(this, "_mp4box", MP4Box.createFile());
7273
- /** 接收到的socket消息 视频数据buffer数组 */
7274
- __publicField(this, "_bufsQueue", []);
7322
+ /** mp4box onFragment获取的视频数据buffer数组 */
7323
+ __publicField(this, "_audioBufsQueue", []);
7324
+ __publicField(this, "_videoBufsQueue", []);
7275
7325
  /** MediaSource 实例 */
7276
7326
  __publicField(this, "_mediaSource");
7277
7327
  /** SourceBuffer 实例 */
7278
- __publicField(this, "_sourceBuffer");
7328
+ __publicField(this, "_audioSourceBuffer");
7329
+ __publicField(this, "_videoSourceBuffer");
7330
+ __publicField(this, "_audioTrackId");
7331
+ __publicField(this, "_videoTrackId");
7279
7332
  /** 用于MediaSource的mimeType */
7280
7333
  __publicField(this, "_mimeType", "");
7334
+ __publicField(this, "_audioMimeType", "");
7335
+ __publicField(this, "_videoMimeType", "");
7281
7336
  /** 是否暂停播放 */
7282
7337
  __publicField(this, "_paused", false);
7283
7338
  __publicField(this, "_options");
7284
7339
  __publicField(this, "_cacheAnimationID");
7340
+ /** fmp4初始化片段是否已经添加 */
7341
+ __publicField(this, "_isAudioInitSegmentAdded", false);
7342
+ __publicField(this, "_isVideoInitSegmentAdded", false);
7343
+ __publicField(this, "_offset", 0);
7285
7344
  this._options = options ? Object.assign({}, WS_VIDEO_RENDER_DEFAULT_OPTIONS, options) : WS_VIDEO_RENDER_DEFAULT_OPTIONS;
7286
7345
  this._mp4box.onReady = this._onMp4boxReady.bind(this);
7346
+ this._mp4box.onSegment = this._onSegment.bind(this);
7287
7347
  this._setupVideo();
7288
7348
  }
7289
7349
  get muted() {
@@ -7321,33 +7381,15 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7321
7381
  * @param buf
7322
7382
  */
7323
7383
  appendMediaBuffer(bufs) {
7324
- var _a;
7325
7384
  if (this._paused) {
7326
7385
  return;
7327
7386
  }
7328
- if (!this._sourceBuffer) {
7329
- const buf = bufs[0];
7330
- buf.fileStart = 0;
7331
- this._mp4box.appendBuffer(buf);
7332
- }
7333
- this._bufsQueue.push(...bufs);
7334
- if (this._sourceBuffer && !((_a = this._videoEl) == null ? void 0 : _a.paused) && this._bufsQueue.length > 2) {
7335
- const len = this._bufsQueue.length;
7336
- const maxTotal = this._options.maxCacheBufByte;
7337
- let lastIndex = len - 1;
7338
- let total = 0;
7339
- for (let i2 = len - 1; i2 > 0; i2--) {
7340
- total += this._bufsQueue[i2].byteLength;
7341
- lastIndex = i2;
7342
- if (total >= maxTotal) {
7343
- this._bufsQueue = this._bufsQueue.slice(lastIndex);
7344
- break;
7345
- }
7346
- }
7347
- }
7348
- this._cacheAnimationID && cancelAnimationFrame(this._cacheAnimationID);
7349
- this._cacheAnimationID = void 0;
7350
- this._cache();
7387
+ bufs.forEach((b) => {
7388
+ b.fileStart = this._offset;
7389
+ this._offset += b.byteLength;
7390
+ this._mp4box.appendBuffer(b);
7391
+ });
7392
+ return;
7351
7393
  }
7352
7394
  /**
7353
7395
  * mp4box解析完成
@@ -7355,7 +7397,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7355
7397
  */
7356
7398
  _onMp4boxReady(info) {
7357
7399
  console.log("onMp4boxReady", info);
7358
- this._mp4box.flush();
7359
7400
  if (!info.isFragmented) {
7360
7401
  console.error("not fragmented mp4");
7361
7402
  return;
@@ -7367,10 +7408,66 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7367
7408
  width,
7368
7409
  height
7369
7410
  });
7411
+ const audioTrack = info.audioTracks[0];
7412
+ const videoTrack = info.videoTracks[0];
7413
+ if (audioTrack) {
7414
+ this._audioMimeType = `audio/mp4; codecs="${audioTrack.codec}"`;
7415
+ this._audioTrackId = audioTrack.id;
7416
+ this._mp4box.setSegmentOptions(audioTrack.id, void 0, {
7417
+ nbSamples: 100
7418
+ });
7419
+ }
7420
+ if (videoTrack) {
7421
+ this._videoMimeType = `video/mp4; codecs="${videoTrack.codec}"`;
7422
+ this._videoTrackId = videoTrack.id;
7423
+ this._mp4box.setSegmentOptions(videoTrack.id, void 0, {
7424
+ nbSamples: 100
7425
+ });
7426
+ }
7427
+ const initSegments = this._mp4box.initializeSegmentation();
7428
+ for (const seg of initSegments) {
7429
+ if (audioTrack && seg.id === audioTrack.id) {
7430
+ this._audioBufsQueue.push(seg.buffer);
7431
+ } else if (videoTrack && seg.id === videoTrack.id) {
7432
+ this._videoBufsQueue.push(seg.buffer);
7433
+ }
7434
+ }
7370
7435
  } catch (error) {
7371
7436
  console.error(error);
7372
7437
  }
7373
7438
  this._setupMSE();
7439
+ this._mp4box.start();
7440
+ }
7441
+ _onSegment(id, __, buffer, sampleNumber) {
7442
+ var _a;
7443
+ const isAudio = id === this._audioTrackId;
7444
+ const isVideo = id === this._videoTrackId;
7445
+ const bufQueue = isAudio ? this._audioBufsQueue : isVideo ? this._videoBufsQueue : null;
7446
+ if (!bufQueue) {
7447
+ return;
7448
+ }
7449
+ const sourceBuffer = isVideo ? this._videoSourceBuffer : this._audioSourceBuffer;
7450
+ bufQueue.push(buffer);
7451
+ this._mp4box.releaseUsedSamples(id, sampleNumber);
7452
+ this._mp4box.removeUsedSamples(id);
7453
+ const segmentAdded = isAudio ? this._isAudioInitSegmentAdded : this._isVideoInitSegmentAdded;
7454
+ if (segmentAdded && sourceBuffer && !((_a = this._videoEl) == null ? void 0 : _a.paused) && bufQueue.length > 2) {
7455
+ const len = bufQueue.length;
7456
+ const maxTotal = this._options.maxCacheBufByte;
7457
+ let lastIndex = len - 1;
7458
+ let total = 0;
7459
+ for (let i2 = len - 1; i2 > 0; i2--) {
7460
+ total += bufQueue[i2].byteLength;
7461
+ lastIndex = i2;
7462
+ if (total >= maxTotal) {
7463
+ bufQueue.splice(0, lastIndex);
7464
+ break;
7465
+ }
7466
+ }
7467
+ }
7468
+ this._cacheAnimationID && cancelAnimationFrame(this._cacheAnimationID);
7469
+ this._cacheAnimationID = void 0;
7470
+ this._cache(isVideo);
7374
7471
  }
7375
7472
  /**
7376
7473
  * 初始化视频元素
@@ -7455,30 +7552,45 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7455
7552
  URL.revokeObjectURL(this._videoEl.src);
7456
7553
  this._videoEl.src = URL.createObjectURL(this._mediaSource);
7457
7554
  this._mediaSource.addEventListener("sourceopen", () => {
7458
- const sourceBuffer = this._sourceBuffer = this._mediaSource.addSourceBuffer(this._mimeType);
7459
- sourceBuffer.mode = "sequence";
7460
- sourceBuffer.onupdateend = () => {
7461
- var _a, _b, _c;
7462
- if (!this._videoEl || !sourceBuffer || ((_a = this._mediaSource) == null ? void 0 : _a.readyState) !== "open" || ![...this._mediaSource.sourceBuffers].includes(sourceBuffer)) {
7463
- return;
7464
- }
7465
- const currentTime = this._videoEl.currentTime;
7466
- if (sourceBuffer.buffered.length > 0) {
7467
- let bufferedLen = sourceBuffer.buffered.length;
7468
- const needDelBuf = bufferedLen > 1;
7469
- if (needDelBuf && currentTime) {
7470
- const lastIndex = bufferedLen - 1;
7471
- if (currentTime < sourceBuffer.buffered.start(lastIndex)) {
7472
- this._videoEl.currentTime = sourceBuffer.buffered.start(lastIndex);
7473
- }
7474
- const delBufEnd = sourceBuffer.buffered.end(lastIndex - 1);
7475
- if (!this._sourceBuffer.updating && currentTime > delBufEnd) {
7476
- (_b = this._sourceBuffer) == null ? void 0 : _b.remove(0, delBufEnd);
7477
- }
7555
+ if (!this._mediaSource) {
7556
+ return;
7557
+ }
7558
+ if (this._audioMimeType) {
7559
+ this._audioSourceBuffer = this._mediaSource.addSourceBuffer(this._audioMimeType);
7560
+ this._audioSourceBuffer.mode = "sequence";
7561
+ this._setupSourceBuffer(this._audioSourceBuffer, false);
7562
+ }
7563
+ if (this._videoMimeType) {
7564
+ this._videoSourceBuffer = this._mediaSource.addSourceBuffer(this._videoMimeType);
7565
+ this._videoSourceBuffer.mode = "sequence";
7566
+ this._setupSourceBuffer(this._videoSourceBuffer, true);
7567
+ }
7568
+ });
7569
+ }
7570
+ _setupSourceBuffer(sourceBuffer, isVideo = false) {
7571
+ sourceBuffer.onupdateend = () => {
7572
+ var _a;
7573
+ if (!this._videoEl || !sourceBuffer || ((_a = this._mediaSource) == null ? void 0 : _a.readyState) !== "open" || ![...this._mediaSource.sourceBuffers].includes(sourceBuffer)) {
7574
+ return;
7575
+ }
7576
+ const currentTime = this._videoEl.currentTime;
7577
+ if (sourceBuffer.buffered.length > 0) {
7578
+ let bufferedLen = sourceBuffer.buffered.length;
7579
+ const needDelBuf = bufferedLen > 1;
7580
+ if (needDelBuf && currentTime) {
7581
+ const lastIndex = bufferedLen - 1;
7582
+ if (currentTime < sourceBuffer.buffered.start(lastIndex)) {
7583
+ this._videoEl.currentTime = sourceBuffer.buffered.start(lastIndex);
7478
7584
  }
7479
- bufferedLen = sourceBuffer.buffered.length;
7480
- const start = sourceBuffer.buffered.start(bufferedLen - 1);
7481
- const end = sourceBuffer.buffered.end(bufferedLen - 1);
7585
+ const delBufEnd = sourceBuffer.buffered.end(lastIndex - 1);
7586
+ if (!sourceBuffer.updating && currentTime > delBufEnd) {
7587
+ sourceBuffer == null ? void 0 : sourceBuffer.remove(0, delBufEnd);
7588
+ }
7589
+ }
7590
+ bufferedLen = sourceBuffer.buffered.length;
7591
+ const start = sourceBuffer.buffered.start(bufferedLen - 1);
7592
+ const end = sourceBuffer.buffered.end(bufferedLen - 1);
7593
+ if (isVideo) {
7482
7594
  if (!currentTime && start) {
7483
7595
  this._videoEl.currentTime = start;
7484
7596
  }
@@ -7488,33 +7600,35 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7488
7600
  this._videoEl.currentTime = end - 0.1;
7489
7601
  }
7490
7602
  }
7491
- if (!this._sourceBuffer.updating && currentTime - start > this._options.maxCache) {
7492
- (_c = this._sourceBuffer) == null ? void 0 : _c.remove(0, currentTime - this._options.maxCache / 2);
7493
- }
7494
7603
  }
7495
- };
7496
- });
7604
+ if (!sourceBuffer.updating && currentTime - start > this._options.maxCache) {
7605
+ sourceBuffer == null ? void 0 : sourceBuffer.remove(0, currentTime - this._options.maxCache / 2);
7606
+ }
7607
+ }
7608
+ };
7497
7609
  }
7498
7610
  /**
7499
7611
  * 将_bufsQueue中的数据添加到SourceBuffer中
7500
7612
  * @returns
7501
7613
  */
7502
- _cache() {
7614
+ _cache(isVideo = false) {
7503
7615
  if (!this._videoEl) {
7504
7616
  return;
7505
7617
  }
7506
- if (!this._mediaSource || !this._sourceBuffer || this._sourceBuffer.updating || !this._bufsQueue.length || this._mediaSource.readyState !== "open") {
7507
- this._cacheAnimationID === void 0 && (this._cacheAnimationID = requestAnimationFrame(() => this._cache()));
7618
+ const queue = isVideo ? this._videoBufsQueue : this._audioBufsQueue;
7619
+ const sourceBuffer = isVideo ? this._videoSourceBuffer : this._audioSourceBuffer;
7620
+ if (!this._mediaSource || !sourceBuffer || sourceBuffer.updating || !queue.length || this._mediaSource.readyState !== "open") {
7621
+ this._cacheAnimationID === void 0 && (this._cacheAnimationID = requestAnimationFrame(() => this._cache(isVideo)));
7508
7622
  return;
7509
7623
  }
7510
7624
  if (this._videoEl.error) {
7511
7625
  this._setupMSE();
7512
- return this._cacheAnimationID === void 0 && (this._cacheAnimationID = requestAnimationFrame(() => this._cache()));
7626
+ return this._cacheAnimationID === void 0 && (this._cacheAnimationID = requestAnimationFrame(() => this._cache(isVideo)));
7513
7627
  }
7514
7628
  this._cacheAnimationID = void 0;
7515
7629
  let frame;
7516
- if (this._bufsQueue.length > 1) {
7517
- const freeBuffer = this._bufsQueue.splice(0, this._bufsQueue.length);
7630
+ if (queue.length > 1) {
7631
+ const freeBuffer = queue.splice(0, queue.length);
7518
7632
  const length = freeBuffer.map((e) => e.byteLength).reduce((a, b) => a + b, 0);
7519
7633
  const buffer = new Uint8Array(length);
7520
7634
  let offset = 0;
@@ -7525,10 +7639,15 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7525
7639
  }
7526
7640
  frame = buffer;
7527
7641
  } else {
7528
- frame = new Uint8Array(this._bufsQueue.shift() || []);
7642
+ frame = new Uint8Array(queue.shift() || []);
7529
7643
  }
7530
7644
  if (frame) {
7531
- this._sourceBuffer.appendBuffer(frame);
7645
+ if (isVideo) {
7646
+ !this._isVideoInitSegmentAdded && (this._isVideoInitSegmentAdded = true);
7647
+ } else {
7648
+ !this._isAudioInitSegmentAdded && (this._isAudioInitSegmentAdded = true);
7649
+ }
7650
+ sourceBuffer.appendBuffer(frame);
7532
7651
  }
7533
7652
  }
7534
7653
  /**
@@ -7542,13 +7661,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7542
7661
  }
7543
7662
  /** 重置解析的视频mime type */
7544
7663
  resetMimeType() {
7664
+ this.destroyMp4box();
7545
7665
  this.destroyMediaSource();
7546
7666
  if (this._videoEl) {
7547
7667
  this._videoEl.src = "";
7548
7668
  }
7549
7669
  this._mp4box = MP4Box.createFile();
7550
7670
  this._mp4box.onReady = this._onMp4boxReady.bind(this);
7551
- this._bufsQueue.length = 0;
7671
+ this._mp4box.onSegment = this._onSegment.bind(this);
7552
7672
  }
7553
7673
  destroyMediaSource() {
7554
7674
  var _a;
@@ -7558,21 +7678,41 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7558
7678
  this._videoEl.src = "";
7559
7679
  }
7560
7680
  if (this._mediaSource.readyState === "open") {
7561
- if (this._sourceBuffer) {
7562
- this._sourceBuffer.abort();
7563
- this._mediaSource.removeSourceBuffer(this._sourceBuffer);
7681
+ if (this._audioSourceBuffer) {
7682
+ this._audioSourceBuffer.abort();
7683
+ this._mediaSource.removeSourceBuffer(this._audioSourceBuffer);
7684
+ }
7685
+ if (this._videoSourceBuffer) {
7686
+ this._videoSourceBuffer.abort();
7687
+ this._mediaSource.removeSourceBuffer(this._videoSourceBuffer);
7564
7688
  }
7565
7689
  this._mediaSource.endOfStream();
7566
7690
  }
7567
7691
  this._mediaSource = void 0;
7568
- this._sourceBuffer = void 0;
7692
+ this._audioSourceBuffer = void 0;
7693
+ this._videoSourceBuffer = void 0;
7569
7694
  }
7570
7695
  }
7696
+ destroyMp4box() {
7697
+ this._audioTrackId = void 0;
7698
+ this._videoTrackId = void 0;
7699
+ this._mimeType = "";
7700
+ this._audioMimeType = "";
7701
+ this._videoMimeType = "";
7702
+ this._isAudioInitSegmentAdded = false;
7703
+ this._isVideoInitSegmentAdded = false;
7704
+ this._audioBufsQueue.length = 0;
7705
+ this._videoBufsQueue.length = 0;
7706
+ this._offset = 0;
7707
+ this._mp4box.stop();
7708
+ this._mp4box.flush();
7709
+ this._mp4box.destroy();
7710
+ this._mp4box = null;
7711
+ }
7571
7712
  /**
7572
7713
  * 销毁
7573
7714
  */
7574
7715
  destroy() {
7575
- this._bufsQueue = [];
7576
7716
  if (this._videoEl) {
7577
7717
  this._videoEl.pause();
7578
7718
  this._videoEl.currentTime = 0;
@@ -7583,9 +7723,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7583
7723
  this._videoEl.src = "";
7584
7724
  this._videoEl = void 0;
7585
7725
  }
7586
- this._mimeType = "";
7587
7726
  this._cacheAnimationID && cancelAnimationFrame(this._cacheAnimationID);
7588
7727
  this._cacheAnimationID = void 0;
7728
+ this.destroyMp4box();
7589
7729
  this.destroyMediaSource();
7590
7730
  }
7591
7731
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@havue/ws-video-manager",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "Javascript class for websocket video manager",
5
5
  "keywords": [
6
6
  "havue",