@give-tech/ec-player 0.0.1-beta.31 → 0.0.1-beta.32

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/dist/index.js CHANGED
@@ -1238,7 +1238,8 @@ class SegmentPrefetcher extends BasePrefetcher {
1238
1238
  this.prefetchQueue.push({
1239
1239
  data,
1240
1240
  segmentIndex: nextIndex,
1241
- fetchTime
1241
+ fetchTime,
1242
+ segmentDuration: segment.duration
1242
1243
  });
1243
1244
  this.fetchedSegmentCount++;
1244
1245
  this.updateStatus({
@@ -1276,7 +1277,7 @@ class SegmentPrefetcher extends BasePrefetcher {
1276
1277
  this.prefetchQueue.shift();
1277
1278
  this.updateStatus({ prefetchQueueSize: this.prefetchQueue.length });
1278
1279
  const parseStart = performance.now();
1279
- const itemCount = this.parseSegment(item.data, item.segmentIndex);
1280
+ const itemCount = this.parseSegment(item.data, item.segmentIndex, item.segmentDuration);
1280
1281
  const parseTime = performance.now() - parseStart;
1281
1282
  this.currentSegmentIndex++;
1282
1283
  this.updateStatus({ currentSegmentIndex: this.currentSegmentIndex });
@@ -1548,11 +1549,11 @@ class HLSSegmentPrefetcher extends SegmentPrefetcher {
1548
1549
  /**
1549
1550
  * 解析分片数据
1550
1551
  */
1551
- parseSegment(data, index) {
1552
+ parseSegment(data, index, segmentDuration) {
1552
1553
  if (this.player.isFMP4) {
1553
1554
  return this.player.parseFMP4Data(data);
1554
1555
  } else {
1555
- return this.player.parseTSData(data);
1556
+ return this.player.parseTSData(data, segmentDuration);
1556
1557
  }
1557
1558
  }
1558
1559
  /**
@@ -1584,14 +1585,36 @@ class HLSPlayer extends BasePlayer {
1584
1585
  this.currentPlaylistUrl = "";
1585
1586
  this._nalQueue = [];
1586
1587
  this._sampleQueue = [];
1588
+ this._currentSegmentDuration = 0;
1587
1589
  this.prefetcher = null;
1590
+ this._nalCountInCurrentSegment = 0;
1588
1591
  this.lastRenderTime = 0;
1589
1592
  this.playStartTime = 0;
1590
1593
  this.accumulatedMediaTime = 0;
1591
1594
  this._lastLogTime = 0;
1595
+ this._lastRafTime = 0;
1592
1596
  this.renderLoop = (timestamp = 0) => {
1593
1597
  if (!this.isPlaying) return;
1594
1598
  const now = performance.now();
1599
+ const BACKGROUND_PAUSE_THRESHOLD = 500;
1600
+ if (this._lastRafTime > 0 && now - this._lastRafTime > BACKGROUND_PAUSE_THRESHOLD) {
1601
+ const pauseDuration = now - this._lastRafTime;
1602
+ console.log("[renderLoop] Background pause detected, duration:", pauseDuration.toFixed(0), "ms");
1603
+ if (this.config.isLive) {
1604
+ const KEEP_FRAMES = 5;
1605
+ if (this.frameBuffer.length > KEEP_FRAMES) {
1606
+ const droppedCount = this.frameBuffer.length - KEEP_FRAMES;
1607
+ this.frameBuffer = this.frameBuffer.slice(-KEEP_FRAMES);
1608
+ this.droppedFrames += droppedCount;
1609
+ console.log("[renderLoop] Live resume: dropped", droppedCount, "old frames, keeping latest", KEEP_FRAMES);
1610
+ }
1611
+ this.playStartTime = now;
1612
+ this.accumulatedMediaTime = 0;
1613
+ } else {
1614
+ this.playStartTime = now - this.accumulatedMediaTime;
1615
+ }
1616
+ }
1617
+ this._lastRafTime = now;
1595
1618
  if (!this._lastLogTime || now - this._lastLogTime > 1e3) {
1596
1619
  this._lastLogTime = now;
1597
1620
  console.log("[renderLoop] frameBuffer=", this.frameBuffer.length, "renderer=", !!this.renderer);
@@ -1696,6 +1719,8 @@ class HLSPlayer extends BasePlayer {
1696
1719
  isLoaded: true,
1697
1720
  totalSegments: segments.length
1698
1721
  });
1722
+ this.initPrefetcher();
1723
+ this.prefetcher.start();
1699
1724
  }
1700
1725
  /**
1701
1726
  * 初始化解码器(覆盖基类方法,添加 fMP4 支持)
@@ -1792,11 +1817,12 @@ class HLSPlayer extends BasePlayer {
1792
1817
  while (this.nalQueue.length > 0 && decodedInBatch < batchSize) {
1793
1818
  const queuedNal = this.nalQueue.shift();
1794
1819
  const nalUnit = queuedNal.nalUnit;
1820
+ const segmentDuration = queuedNal.segmentDuration;
1795
1821
  if (!this.decoderInitialized && (nalUnit.type === 7 || nalUnit.type === 8)) {
1796
1822
  this.initDecoderParamsSync([nalUnit]);
1797
1823
  }
1798
1824
  if (nalUnit.type === 5 || nalUnit.type === 1) {
1799
- const frame = this.decodeNAL(nalUnit);
1825
+ const frame = this.decodeNAL(nalUnit, segmentDuration);
1800
1826
  if (frame) {
1801
1827
  this.frameBuffer.push(frame);
1802
1828
  decodedInBatch++;
@@ -1910,7 +1936,7 @@ class HLSPlayer extends BasePlayer {
1910
1936
  /**
1911
1937
  * 解析 TS 数据
1912
1938
  */
1913
- parseTSData(tsData) {
1939
+ parseTSData(tsData, segmentDuration) {
1914
1940
  const packets = this.tsDemuxer.parse(tsData);
1915
1941
  let nalCount = 0;
1916
1942
  if (packets.video.length > 0) {
@@ -1920,8 +1946,15 @@ class HLSPlayer extends BasePlayer {
1920
1946
  if (!this.decoderInitialized) {
1921
1947
  this.initDecoderParamsSync(nalUnits);
1922
1948
  }
1949
+ if (segmentDuration !== void 0) {
1950
+ this._currentSegmentDuration = segmentDuration;
1951
+ }
1923
1952
  for (const nalUnit of nalUnits) {
1924
- this._nalQueue.push({ nalUnit, pts: 0 });
1953
+ this._nalQueue.push({
1954
+ nalUnit,
1955
+ pts: 0,
1956
+ segmentDuration: this._currentSegmentDuration
1957
+ });
1925
1958
  }
1926
1959
  nalCount = nalUnits.length;
1927
1960
  }
@@ -1978,7 +2011,13 @@ class HLSPlayer extends BasePlayer {
1978
2011
  this._sampleQueue.length = 0;
1979
2012
  this._nalQueue.length = 0;
1980
2013
  const url = uri.startsWith("http") ? uri : this.currentPlaylistUrl.substring(0, this.currentPlaylistUrl.lastIndexOf("/") + 1) + uri;
1981
- const response = await fetch(url);
2014
+ const headers = {};
2015
+ if (this.initSegment?.uri === uri && this.initSegment.byteRange) {
2016
+ const { start, end } = this.initSegment.byteRange;
2017
+ headers["Range"] = `bytes=${start}-${end}`;
2018
+ console.log("[fMP4] Using byte range for init segment:", { start, end });
2019
+ }
2020
+ const response = await fetch(url, { headers });
1982
2021
  const data = new Uint8Array(await response.arrayBuffer());
1983
2022
  console.log("[fMP4] New init segment data size:", data.length, "bytes");
1984
2023
  const initInfo = this.fmp4Demuxer.parseInitSegment(data);
@@ -2297,16 +2336,22 @@ class HLSPlayer extends BasePlayer {
2297
2336
  /**
2298
2337
  * 解码单个 NAL 单元
2299
2338
  */
2300
- decodeNAL(nalUnit) {
2339
+ decodeNAL(nalUnit, segmentDuration) {
2301
2340
  if (!this.decoder) return null;
2302
2341
  const nalWithStartCode = new Uint8Array(nalUnit.size + 4);
2303
2342
  nalWithStartCode.set([0, 0, 0, 1], 0);
2304
2343
  nalWithStartCode.set(nalUnit.data, 4);
2305
- return this.decoder.decode({
2344
+ const frame = this.decoder.decode({
2306
2345
  type: nalUnit.type,
2307
2346
  data: nalWithStartCode,
2308
2347
  size: nalWithStartCode.length
2309
2348
  });
2349
+ if (frame && segmentDuration && segmentDuration > 0) {
2350
+ const timescale = 1e3;
2351
+ const frameDuration = timescale / 60;
2352
+ frame.duration = frameDuration;
2353
+ }
2354
+ return frame;
2310
2355
  }
2311
2356
  }
2312
2357
  const FLV_SIGNATURE = [70, 76, 86];
@@ -2842,6 +2887,7 @@ class FLVPlayer extends BasePlayer {
2842
2887
  this.bufferEmptyStartTime = 0;
2843
2888
  this.playStartTimeOffset = 0;
2844
2889
  this.resyncCount = 0;
2890
+ this._lastRafTime = 0;
2845
2891
  this.renderLoop = () => {
2846
2892
  if (!this.isPlaying) return;
2847
2893
  this.updateState({
@@ -2851,12 +2897,32 @@ class FLVPlayer extends BasePlayer {
2851
2897
  });
2852
2898
  const now = performance.now();
2853
2899
  const isLive = this.config.isLive;
2900
+ const BACKGROUND_PAUSE_THRESHOLD = 500;
2901
+ if (this._lastRafTime > 0 && now - this._lastRafTime > BACKGROUND_PAUSE_THRESHOLD) {
2902
+ const pauseDuration = now - this._lastRafTime;
2903
+ console.log("[FLVPlayer] Background pause detected, duration:", pauseDuration.toFixed(0), "ms, isLive:", isLive, "queue:", this._videoTagQueue.length, "buffer:", this._timedFrameBuffer.length);
2904
+ if (isLive) {
2905
+ const droppedDecoded = this._timedFrameBuffer.length;
2906
+ const droppedQueue = this._videoTagQueue.length;
2907
+ this._timedFrameBuffer = [];
2908
+ this._videoTagQueue = [];
2909
+ this.droppedFrames += droppedDecoded;
2910
+ this.playStartTime = 0;
2911
+ this.firstFrameDts = -1;
2912
+ this.pausedTime = 0;
2913
+ console.log("[FLVPlayer] Live resume: cleared all buffers (decoded:", droppedDecoded, ", queue:", droppedQueue, "), waiting for new data");
2914
+ } else {
2915
+ this.playStartTimeOffset += pauseDuration;
2916
+ }
2917
+ }
2918
+ this._lastRafTime = now;
2854
2919
  if (this._timedFrameBuffer.length > 0 && this.renderer) {
2855
2920
  this.consecutiveEmptyBuffer = 0;
2856
2921
  if (this.playStartTime <= 0) {
2857
2922
  this.firstFrameDts = this._timedFrameBuffer[0].dts;
2858
2923
  this.playStartTime = now;
2859
2924
  this.playStartTimeOffset = 0;
2925
+ this.pausedTime = 0;
2860
2926
  console.log("[FLVPlayer] RenderLoop initialized, firstFrameDts:", this.firstFrameDts, "isLive:", isLive);
2861
2927
  }
2862
2928
  if (isLive) {