@havue/solutions 1.1.0 → 1.1.1

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@havue/bc-connect",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Javascript class for Broadcast channel connect",
5
5
  "keywords": [
6
6
  "havue",
@@ -7605,6 +7605,57 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7605
7605
  }
7606
7606
  })(mp4box_all);
7607
7607
  const MP4Box = /* @__PURE__ */ getDefaultExportFromCjs(mp4box_all);
7608
+ function ExtendMp4box() {
7609
+ const MP4BoxFile = MP4Box.createFile().constructor;
7610
+ MP4BoxFile.prototype.removeUsedSamples = function(id) {
7611
+ const track = this.getTrackById(id);
7612
+ const samples = track.samples;
7613
+ const lastSample = samples[samples.length - 1];
7614
+ lastSample.data = null;
7615
+ lastSample.description = null;
7616
+ lastSample.alreadyRead = 0;
7617
+ track.samples = [];
7618
+ track.samples.push(lastSample);
7619
+ track.nextSample = track.samples.length;
7620
+ this.boxes = [];
7621
+ this.mdats = [];
7622
+ this.moofs = [];
7623
+ this.lastMoofIndex = 0;
7624
+ };
7625
+ MP4BoxFile.prototype.destroy = function() {
7626
+ if (this.stream) {
7627
+ this.stream.buffers = [];
7628
+ this.stream.bufferIndex = -1;
7629
+ this.stream = null;
7630
+ }
7631
+ this.boxes = [];
7632
+ this.mdats = [];
7633
+ this.moofs = [];
7634
+ this.isProgressive = false;
7635
+ this.moovStartFound = false;
7636
+ this.onMoovStart = null;
7637
+ this.moovStartSent = false;
7638
+ this.onReady = null;
7639
+ this.readySent = false;
7640
+ this.onSegment = null;
7641
+ this.onSamples = null;
7642
+ this.onError = null;
7643
+ this.sampleListBuilt = false;
7644
+ this.fragmentedTracks = [];
7645
+ this.extractedTracks = [];
7646
+ this.isFragmentationInitialized = false;
7647
+ this.sampleProcessingStarted = false;
7648
+ this.nextMoofNumber = 0;
7649
+ this.itemListBuilt = false;
7650
+ this.onSidx = null;
7651
+ this.sidxSent = false;
7652
+ this.moov = null;
7653
+ this.ftyp = null;
7654
+ this.items = [];
7655
+ this.entity_groups = [];
7656
+ };
7657
+ }
7658
+ ExtendMp4box();
7608
7659
  const WS_VIDEO_RENDER_DEFAULT_OPTIONS = Object.freeze({
7609
7660
  liveMaxLatency: 0.3,
7610
7661
  maxCacheBufByte: 200 * 1024,
@@ -7633,24 +7684,33 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7633
7684
  super();
7634
7685
  /** video元素 */
7635
7686
  __publicField(this, "_videoEl");
7636
- /** pixi.js 实例 */
7637
- // private _pixiApp: Application | null = null
7638
7687
  /** mp4box 实例 */
7639
7688
  __publicField(this, "_mp4box", MP4Box.createFile());
7640
- /** 接收到的socket消息 视频数据buffer数组 */
7641
- __publicField(this, "_bufsQueue", []);
7689
+ /** mp4box onFragment获取的视频数据buffer数组 */
7690
+ __publicField(this, "_audioBufsQueue", []);
7691
+ __publicField(this, "_videoBufsQueue", []);
7642
7692
  /** MediaSource 实例 */
7643
7693
  __publicField(this, "_mediaSource");
7644
7694
  /** SourceBuffer 实例 */
7645
- __publicField(this, "_sourceBuffer");
7695
+ __publicField(this, "_audioSourceBuffer");
7696
+ __publicField(this, "_videoSourceBuffer");
7697
+ __publicField(this, "_audioTrackId");
7698
+ __publicField(this, "_videoTrackId");
7646
7699
  /** 用于MediaSource的mimeType */
7647
7700
  __publicField(this, "_mimeType", "");
7701
+ __publicField(this, "_audioMimeType", "");
7702
+ __publicField(this, "_videoMimeType", "");
7648
7703
  /** 是否暂停播放 */
7649
7704
  __publicField(this, "_paused", false);
7650
7705
  __publicField(this, "_options");
7651
7706
  __publicField(this, "_cacheAnimationID");
7707
+ /** fmp4初始化片段是否已经添加 */
7708
+ __publicField(this, "_isAudioInitSegmentAdded", false);
7709
+ __publicField(this, "_isVideoInitSegmentAdded", false);
7710
+ __publicField(this, "_offset", 0);
7652
7711
  this._options = options ? Object.assign({}, WS_VIDEO_RENDER_DEFAULT_OPTIONS, options) : WS_VIDEO_RENDER_DEFAULT_OPTIONS;
7653
7712
  this._mp4box.onReady = this._onMp4boxReady.bind(this);
7713
+ this._mp4box.onSegment = this._onSegment.bind(this);
7654
7714
  this._setupVideo();
7655
7715
  }
7656
7716
  get muted() {
@@ -7688,33 +7748,15 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7688
7748
  * @param buf
7689
7749
  */
7690
7750
  appendMediaBuffer(bufs) {
7691
- var _a;
7692
7751
  if (this._paused) {
7693
7752
  return;
7694
7753
  }
7695
- if (!this._sourceBuffer) {
7696
- const buf = bufs[0];
7697
- buf.fileStart = 0;
7698
- this._mp4box.appendBuffer(buf);
7699
- }
7700
- this._bufsQueue.push(...bufs);
7701
- if (this._sourceBuffer && !((_a = this._videoEl) == null ? void 0 : _a.paused) && this._bufsQueue.length > 2) {
7702
- const len = this._bufsQueue.length;
7703
- const maxTotal = this._options.maxCacheBufByte;
7704
- let lastIndex = len - 1;
7705
- let total = 0;
7706
- for (let i2 = len - 1; i2 > 0; i2--) {
7707
- total += this._bufsQueue[i2].byteLength;
7708
- lastIndex = i2;
7709
- if (total >= maxTotal) {
7710
- this._bufsQueue = this._bufsQueue.slice(lastIndex);
7711
- break;
7712
- }
7713
- }
7714
- }
7715
- this._cacheAnimationID && cancelAnimationFrame(this._cacheAnimationID);
7716
- this._cacheAnimationID = void 0;
7717
- this._cache();
7754
+ bufs.forEach((b) => {
7755
+ b.fileStart = this._offset;
7756
+ this._offset += b.byteLength;
7757
+ this._mp4box.appendBuffer(b);
7758
+ });
7759
+ return;
7718
7760
  }
7719
7761
  /**
7720
7762
  * mp4box解析完成
@@ -7722,7 +7764,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7722
7764
  */
7723
7765
  _onMp4boxReady(info) {
7724
7766
  console.log("onMp4boxReady", info);
7725
- this._mp4box.flush();
7726
7767
  if (!info.isFragmented) {
7727
7768
  console.error("not fragmented mp4");
7728
7769
  return;
@@ -7734,10 +7775,66 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7734
7775
  width,
7735
7776
  height
7736
7777
  });
7778
+ const audioTrack = info.audioTracks[0];
7779
+ const videoTrack = info.videoTracks[0];
7780
+ if (audioTrack) {
7781
+ this._audioMimeType = `audio/mp4; codecs="${audioTrack.codec}"`;
7782
+ this._audioTrackId = audioTrack.id;
7783
+ this._mp4box.setSegmentOptions(audioTrack.id, void 0, {
7784
+ nbSamples: 100
7785
+ });
7786
+ }
7787
+ if (videoTrack) {
7788
+ this._videoMimeType = `video/mp4; codecs="${videoTrack.codec}"`;
7789
+ this._videoTrackId = videoTrack.id;
7790
+ this._mp4box.setSegmentOptions(videoTrack.id, void 0, {
7791
+ nbSamples: 100
7792
+ });
7793
+ }
7794
+ const initSegments = this._mp4box.initializeSegmentation();
7795
+ for (const seg of initSegments) {
7796
+ if (audioTrack && seg.id === audioTrack.id) {
7797
+ this._audioBufsQueue.push(seg.buffer);
7798
+ } else if (videoTrack && seg.id === videoTrack.id) {
7799
+ this._videoBufsQueue.push(seg.buffer);
7800
+ }
7801
+ }
7737
7802
  } catch (error) {
7738
7803
  console.error(error);
7739
7804
  }
7740
7805
  this._setupMSE();
7806
+ this._mp4box.start();
7807
+ }
7808
+ _onSegment(id, __, buffer, sampleNumber) {
7809
+ var _a;
7810
+ const isAudio = id === this._audioTrackId;
7811
+ const isVideo = id === this._videoTrackId;
7812
+ const bufQueue = isAudio ? this._audioBufsQueue : isVideo ? this._videoBufsQueue : null;
7813
+ if (!bufQueue) {
7814
+ return;
7815
+ }
7816
+ const sourceBuffer = isVideo ? this._videoSourceBuffer : this._audioSourceBuffer;
7817
+ bufQueue.push(buffer);
7818
+ this._mp4box.releaseUsedSamples(id, sampleNumber);
7819
+ this._mp4box.removeUsedSamples(id);
7820
+ const segmentAdded = isAudio ? this._isAudioInitSegmentAdded : this._isVideoInitSegmentAdded;
7821
+ if (segmentAdded && sourceBuffer && !((_a = this._videoEl) == null ? void 0 : _a.paused) && bufQueue.length > 2) {
7822
+ const len = bufQueue.length;
7823
+ const maxTotal = this._options.maxCacheBufByte;
7824
+ let lastIndex = len - 1;
7825
+ let total = 0;
7826
+ for (let i2 = len - 1; i2 > 0; i2--) {
7827
+ total += bufQueue[i2].byteLength;
7828
+ lastIndex = i2;
7829
+ if (total >= maxTotal) {
7830
+ bufQueue.splice(0, lastIndex);
7831
+ break;
7832
+ }
7833
+ }
7834
+ }
7835
+ this._cacheAnimationID && cancelAnimationFrame(this._cacheAnimationID);
7836
+ this._cacheAnimationID = void 0;
7837
+ this._cache(isVideo);
7741
7838
  }
7742
7839
  /**
7743
7840
  * 初始化视频元素
@@ -7822,30 +7919,45 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7822
7919
  URL.revokeObjectURL(this._videoEl.src);
7823
7920
  this._videoEl.src = URL.createObjectURL(this._mediaSource);
7824
7921
  this._mediaSource.addEventListener("sourceopen", () => {
7825
- const sourceBuffer = this._sourceBuffer = this._mediaSource.addSourceBuffer(this._mimeType);
7826
- sourceBuffer.mode = "sequence";
7827
- sourceBuffer.onupdateend = () => {
7828
- var _a, _b, _c;
7829
- if (!this._videoEl || !sourceBuffer || ((_a = this._mediaSource) == null ? void 0 : _a.readyState) !== "open" || ![...this._mediaSource.sourceBuffers].includes(sourceBuffer)) {
7830
- return;
7831
- }
7832
- const currentTime = this._videoEl.currentTime;
7833
- if (sourceBuffer.buffered.length > 0) {
7834
- let bufferedLen = sourceBuffer.buffered.length;
7835
- const needDelBuf = bufferedLen > 1;
7836
- if (needDelBuf && currentTime) {
7837
- const lastIndex = bufferedLen - 1;
7838
- if (currentTime < sourceBuffer.buffered.start(lastIndex)) {
7839
- this._videoEl.currentTime = sourceBuffer.buffered.start(lastIndex);
7840
- }
7841
- const delBufEnd = sourceBuffer.buffered.end(lastIndex - 1);
7842
- if (!this._sourceBuffer.updating && currentTime > delBufEnd) {
7843
- (_b = this._sourceBuffer) == null ? void 0 : _b.remove(0, delBufEnd);
7844
- }
7922
+ if (!this._mediaSource) {
7923
+ return;
7924
+ }
7925
+ if (this._audioMimeType) {
7926
+ this._audioSourceBuffer = this._mediaSource.addSourceBuffer(this._audioMimeType);
7927
+ this._audioSourceBuffer.mode = "sequence";
7928
+ this._setupSourceBuffer(this._audioSourceBuffer, false);
7929
+ }
7930
+ if (this._videoMimeType) {
7931
+ this._videoSourceBuffer = this._mediaSource.addSourceBuffer(this._videoMimeType);
7932
+ this._videoSourceBuffer.mode = "sequence";
7933
+ this._setupSourceBuffer(this._videoSourceBuffer, true);
7934
+ }
7935
+ });
7936
+ }
7937
+ _setupSourceBuffer(sourceBuffer, isVideo = false) {
7938
+ sourceBuffer.onupdateend = () => {
7939
+ var _a;
7940
+ if (!this._videoEl || !sourceBuffer || ((_a = this._mediaSource) == null ? void 0 : _a.readyState) !== "open" || ![...this._mediaSource.sourceBuffers].includes(sourceBuffer)) {
7941
+ return;
7942
+ }
7943
+ const currentTime = this._videoEl.currentTime;
7944
+ if (sourceBuffer.buffered.length > 0) {
7945
+ let bufferedLen = sourceBuffer.buffered.length;
7946
+ const needDelBuf = bufferedLen > 1;
7947
+ if (needDelBuf && currentTime) {
7948
+ const lastIndex = bufferedLen - 1;
7949
+ if (currentTime < sourceBuffer.buffered.start(lastIndex)) {
7950
+ this._videoEl.currentTime = sourceBuffer.buffered.start(lastIndex);
7845
7951
  }
7846
- bufferedLen = sourceBuffer.buffered.length;
7847
- const start = sourceBuffer.buffered.start(bufferedLen - 1);
7848
- const end = sourceBuffer.buffered.end(bufferedLen - 1);
7952
+ const delBufEnd = sourceBuffer.buffered.end(lastIndex - 1);
7953
+ if (!sourceBuffer.updating && currentTime > delBufEnd) {
7954
+ sourceBuffer == null ? void 0 : sourceBuffer.remove(0, delBufEnd);
7955
+ }
7956
+ }
7957
+ bufferedLen = sourceBuffer.buffered.length;
7958
+ const start = sourceBuffer.buffered.start(bufferedLen - 1);
7959
+ const end = sourceBuffer.buffered.end(bufferedLen - 1);
7960
+ if (isVideo) {
7849
7961
  if (!currentTime && start) {
7850
7962
  this._videoEl.currentTime = start;
7851
7963
  }
@@ -7855,33 +7967,35 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7855
7967
  this._videoEl.currentTime = end - 0.1;
7856
7968
  }
7857
7969
  }
7858
- if (!this._sourceBuffer.updating && currentTime - start > this._options.maxCache) {
7859
- (_c = this._sourceBuffer) == null ? void 0 : _c.remove(0, currentTime - this._options.maxCache / 2);
7860
- }
7861
7970
  }
7862
- };
7863
- });
7971
+ if (!sourceBuffer.updating && currentTime - start > this._options.maxCache) {
7972
+ sourceBuffer == null ? void 0 : sourceBuffer.remove(0, currentTime - this._options.maxCache / 2);
7973
+ }
7974
+ }
7975
+ };
7864
7976
  }
7865
7977
  /**
7866
7978
  * 将_bufsQueue中的数据添加到SourceBuffer中
7867
7979
  * @returns
7868
7980
  */
7869
- _cache() {
7981
+ _cache(isVideo = false) {
7870
7982
  if (!this._videoEl) {
7871
7983
  return;
7872
7984
  }
7873
- if (!this._mediaSource || !this._sourceBuffer || this._sourceBuffer.updating || !this._bufsQueue.length || this._mediaSource.readyState !== "open") {
7874
- this._cacheAnimationID === void 0 && (this._cacheAnimationID = requestAnimationFrame(() => this._cache()));
7985
+ const queue = isVideo ? this._videoBufsQueue : this._audioBufsQueue;
7986
+ const sourceBuffer = isVideo ? this._videoSourceBuffer : this._audioSourceBuffer;
7987
+ if (!this._mediaSource || !sourceBuffer || sourceBuffer.updating || !queue.length || this._mediaSource.readyState !== "open") {
7988
+ this._cacheAnimationID === void 0 && (this._cacheAnimationID = requestAnimationFrame(() => this._cache(isVideo)));
7875
7989
  return;
7876
7990
  }
7877
7991
  if (this._videoEl.error) {
7878
7992
  this._setupMSE();
7879
- return this._cacheAnimationID === void 0 && (this._cacheAnimationID = requestAnimationFrame(() => this._cache()));
7993
+ return this._cacheAnimationID === void 0 && (this._cacheAnimationID = requestAnimationFrame(() => this._cache(isVideo)));
7880
7994
  }
7881
7995
  this._cacheAnimationID = void 0;
7882
7996
  let frame;
7883
- if (this._bufsQueue.length > 1) {
7884
- const freeBuffer = this._bufsQueue.splice(0, this._bufsQueue.length);
7997
+ if (queue.length > 1) {
7998
+ const freeBuffer = queue.splice(0, queue.length);
7885
7999
  const length = freeBuffer.map((e) => e.byteLength).reduce((a, b) => a + b, 0);
7886
8000
  const buffer = new Uint8Array(length);
7887
8001
  let offset = 0;
@@ -7892,10 +8006,15 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7892
8006
  }
7893
8007
  frame = buffer;
7894
8008
  } else {
7895
- frame = new Uint8Array(this._bufsQueue.shift() || []);
8009
+ frame = new Uint8Array(queue.shift() || []);
7896
8010
  }
7897
8011
  if (frame) {
7898
- this._sourceBuffer.appendBuffer(frame);
8012
+ if (isVideo) {
8013
+ !this._isVideoInitSegmentAdded && (this._isVideoInitSegmentAdded = true);
8014
+ } else {
8015
+ !this._isAudioInitSegmentAdded && (this._isAudioInitSegmentAdded = true);
8016
+ }
8017
+ sourceBuffer.appendBuffer(frame);
7899
8018
  }
7900
8019
  }
7901
8020
  /**
@@ -7909,13 +8028,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7909
8028
  }
7910
8029
  /** 重置解析的视频mime type */
7911
8030
  resetMimeType() {
8031
+ this.destroyMp4box();
7912
8032
  this.destroyMediaSource();
7913
8033
  if (this._videoEl) {
7914
8034
  this._videoEl.src = "";
7915
8035
  }
7916
8036
  this._mp4box = MP4Box.createFile();
7917
8037
  this._mp4box.onReady = this._onMp4boxReady.bind(this);
7918
- this._bufsQueue.length = 0;
8038
+ this._mp4box.onSegment = this._onSegment.bind(this);
7919
8039
  }
7920
8040
  destroyMediaSource() {
7921
8041
  var _a;
@@ -7925,21 +8045,41 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7925
8045
  this._videoEl.src = "";
7926
8046
  }
7927
8047
  if (this._mediaSource.readyState === "open") {
7928
- if (this._sourceBuffer) {
7929
- this._sourceBuffer.abort();
7930
- this._mediaSource.removeSourceBuffer(this._sourceBuffer);
8048
+ if (this._audioSourceBuffer) {
8049
+ this._audioSourceBuffer.abort();
8050
+ this._mediaSource.removeSourceBuffer(this._audioSourceBuffer);
8051
+ }
8052
+ if (this._videoSourceBuffer) {
8053
+ this._videoSourceBuffer.abort();
8054
+ this._mediaSource.removeSourceBuffer(this._videoSourceBuffer);
7931
8055
  }
7932
8056
  this._mediaSource.endOfStream();
7933
8057
  }
7934
8058
  this._mediaSource = void 0;
7935
- this._sourceBuffer = void 0;
8059
+ this._audioSourceBuffer = void 0;
8060
+ this._videoSourceBuffer = void 0;
7936
8061
  }
7937
8062
  }
8063
+ destroyMp4box() {
8064
+ this._audioTrackId = void 0;
8065
+ this._videoTrackId = void 0;
8066
+ this._mimeType = "";
8067
+ this._audioMimeType = "";
8068
+ this._videoMimeType = "";
8069
+ this._isAudioInitSegmentAdded = false;
8070
+ this._isVideoInitSegmentAdded = false;
8071
+ this._audioBufsQueue.length = 0;
8072
+ this._videoBufsQueue.length = 0;
8073
+ this._offset = 0;
8074
+ this._mp4box.stop();
8075
+ this._mp4box.flush();
8076
+ this._mp4box.destroy();
8077
+ this._mp4box = null;
8078
+ }
7938
8079
  /**
7939
8080
  * 销毁
7940
8081
  */
7941
8082
  destroy() {
7942
- this._bufsQueue = [];
7943
8083
  if (this._videoEl) {
7944
8084
  this._videoEl.pause();
7945
8085
  this._videoEl.currentTime = 0;
@@ -7950,9 +8090,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
7950
8090
  this._videoEl.src = "";
7951
8091
  this._videoEl = void 0;
7952
8092
  }
7953
- this._mimeType = "";
7954
8093
  this._cacheAnimationID && cancelAnimationFrame(this._cacheAnimationID);
7955
8094
  this._cacheAnimationID = void 0;
8095
+ this.destroyMp4box();
7956
8096
  this.destroyMediaSource();
7957
8097
  }
7958
8098
  }