@give-tech/ec-player 0.0.1-beta.6 → 0.0.1-beta.8
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
|
@@ -1460,12 +1460,18 @@ const DEFAULT_HLS_CONFIG = {
|
|
|
1460
1460
|
class HLSSegmentPrefetcher extends SegmentPrefetcher {
|
|
1461
1461
|
constructor(config, callbacks, player) {
|
|
1462
1462
|
super(config, callbacks);
|
|
1463
|
+
this.currentInitSegmentUri = null;
|
|
1463
1464
|
this.player = player;
|
|
1464
1465
|
}
|
|
1465
1466
|
/**
|
|
1466
1467
|
* 获取分片数据
|
|
1467
1468
|
*/
|
|
1468
1469
|
async fetchSegment(segment, index) {
|
|
1470
|
+
if (segment.initSegmentUri && segment.initSegmentUri !== this.currentInitSegmentUri) {
|
|
1471
|
+
console.log("[HLSSegmentPrefetcher] Init segment changed:", segment.initSegmentUri);
|
|
1472
|
+
await this.player.loadNewInitSegment(segment.initSegmentUri);
|
|
1473
|
+
this.currentInitSegmentUri = segment.initSegmentUri;
|
|
1474
|
+
}
|
|
1469
1475
|
const baseUrl = this.baseUrl;
|
|
1470
1476
|
const url = segment.uri.startsWith("http") ? segment.uri : baseUrl + segment.uri;
|
|
1471
1477
|
const headers = {};
|
|
@@ -1735,7 +1741,9 @@ class HLSPlayer extends BasePlayer {
|
|
|
1735
1741
|
const segmentInfos = this.fmp4Segments.map((seg) => ({
|
|
1736
1742
|
uri: seg.uri,
|
|
1737
1743
|
duration: seg.duration,
|
|
1738
|
-
byteRange: seg.byteRange
|
|
1744
|
+
byteRange: seg.byteRange,
|
|
1745
|
+
initSegmentUri: seg.initSegmentUri
|
|
1746
|
+
// 传递初始化段 URI
|
|
1739
1747
|
}));
|
|
1740
1748
|
this.prefetcher.setSegments(segmentInfos, baseUrl);
|
|
1741
1749
|
} else {
|
|
@@ -1751,33 +1759,46 @@ class HLSPlayer extends BasePlayer {
|
|
|
1751
1759
|
* 解析 fMP4 数据
|
|
1752
1760
|
*/
|
|
1753
1761
|
parseFMP4Data(data) {
|
|
1754
|
-
let
|
|
1755
|
-
let mdatOffset = -1;
|
|
1756
|
-
let mdatSize = 0;
|
|
1762
|
+
let totalSampleCount = 0;
|
|
1757
1763
|
let offset = 0;
|
|
1758
1764
|
while (offset < data.length - 8) {
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1765
|
+
let moofOffset = -1;
|
|
1766
|
+
let mdatOffset = -1;
|
|
1767
|
+
let mdatSize = 0;
|
|
1768
|
+
while (offset < data.length - 8) {
|
|
1769
|
+
const boxSize = this.readBoxSize(data, offset);
|
|
1770
|
+
const boxType = this.readBoxType(data, offset + 4);
|
|
1771
|
+
if (boxSize < 8) break;
|
|
1772
|
+
if (boxType === "moof") {
|
|
1773
|
+
moofOffset = offset;
|
|
1774
|
+
offset += boxSize;
|
|
1775
|
+
break;
|
|
1776
|
+
}
|
|
1777
|
+
offset += boxSize;
|
|
1778
|
+
}
|
|
1779
|
+
if (moofOffset < 0) break;
|
|
1780
|
+
while (offset < data.length - 8) {
|
|
1781
|
+
const boxSize = this.readBoxSize(data, offset);
|
|
1782
|
+
const boxType = this.readBoxType(data, offset + 4);
|
|
1783
|
+
if (boxSize < 8) break;
|
|
1784
|
+
if (boxType === "mdat") {
|
|
1785
|
+
mdatOffset = offset;
|
|
1786
|
+
mdatSize = boxSize;
|
|
1787
|
+
offset += boxSize;
|
|
1788
|
+
break;
|
|
1789
|
+
}
|
|
1790
|
+
offset += boxSize;
|
|
1767
1791
|
}
|
|
1768
|
-
|
|
1769
|
-
}
|
|
1770
|
-
let sampleCount = 0;
|
|
1771
|
-
if (moofOffset >= 0 && mdatOffset >= 0) {
|
|
1792
|
+
if (mdatOffset < 0) break;
|
|
1772
1793
|
const moof = this.fmp4Demuxer.parseMoof(data, moofOffset);
|
|
1773
1794
|
const mdatData = data.slice(mdatOffset + 8, mdatOffset + mdatSize);
|
|
1774
1795
|
const samples = this.fmp4Demuxer.extractSamples(moof, mdatData, mdatOffset);
|
|
1775
1796
|
for (const sample of samples) {
|
|
1776
1797
|
this._sampleQueue.push({ sample });
|
|
1777
1798
|
}
|
|
1778
|
-
|
|
1799
|
+
totalSampleCount += samples.length;
|
|
1779
1800
|
}
|
|
1780
|
-
return
|
|
1801
|
+
return totalSampleCount;
|
|
1781
1802
|
}
|
|
1782
1803
|
/**
|
|
1783
1804
|
* 解析 TS 数据
|
|
@@ -1842,6 +1863,45 @@ class HLSPlayer extends BasePlayer {
|
|
|
1842
1863
|
throw new Error("Failed to parse fMP4 init segment: no valid codec config found");
|
|
1843
1864
|
}
|
|
1844
1865
|
}
|
|
1866
|
+
/**
|
|
1867
|
+
* 加载新的初始化段(用于不连续性流)
|
|
1868
|
+
*/
|
|
1869
|
+
async loadNewInitSegment(uri) {
|
|
1870
|
+
console.log("[fMP4] Loading new init segment for discontinuity:", uri);
|
|
1871
|
+
this._sampleQueue.length = 0;
|
|
1872
|
+
this._nalQueue.length = 0;
|
|
1873
|
+
this.frameBuffer = [];
|
|
1874
|
+
const url = uri.startsWith("http") ? uri : this.currentPlaylistUrl.substring(0, this.currentPlaylistUrl.lastIndexOf("/") + 1) + uri;
|
|
1875
|
+
const response = await fetch(url);
|
|
1876
|
+
const data = new Uint8Array(await response.arrayBuffer());
|
|
1877
|
+
console.log("[fMP4] New init segment data size:", data.length, "bytes");
|
|
1878
|
+
const initInfo = this.fmp4Demuxer.parseInitSegment(data);
|
|
1879
|
+
console.log("[fMP4] New init segment parse result:", {
|
|
1880
|
+
isHevc: initInfo?.isHevc,
|
|
1881
|
+
hasAvcC: !!initInfo?.avcC,
|
|
1882
|
+
hasHvcC: !!initInfo?.hvcC
|
|
1883
|
+
});
|
|
1884
|
+
const newIsHevc = initInfo?.isHevc ?? false;
|
|
1885
|
+
if (newIsHevc !== this._isHevc) {
|
|
1886
|
+
console.log("[fMP4] Codec type changed from", this._isHevc ? "HEVC" : "AVC", "to", newIsHevc ? "HEVC" : "AVC");
|
|
1887
|
+
this._isHevc = newIsHevc;
|
|
1888
|
+
this.decoderInitialized = false;
|
|
1889
|
+
if (newIsHevc) {
|
|
1890
|
+
await this.initHevcDecoder();
|
|
1891
|
+
}
|
|
1892
|
+
} else {
|
|
1893
|
+
this.decoderInitialized = false;
|
|
1894
|
+
}
|
|
1895
|
+
if (initInfo?.hvcC && this._isHevc) {
|
|
1896
|
+
this.initDecoderFromHvcC(initInfo.hvcC);
|
|
1897
|
+
console.log("[fMP4] HEVC decoder re-initialized for discontinuity");
|
|
1898
|
+
} else if (initInfo?.avcC) {
|
|
1899
|
+
this.initDecoderFromAvcC(initInfo.avcC);
|
|
1900
|
+
console.log("[fMP4] AVC decoder re-initialized for discontinuity");
|
|
1901
|
+
} else {
|
|
1902
|
+
console.error("[fMP4] Failed to parse new init segment!");
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1845
1905
|
/**
|
|
1846
1906
|
* 初始化 HEVC 解码器
|
|
1847
1907
|
*/
|
|
@@ -1961,25 +2021,31 @@ class HLSPlayer extends BasePlayer {
|
|
|
1961
2021
|
}
|
|
1962
2022
|
const isFMP4 = lines.some((line) => line.includes("#EXT-X-MAP:"));
|
|
1963
2023
|
console.log("[parsePlaylist] isFMP4:", isFMP4, "url:", url);
|
|
2024
|
+
let currentInitSegment;
|
|
1964
2025
|
for (let i = 0; i < lines.length; i++) {
|
|
1965
2026
|
const line = lines[i].trim();
|
|
1966
2027
|
if (line.startsWith("#EXT-X-MAP:")) {
|
|
1967
2028
|
const mapInfo = line.substring("#EXT-X-MAP:".length);
|
|
1968
2029
|
const uriMatch = mapInfo.match(/URI="([^"]+)"/);
|
|
1969
2030
|
if (uriMatch) {
|
|
1970
|
-
|
|
2031
|
+
currentInitSegment = { uri: uriMatch[1] };
|
|
1971
2032
|
const byteRangeMatch = mapInfo.match(/BYTERANGE="(\d+)@(\d+)"/);
|
|
1972
2033
|
if (byteRangeMatch) {
|
|
1973
|
-
|
|
2034
|
+
currentInitSegment.byteRange = {
|
|
1974
2035
|
start: parseInt(byteRangeMatch[2]),
|
|
1975
2036
|
end: parseInt(byteRangeMatch[2]) + parseInt(byteRangeMatch[1]) - 1
|
|
1976
2037
|
};
|
|
1977
2038
|
}
|
|
2039
|
+
if (!initSegment) {
|
|
2040
|
+
initSegment = currentInitSegment;
|
|
2041
|
+
}
|
|
1978
2042
|
}
|
|
2043
|
+
continue;
|
|
2044
|
+
}
|
|
2045
|
+
if (line === "#EXT-X-DISCONTINUITY") {
|
|
2046
|
+
console.log("[parsePlaylist] Found EXT-X-DISCONTINUITY");
|
|
2047
|
+
continue;
|
|
1979
2048
|
}
|
|
1980
|
-
}
|
|
1981
|
-
for (let i = 0; i < lines.length; i++) {
|
|
1982
|
-
const line = lines[i].trim();
|
|
1983
2049
|
if (line.startsWith("#EXTINF:")) {
|
|
1984
2050
|
const duration = parseFloat(line.split(":")[1].split(",")[0]);
|
|
1985
2051
|
let byteRange;
|
|
@@ -1997,7 +2063,13 @@ class HLSPlayer extends BasePlayer {
|
|
|
1997
2063
|
const uri = nextLine;
|
|
1998
2064
|
if (uri && !uri.startsWith("#")) {
|
|
1999
2065
|
if (isFMP4) {
|
|
2000
|
-
fmp4Segments.push({
|
|
2066
|
+
fmp4Segments.push({
|
|
2067
|
+
uri,
|
|
2068
|
+
duration,
|
|
2069
|
+
byteRange,
|
|
2070
|
+
initSegmentUri: currentInitSegment?.uri
|
|
2071
|
+
// 关联当前初始化段
|
|
2072
|
+
});
|
|
2001
2073
|
} else {
|
|
2002
2074
|
segments.push({ uri, duration });
|
|
2003
2075
|
}
|