@give-tech/ec-player 0.0.1-beta.34 → 0.0.1-beta.35
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.
|
@@ -52,6 +52,7 @@ export interface InitSegment {
|
|
|
52
52
|
avcC?: Uint8Array;
|
|
53
53
|
hvcC?: Uint8Array;
|
|
54
54
|
isHevc?: boolean;
|
|
55
|
+
lengthSizeMinusOne?: number;
|
|
55
56
|
}
|
|
56
57
|
export declare class fMP4Demuxer {
|
|
57
58
|
private timescale;
|
|
@@ -59,6 +60,7 @@ export declare class fMP4Demuxer {
|
|
|
59
60
|
private avcC;
|
|
60
61
|
private hvcC;
|
|
61
62
|
private isHevc;
|
|
63
|
+
private lengthSizeMinusOne;
|
|
62
64
|
private trackHandlers;
|
|
63
65
|
/**
|
|
64
66
|
* 解析初始化段 (ftyp + moov)
|
|
@@ -141,6 +143,10 @@ export declare class fMP4Demuxer {
|
|
|
141
143
|
* 是否为 HEVC 编码
|
|
142
144
|
*/
|
|
143
145
|
isHevcStream(): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* 获取 NAL 长度字段大小 - 1
|
|
148
|
+
*/
|
|
149
|
+
getLengthSizeMinusOne(): number;
|
|
144
150
|
}
|
|
145
151
|
/**
|
|
146
152
|
* 检测是否为 fMP4 格式
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fMP4Demuxer.d.ts","sourceRoot":"","sources":["../../src/demuxer/fMP4Demuxer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8CH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,sBAAsB,CAAC,EAAE,MAAM,CAAA;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,OAAO;IACtB,mBAAmB,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,OAAO,EAAE,UAAU,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,EAAE,OAAO,EAAE,CAAA;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,CAAC,EAAE;QAAE,cAAc,EAAE,MAAM,CAAA;KAAE,CAAA;IACjC,KAAK,EAAE,OAAO,EAAE,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,MAAM,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"fMP4Demuxer.d.ts","sourceRoot":"","sources":["../../src/demuxer/fMP4Demuxer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -511,6 +511,7 @@ class fMP4Demuxer {
|
|
|
511
511
|
this.avcC = null;
|
|
512
512
|
this.hvcC = null;
|
|
513
513
|
this.isHevc = false;
|
|
514
|
+
this.lengthSizeMinusOne = 3;
|
|
514
515
|
this.trackHandlers = /* @__PURE__ */ new Map();
|
|
515
516
|
}
|
|
516
517
|
/**
|
|
@@ -532,7 +533,8 @@ class fMP4Demuxer {
|
|
|
532
533
|
timescale: this.timescale,
|
|
533
534
|
avcC: this.avcC || void 0,
|
|
534
535
|
hvcC: this.hvcC || void 0,
|
|
535
|
-
isHevc: this.isHevc
|
|
536
|
+
isHevc: this.isHevc,
|
|
537
|
+
lengthSizeMinusOne: this.lengthSizeMinusOne
|
|
536
538
|
};
|
|
537
539
|
}
|
|
538
540
|
/**
|
|
@@ -685,6 +687,10 @@ class fMP4Demuxer {
|
|
|
685
687
|
if (boxSize < 8) break;
|
|
686
688
|
if (boxType === "avcC") {
|
|
687
689
|
this.avcC = data.slice(offset, offset + boxSize);
|
|
690
|
+
if (boxSize > 12) {
|
|
691
|
+
this.lengthSizeMinusOne = data[offset + 8 + 4] & 3;
|
|
692
|
+
console.log("[fMP4Demuxer] avcC lengthSizeMinusOne:", this.lengthSizeMinusOne, "(NAL length size:", this.lengthSizeMinusOne + 1, "bytes)");
|
|
693
|
+
}
|
|
688
694
|
return;
|
|
689
695
|
}
|
|
690
696
|
offset += boxSize;
|
|
@@ -703,6 +709,10 @@ class fMP4Demuxer {
|
|
|
703
709
|
if (boxSize < 8) break;
|
|
704
710
|
if (boxType === "hvcC") {
|
|
705
711
|
this.hvcC = data.slice(offset, offset + boxSize);
|
|
712
|
+
if (boxSize > 12) {
|
|
713
|
+
this.lengthSizeMinusOne = data[offset + 8 + 21] & 3;
|
|
714
|
+
console.log("[fMP4Demuxer] hvcC lengthSizeMinusOne:", this.lengthSizeMinusOne, "(NAL length size:", this.lengthSizeMinusOne + 1, "bytes)");
|
|
715
|
+
}
|
|
706
716
|
console.log("[fMP4Demuxer] Found hvcC, size:", boxSize);
|
|
707
717
|
return;
|
|
708
718
|
}
|
|
@@ -944,6 +954,12 @@ class fMP4Demuxer {
|
|
|
944
954
|
isHevcStream() {
|
|
945
955
|
return this.isHevc;
|
|
946
956
|
}
|
|
957
|
+
/**
|
|
958
|
+
* 获取 NAL 长度字段大小 - 1
|
|
959
|
+
*/
|
|
960
|
+
getLengthSizeMinusOne() {
|
|
961
|
+
return this.lengthSizeMinusOne;
|
|
962
|
+
}
|
|
947
963
|
}
|
|
948
964
|
class NALParser {
|
|
949
965
|
/**
|
|
@@ -1901,7 +1917,7 @@ class HLSPlayer extends BasePlayer {
|
|
|
1901
1917
|
if (this.isFMP4) {
|
|
1902
1918
|
const queueSize = this.sampleQueue.length;
|
|
1903
1919
|
if (queueSize > 0 || batchCount % 50 === 0) {
|
|
1904
|
-
console.log("[DecodeLoop] fMP4: sampleQueue=", queueSize, "frameBuffer=", this.frameBuffer.length, "batch=", batchCount);
|
|
1920
|
+
console.log("[DecodeLoop] fMP4: sampleQueue=", queueSize, "frameBuffer=", this.frameBuffer.length, "batch=", batchCount, "decoderInit=", this.decoderInitialized);
|
|
1905
1921
|
}
|
|
1906
1922
|
while (this.sampleQueue.length > 0 && decodedInBatch < batchSize) {
|
|
1907
1923
|
const queuedSample = this.sampleQueue.shift();
|
|
@@ -1916,6 +1932,8 @@ class HLSPlayer extends BasePlayer {
|
|
|
1916
1932
|
this.droppedFrames++;
|
|
1917
1933
|
}
|
|
1918
1934
|
}
|
|
1935
|
+
} else {
|
|
1936
|
+
console.warn("[DecodeLoop] decodeSample returned null, remaining samples=", this.sampleQueue.length);
|
|
1919
1937
|
}
|
|
1920
1938
|
}
|
|
1921
1939
|
} else {
|
|
@@ -2091,7 +2109,8 @@ class HLSPlayer extends BasePlayer {
|
|
|
2091
2109
|
isHevc: initInfo?.isHevc,
|
|
2092
2110
|
hasAvcC: !!initInfo?.avcC,
|
|
2093
2111
|
hasHvcC: !!initInfo?.hvcC,
|
|
2094
|
-
timescale: initInfo?.timescale
|
|
2112
|
+
timescale: initInfo?.timescale,
|
|
2113
|
+
lengthSizeMinusOne: initInfo?.lengthSizeMinusOne
|
|
2095
2114
|
});
|
|
2096
2115
|
this._isHevc = initInfo?.isHevc ?? false;
|
|
2097
2116
|
if (initInfo?.hvcC && this._isHevc) {
|
|
@@ -2367,53 +2386,61 @@ class HLSPlayer extends BasePlayer {
|
|
|
2367
2386
|
decodeSample(sample) {
|
|
2368
2387
|
const decoder = this._isHevc ? this.hevcDecoder : this.decoder;
|
|
2369
2388
|
if (!decoder) {
|
|
2370
|
-
console.warn("[fMP4] Decoder not available");
|
|
2389
|
+
console.warn("[fMP4] Decoder not available, isHevc=", this._isHevc);
|
|
2371
2390
|
return null;
|
|
2372
2391
|
}
|
|
2373
2392
|
if (!this.decoderInitialized) {
|
|
2374
|
-
console.warn("[fMP4] Decoder not initialized,
|
|
2393
|
+
console.warn("[fMP4] Decoder not initialized, isHevc=", this._isHevc, ", sample size=", sample.data.length);
|
|
2375
2394
|
return null;
|
|
2376
2395
|
}
|
|
2377
2396
|
const data = sample.data;
|
|
2378
|
-
const
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2397
|
+
const lengthSize = this.fmp4Demuxer.getLengthSizeMinusOne() + 1;
|
|
2398
|
+
const readNalLength = (data2, offset2, size) => {
|
|
2399
|
+
switch (size) {
|
|
2400
|
+
case 1:
|
|
2401
|
+
return data2[offset2];
|
|
2402
|
+
case 2:
|
|
2403
|
+
return data2[offset2] << 8 | data2[offset2 + 1];
|
|
2404
|
+
case 4:
|
|
2405
|
+
default:
|
|
2406
|
+
return data2[offset2] << 24 | data2[offset2 + 1] << 16 | data2[offset2 + 2] << 8 | data2[offset2 + 3];
|
|
2384
2407
|
}
|
|
2385
|
-
}
|
|
2386
|
-
|
|
2387
|
-
const nalType2 = this._isHevc ? sample.isSync ? HEVC_NAL_TYPE.IDR_W_RADL : 1 : sample.isSync ? 5 : 1;
|
|
2388
|
-
return decoder.decode({
|
|
2389
|
-
type: nalType2,
|
|
2390
|
-
data,
|
|
2391
|
-
size: data.length
|
|
2392
|
-
});
|
|
2393
|
-
}
|
|
2408
|
+
};
|
|
2409
|
+
const hasAnnexBStartCode = data.length >= 4 && data[0] === 0 && data[1] === 0 && (data[2] === 0 && data[3] === 1 || data[2] === 1);
|
|
2394
2410
|
let nalCount = 0;
|
|
2395
2411
|
let totalSize = 0;
|
|
2396
2412
|
let offset = 0;
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2413
|
+
let avccParseError = false;
|
|
2414
|
+
while (offset + lengthSize <= data.length) {
|
|
2415
|
+
const nalLength = readNalLength(data, offset, lengthSize);
|
|
2416
|
+
if (nalLength <= 0 || nalLength > 1e7 || offset + lengthSize + nalLength > data.length) {
|
|
2417
|
+
avccParseError = true;
|
|
2401
2418
|
break;
|
|
2402
2419
|
}
|
|
2403
2420
|
totalSize += 4 + nalLength;
|
|
2404
|
-
offset +=
|
|
2421
|
+
offset += lengthSize + nalLength;
|
|
2405
2422
|
nalCount++;
|
|
2406
2423
|
}
|
|
2424
|
+
if (avccParseError && hasAnnexBStartCode) {
|
|
2425
|
+
const nalType2 = this._isHevc ? sample.isSync ? HEVC_NAL_TYPE.IDR_W_RADL : 1 : sample.isSync ? 5 : 1;
|
|
2426
|
+
console.log("[fMP4] Sample appears to be Annex B format, isSync=", sample.isSync, "size=", data.length);
|
|
2427
|
+
return decoder.decode({
|
|
2428
|
+
type: nalType2,
|
|
2429
|
+
data,
|
|
2430
|
+
size: data.length
|
|
2431
|
+
});
|
|
2432
|
+
}
|
|
2407
2433
|
if (nalCount === 0) {
|
|
2408
|
-
console.warn("[fMP4] No valid NAL units found in sample");
|
|
2434
|
+
console.warn("[fMP4] No valid NAL units found in sample, data.length=", data.length, "lengthSize=", lengthSize, "firstBytes=", Array.from(data.slice(0, 8)).map((b) => b.toString(16).padStart(2, "0")).join(" "));
|
|
2409
2435
|
return null;
|
|
2410
2436
|
}
|
|
2437
|
+
console.log("[fMP4] AVCC sample: nalCount=", nalCount, "annexBSize=", totalSize, "isSync=", sample.isSync, "lengthSize=", lengthSize);
|
|
2411
2438
|
const annexBData = new Uint8Array(totalSize);
|
|
2412
2439
|
let writeOffset = 0;
|
|
2413
2440
|
offset = 0;
|
|
2414
|
-
while (offset +
|
|
2415
|
-
const nalLength = data
|
|
2416
|
-
if (nalLength <= 0 || offset +
|
|
2441
|
+
while (offset + lengthSize <= data.length) {
|
|
2442
|
+
const nalLength = readNalLength(data, offset, lengthSize);
|
|
2443
|
+
if (nalLength <= 0 || offset + lengthSize + nalLength > data.length) {
|
|
2417
2444
|
break;
|
|
2418
2445
|
}
|
|
2419
2446
|
annexBData[writeOffset] = 0;
|
|
@@ -2421,9 +2448,9 @@ class HLSPlayer extends BasePlayer {
|
|
|
2421
2448
|
annexBData[writeOffset + 2] = 0;
|
|
2422
2449
|
annexBData[writeOffset + 3] = 1;
|
|
2423
2450
|
writeOffset += 4;
|
|
2424
|
-
annexBData.set(data.slice(offset +
|
|
2451
|
+
annexBData.set(data.slice(offset + lengthSize, offset + lengthSize + nalLength), writeOffset);
|
|
2425
2452
|
writeOffset += nalLength;
|
|
2426
|
-
offset +=
|
|
2453
|
+
offset += lengthSize + nalLength;
|
|
2427
2454
|
}
|
|
2428
2455
|
const nalType = this._isHevc ? sample.isSync ? HEVC_NAL_TYPE.IDR_W_RADL : 1 : sample.isSync ? 5 : 1;
|
|
2429
2456
|
const frame = decoder.decode({
|