avbridge 2.2.1 → 2.5.0
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/CHANGELOG.md +153 -1
- package/NOTICE.md +2 -2
- package/README.md +2 -3
- package/THIRD_PARTY_LICENSES.md +2 -2
- package/dist/avi-2JPBSHGA.js +183 -0
- package/dist/avi-2JPBSHGA.js.map +1 -0
- package/dist/avi-F6WZJK5T.cjs +185 -0
- package/dist/avi-F6WZJK5T.cjs.map +1 -0
- package/dist/{avi-GCGM7OJI.js → avi-NJXAXUXK.js} +9 -3
- package/dist/avi-NJXAXUXK.js.map +1 -0
- package/dist/{avi-6SJLWIWW.cjs → avi-W6L3BTWU.cjs} +10 -4
- package/dist/avi-W6L3BTWU.cjs.map +1 -0
- package/dist/chunk-2IJ66NTD.cjs +212 -0
- package/dist/chunk-2IJ66NTD.cjs.map +1 -0
- package/dist/{chunk-ILKDNBSE.js → chunk-2XW2O3YI.cjs} +55 -10
- package/dist/chunk-2XW2O3YI.cjs.map +1 -0
- package/dist/chunk-5KVLE6YI.js +167 -0
- package/dist/chunk-5KVLE6YI.js.map +1 -0
- package/dist/chunk-5YAWWKA3.js +18 -0
- package/dist/chunk-5YAWWKA3.js.map +1 -0
- package/dist/chunk-CPJLFFCC.js +189 -0
- package/dist/chunk-CPJLFFCC.js.map +1 -0
- package/dist/chunk-CPZ7PXAM.cjs +240 -0
- package/dist/chunk-CPZ7PXAM.cjs.map +1 -0
- package/dist/{chunk-WD2ZNQA7.js → chunk-DCSOQH2N.js} +7 -4
- package/dist/chunk-DCSOQH2N.js.map +1 -0
- package/dist/{chunk-HZLQNKFN.cjs → chunk-E76AMWI4.js} +40 -15
- package/dist/chunk-E76AMWI4.js.map +1 -0
- package/dist/chunk-F3LQJKXK.cjs +20 -0
- package/dist/chunk-F3LQJKXK.cjs.map +1 -0
- package/dist/chunk-IAYKFGFG.js +200 -0
- package/dist/chunk-IAYKFGFG.js.map +1 -0
- package/dist/{chunk-DMWARSEF.js → chunk-KY2GPCT7.js} +788 -697
- package/dist/chunk-KY2GPCT7.js.map +1 -0
- package/dist/chunk-LUFA47FP.js +19 -0
- package/dist/chunk-LUFA47FP.js.map +1 -0
- package/dist/chunk-NNVOHKXJ.cjs +204 -0
- package/dist/chunk-NNVOHKXJ.cjs.map +1 -0
- package/dist/chunk-Q2VUO52Z.cjs +374 -0
- package/dist/chunk-Q2VUO52Z.cjs.map +1 -0
- package/dist/chunk-QDJLQR53.cjs +22 -0
- package/dist/chunk-QDJLQR53.cjs.map +1 -0
- package/dist/chunk-S4WAZC2T.cjs +173 -0
- package/dist/chunk-S4WAZC2T.cjs.map +1 -0
- package/dist/chunk-SMH6IOP2.js +368 -0
- package/dist/chunk-SMH6IOP2.js.map +1 -0
- package/dist/chunk-SR3MPV4D.js +237 -0
- package/dist/chunk-SR3MPV4D.js.map +1 -0
- package/dist/{chunk-UF2N5L63.cjs → chunk-TBW26OPP.cjs} +800 -710
- package/dist/chunk-TBW26OPP.cjs.map +1 -0
- package/dist/chunk-X2K3GIWE.js +235 -0
- package/dist/chunk-X2K3GIWE.js.map +1 -0
- package/dist/{chunk-L4NPOJ36.cjs → chunk-Z33SBWL5.cjs} +7 -4
- package/dist/chunk-Z33SBWL5.cjs.map +1 -0
- package/dist/chunk-ZCUXHW55.cjs +242 -0
- package/dist/chunk-ZCUXHW55.cjs.map +1 -0
- package/dist/element-browser.js +1282 -503
- package/dist/element-browser.js.map +1 -1
- package/dist/element.cjs +59 -5
- package/dist/element.cjs.map +1 -1
- package/dist/element.d.cts +39 -1
- package/dist/element.d.ts +39 -1
- package/dist/element.js +58 -4
- package/dist/element.js.map +1 -1
- package/dist/index.cjs +605 -327
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -4
- package/dist/index.d.ts +48 -4
- package/dist/index.js +528 -319
- package/dist/index.js.map +1 -1
- package/dist/libav-demux-H2GS46GH.cjs +27 -0
- package/dist/{libav-http-reader-NQJVY273.js.map → libav-demux-H2GS46GH.cjs.map} +1 -1
- package/dist/libav-demux-OWZ4T2YW.js +6 -0
- package/dist/{libav-http-reader-FPYDBMYK.cjs.map → libav-demux-OWZ4T2YW.js.map} +1 -1
- package/dist/libav-http-reader-AZLE7YFS.cjs +16 -0
- package/dist/libav-http-reader-AZLE7YFS.cjs.map +1 -0
- package/dist/libav-http-reader-WXG3Z7AI.js +3 -0
- package/dist/libav-http-reader-WXG3Z7AI.js.map +1 -0
- package/dist/{libav-import-GST2AMPL.cjs → libav-import-2ZVKV2E7.cjs} +2 -2
- package/dist/{libav-import-GST2AMPL.cjs.map → libav-import-2ZVKV2E7.cjs.map} +1 -1
- package/dist/{libav-import-2JURFHEW.js → libav-import-6MGLCXVQ.js} +2 -2
- package/dist/{libav-import-2JURFHEW.js.map → libav-import-6MGLCXVQ.js.map} +1 -1
- package/dist/{player-U2NPmFvA.d.cts → player-B6WB74RD.d.cts} +62 -3
- package/dist/{player-U2NPmFvA.d.ts → player-B6WB74RD.d.ts} +62 -3
- package/dist/player.cjs +5631 -0
- package/dist/player.cjs.map +1 -0
- package/dist/player.d.cts +699 -0
- package/dist/player.d.ts +699 -0
- package/dist/player.js +5629 -0
- package/dist/player.js.map +1 -0
- package/dist/remux-OBSMIENG.cjs +35 -0
- package/dist/remux-OBSMIENG.cjs.map +1 -0
- package/dist/remux-WBYIZBBX.js +10 -0
- package/dist/remux-WBYIZBBX.js.map +1 -0
- package/dist/source-4TZ6KMNV.js +4 -0
- package/dist/{source-FFZ7TW2B.js.map → source-4TZ6KMNV.js.map} +1 -1
- package/dist/source-7YLO6E7X.cjs +29 -0
- package/dist/{source-CN43EI7Z.cjs.map → source-7YLO6E7X.cjs.map} +1 -1
- package/dist/source-MTX5ELUZ.js +4 -0
- package/dist/source-MTX5ELUZ.js.map +1 -0
- package/dist/source-VFLXLOCN.cjs +29 -0
- package/dist/source-VFLXLOCN.cjs.map +1 -0
- package/dist/subtitles-4T74JRGT.js +4 -0
- package/dist/subtitles-4T74JRGT.js.map +1 -0
- package/dist/subtitles-QUH4LPI4.cjs +29 -0
- package/dist/subtitles-QUH4LPI4.cjs.map +1 -0
- package/dist/variant-routing-434STYAB.js +3 -0
- package/dist/{variant-routing-JOBWXYKD.js.map → variant-routing-434STYAB.js.map} +1 -1
- package/dist/variant-routing-HONNAA6R.cjs +12 -0
- package/dist/{variant-routing-GOHB2RZN.cjs.map → variant-routing-HONNAA6R.cjs.map} +1 -1
- package/package.json +9 -1
- package/src/classify/rules.ts +27 -5
- package/src/convert/remux.ts +9 -35
- package/src/convert/transcode-libav.ts +691 -0
- package/src/convert/transcode.ts +53 -12
- package/src/element/avbridge-player.ts +861 -0
- package/src/element/avbridge-video.ts +54 -0
- package/src/element/player-icons.ts +25 -0
- package/src/element/player-styles.ts +472 -0
- package/src/errors.ts +53 -0
- package/src/index.ts +23 -0
- package/src/player-element.ts +18 -0
- package/src/player.ts +118 -27
- package/src/plugins/builtin.ts +2 -2
- package/src/probe/avi.ts +4 -0
- package/src/probe/index.ts +40 -10
- package/src/strategies/fallback/audio-output.ts +31 -0
- package/src/strategies/fallback/decoder.ts +179 -175
- package/src/strategies/fallback/index.ts +48 -6
- package/src/strategies/fallback/libav-import.ts +9 -1
- package/src/strategies/fallback/variant-routing.ts +7 -13
- package/src/strategies/fallback/video-renderer.ts +231 -32
- package/src/strategies/hybrid/decoder.ts +219 -200
- package/src/strategies/hybrid/index.ts +48 -7
- package/src/strategies/native.ts +6 -3
- package/src/strategies/remux/index.ts +14 -2
- package/src/strategies/remux/mse.ts +12 -2
- package/src/strategies/remux/pipeline.ts +72 -12
- package/src/subtitles/index.ts +7 -3
- package/src/subtitles/render.ts +8 -0
- package/src/types.ts +53 -1
- package/src/util/libav-demux.ts +405 -0
- package/src/util/libav-http-reader.ts +5 -1
- package/src/util/source.ts +28 -8
- package/src/util/transport.ts +26 -0
- package/vendor/libav/avbridge/libav-6.8.8.0-avbridge.wasm.mjs +1 -1
- package/vendor/libav/avbridge/libav-6.8.8.0-avbridge.wasm.wasm +0 -0
- package/dist/avi-6SJLWIWW.cjs.map +0 -1
- package/dist/avi-GCGM7OJI.js.map +0 -1
- package/dist/chunk-DMWARSEF.js.map +0 -1
- package/dist/chunk-HZLQNKFN.cjs.map +0 -1
- package/dist/chunk-ILKDNBSE.js.map +0 -1
- package/dist/chunk-J5MCMN3S.js +0 -27
- package/dist/chunk-J5MCMN3S.js.map +0 -1
- package/dist/chunk-L4NPOJ36.cjs.map +0 -1
- package/dist/chunk-NZU7W256.cjs +0 -29
- package/dist/chunk-NZU7W256.cjs.map +0 -1
- package/dist/chunk-UF2N5L63.cjs.map +0 -1
- package/dist/chunk-WD2ZNQA7.js.map +0 -1
- package/dist/libav-http-reader-FPYDBMYK.cjs +0 -16
- package/dist/libav-http-reader-NQJVY273.js +0 -3
- package/dist/source-CN43EI7Z.cjs +0 -28
- package/dist/source-FFZ7TW2B.js +0 -3
- package/dist/variant-routing-GOHB2RZN.cjs +0 -12
- package/dist/variant-routing-JOBWXYKD.js +0 -3
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkQ2VUO52Z_cjs = require('./chunk-Q2VUO52Z.cjs');
|
|
4
|
+
require('./chunk-ZCUXHW55.cjs');
|
|
5
|
+
require('./chunk-2IJ66NTD.cjs');
|
|
6
|
+
require('./chunk-QDJLQR53.cjs');
|
|
7
|
+
require('./chunk-CPZ7PXAM.cjs');
|
|
8
|
+
require('./chunk-Z33SBWL5.cjs');
|
|
9
|
+
require('./chunk-G4APZMCP.cjs');
|
|
10
|
+
require('./chunk-F3LQJKXK.cjs');
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Object.defineProperty(exports, "createOutputFormat", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return chunkQ2VUO52Z_cjs.createOutputFormat; }
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "generateFilename", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return chunkQ2VUO52Z_cjs.generateFilename; }
|
|
21
|
+
});
|
|
22
|
+
Object.defineProperty(exports, "mimeForFormat", {
|
|
23
|
+
enumerable: true,
|
|
24
|
+
get: function () { return chunkQ2VUO52Z_cjs.mimeForFormat; }
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(exports, "remux", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function () { return chunkQ2VUO52Z_cjs.remux; }
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "validateRemuxEligibility", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () { return chunkQ2VUO52Z_cjs.validateRemuxEligibility; }
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=remux-OBSMIENG.cjs.map
|
|
35
|
+
//# sourceMappingURL=remux-OBSMIENG.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"remux-OBSMIENG.cjs"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { createOutputFormat, generateFilename, mimeForFormat, remux, validateRemuxEligibility } from './chunk-SMH6IOP2.js';
|
|
2
|
+
import './chunk-SR3MPV4D.js';
|
|
3
|
+
import './chunk-CPJLFFCC.js';
|
|
4
|
+
import './chunk-LUFA47FP.js';
|
|
5
|
+
import './chunk-X2K3GIWE.js';
|
|
6
|
+
import './chunk-DCSOQH2N.js';
|
|
7
|
+
import './chunk-5DMTJVIU.js';
|
|
8
|
+
import './chunk-5YAWWKA3.js';
|
|
9
|
+
//# sourceMappingURL=remux-WBYIZBBX.js.map
|
|
10
|
+
//# sourceMappingURL=remux-WBYIZBBX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"remux-WBYIZBBX.js"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"source-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"source-4TZ6KMNV.js"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk2XW2O3YI_cjs = require('./chunk-2XW2O3YI.cjs');
|
|
4
|
+
require('./chunk-QDJLQR53.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "isInMemorySource", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunk2XW2O3YI_cjs.isInMemorySource; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "normalizeSource", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunk2XW2O3YI_cjs.normalizeSource; }
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "sniffContainer", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return chunk2XW2O3YI_cjs.sniffContainer; }
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(exports, "sniffContainerFromBytes", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return chunk2XW2O3YI_cjs.sniffContainerFromBytes; }
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "sniffNormalizedSource", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () { return chunk2XW2O3YI_cjs.sniffNormalizedSource; }
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=source-7YLO6E7X.cjs.map
|
|
29
|
+
//# sourceMappingURL=source-7YLO6E7X.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"source-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"source-7YLO6E7X.cjs"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"source-MTX5ELUZ.js"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk2IJ66NTD_cjs = require('./chunk-2IJ66NTD.cjs');
|
|
4
|
+
require('./chunk-QDJLQR53.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "isInMemorySource", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunk2IJ66NTD_cjs.isInMemorySource; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "normalizeSource", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunk2IJ66NTD_cjs.normalizeSource; }
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "sniffContainer", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return chunk2IJ66NTD_cjs.sniffContainer; }
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(exports, "sniffContainerFromBytes", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return chunk2IJ66NTD_cjs.sniffContainerFromBytes; }
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "sniffNormalizedSource", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () { return chunk2IJ66NTD_cjs.sniffNormalizedSource; }
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=source-VFLXLOCN.cjs.map
|
|
29
|
+
//# sourceMappingURL=source-VFLXLOCN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"source-VFLXLOCN.cjs"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"subtitles-4T74JRGT.js"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkS4WAZC2T_cjs = require('./chunk-S4WAZC2T.cjs');
|
|
4
|
+
require('./chunk-QDJLQR53.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "SubtitleOverlay", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkS4WAZC2T_cjs.SubtitleOverlay; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "SubtitleResourceBag", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunkS4WAZC2T_cjs.SubtitleResourceBag; }
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "attachSubtitleTracks", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return chunkS4WAZC2T_cjs.attachSubtitleTracks; }
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(exports, "discoverSidecars", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return chunkS4WAZC2T_cjs.discoverSidecars; }
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "srtToVtt", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () { return chunkS4WAZC2T_cjs.srtToVtt; }
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=subtitles-QUH4LPI4.cjs.map
|
|
29
|
+
//# sourceMappingURL=subtitles-QUH4LPI4.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"subtitles-QUH4LPI4.cjs"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"variant-routing-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"variant-routing-434STYAB.js"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkF3LQJKXK_cjs = require('./chunk-F3LQJKXK.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
Object.defineProperty(exports, "pickLibavVariant", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () { return chunkF3LQJKXK_cjs.pickLibavVariant; }
|
|
10
|
+
});
|
|
11
|
+
//# sourceMappingURL=variant-routing-HONNAA6R.cjs.map
|
|
12
|
+
//# sourceMappingURL=variant-routing-HONNAA6R.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"variant-routing-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"variant-routing-HONNAA6R.cjs"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "avbridge",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "Play and convert arbitrary video files in the browser. Native, remux, hybrid, fallback, and transcode — one API.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Keishi Hattori",
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
"sideEffects": [
|
|
36
36
|
"./dist/element.js",
|
|
37
37
|
"./dist/element.cjs",
|
|
38
|
+
"./dist/player.js",
|
|
39
|
+
"./dist/player.cjs",
|
|
38
40
|
"./dist/element-browser.js"
|
|
39
41
|
],
|
|
40
42
|
"main": "./dist/index.cjs",
|
|
@@ -51,6 +53,11 @@
|
|
|
51
53
|
"import": "./dist/element.js",
|
|
52
54
|
"require": "./dist/element.cjs"
|
|
53
55
|
},
|
|
56
|
+
"./player": {
|
|
57
|
+
"types": "./dist/player.d.ts",
|
|
58
|
+
"import": "./dist/player.js",
|
|
59
|
+
"require": "./dist/player.cjs"
|
|
60
|
+
},
|
|
54
61
|
"./element-browser": {
|
|
55
62
|
"types": "./dist/element.d.ts",
|
|
56
63
|
"import": "./dist/element-browser.js"
|
|
@@ -83,6 +90,7 @@
|
|
|
83
90
|
"test:playback": "node scripts/playback-test.mjs",
|
|
84
91
|
"test:convert": "node scripts/convert-test.mjs",
|
|
85
92
|
"test:element": "node scripts/element-test.mjs",
|
|
93
|
+
"test:player-controls": "node scripts/player-controls-test.mjs",
|
|
86
94
|
"test:url-streaming": "node scripts/url-streaming-test.mjs",
|
|
87
95
|
"fixtures": "node scripts/generate-fixtures.mjs",
|
|
88
96
|
"audit:bundle": "node scripts/bundle-audit.mjs"
|
package/src/classify/rules.ts
CHANGED
|
@@ -13,8 +13,9 @@ import { mp4MimeFor, mseSupports } from "../util/codec-strings.js";
|
|
|
13
13
|
* Codecs we know `<video>` and MSE support across modern desktop + Android.
|
|
14
14
|
* The decision to remux instead of decode hinges on this list.
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
const
|
|
16
|
+
/** Codecs the browser can decode natively (also the set WebCodecs can transcode). */
|
|
17
|
+
export const NATIVE_VIDEO_CODECS = new Set<VideoCodec>(["h264", "h265", "vp8", "vp9", "av1"]);
|
|
18
|
+
export const NATIVE_AUDIO_CODECS = new Set<AudioCodec>([
|
|
18
19
|
"aac",
|
|
19
20
|
"mp3",
|
|
20
21
|
"opus",
|
|
@@ -25,14 +26,15 @@ const NATIVE_AUDIO_CODECS = new Set<AudioCodec>([
|
|
|
25
26
|
/**
|
|
26
27
|
* Codecs no major browser plays, period. These force the WASM fallback.
|
|
27
28
|
*/
|
|
28
|
-
const FALLBACK_VIDEO_CODECS = new Set<VideoCodec>([
|
|
29
|
+
export const FALLBACK_VIDEO_CODECS = new Set<VideoCodec>([
|
|
29
30
|
"wmv3", "vc1", "mpeg4",
|
|
30
31
|
"rv10", "rv20", "rv30", "rv40",
|
|
31
32
|
"mpeg2", "mpeg1", "theora",
|
|
32
33
|
]);
|
|
33
|
-
const FALLBACK_AUDIO_CODECS = new Set<AudioCodec>([
|
|
34
|
+
export const FALLBACK_AUDIO_CODECS = new Set<AudioCodec>([
|
|
34
35
|
"wmav2", "wmapro", "ac3", "eac3",
|
|
35
36
|
"cook", "ra_144", "ra_288", "sipr", "atrac3",
|
|
37
|
+
"dts", "truehd",
|
|
36
38
|
]);
|
|
37
39
|
|
|
38
40
|
/**
|
|
@@ -120,7 +122,27 @@ export function classifyContext(ctx: MediaContext): Classification {
|
|
|
120
122
|
reason: `video codec "${video.codec}" has no browser decoder; WASM fallback required`,
|
|
121
123
|
};
|
|
122
124
|
}
|
|
123
|
-
|
|
125
|
+
// Audio codec needs WASM decode — either it's in the known fallback set
|
|
126
|
+
// or it's unrecognized ("unknown" / not in native set). Unknown codecs
|
|
127
|
+
// definitely can't play natively, so they get the same treatment.
|
|
128
|
+
const audioNeedsFallback = audio && (
|
|
129
|
+
FALLBACK_AUDIO_CODECS.has(audio.codec) ||
|
|
130
|
+
!NATIVE_AUDIO_CODECS.has(audio.codec)
|
|
131
|
+
);
|
|
132
|
+
if (audioNeedsFallback) {
|
|
133
|
+
// If the VIDEO codec is native, prefer hybrid (WebCodecs hardware video
|
|
134
|
+
// decode + libav software audio decode) over full WASM fallback. This is
|
|
135
|
+
// critical for Blu-ray MKVs: H.264 1080p in WASM is unwatchably slow,
|
|
136
|
+
// but WebCodecs decodes it at full speed while libav handles the DTS/AC3
|
|
137
|
+
// audio in software.
|
|
138
|
+
if (NATIVE_VIDEO_CODECS.has(video.codec) && webCodecsAvailable()) {
|
|
139
|
+
return {
|
|
140
|
+
class: "HYBRID_CANDIDATE",
|
|
141
|
+
strategy: "hybrid",
|
|
142
|
+
reason: `video "${video.codec}" is hardware-decodable via WebCodecs; audio "${audio.codec}" decoded in software by libav`,
|
|
143
|
+
fallbackChain: ["fallback"],
|
|
144
|
+
};
|
|
145
|
+
}
|
|
124
146
|
return {
|
|
125
147
|
class: "FALLBACK_REQUIRED",
|
|
126
148
|
strategy: "fallback",
|
package/src/convert/remux.ts
CHANGED
|
@@ -11,12 +11,14 @@
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { probe } from "../probe/index.js";
|
|
14
|
+
import { isAnnexB, annexBToAvcc } from "../strategies/remux/annexb.js";
|
|
14
15
|
import {
|
|
15
16
|
avbridgeVideoToMediabunny,
|
|
16
17
|
avbridgeAudioToMediabunny,
|
|
17
18
|
buildMediabunnySourceFromInput,
|
|
18
19
|
} from "../probe/mediabunny.js";
|
|
19
20
|
import { normalizeSource } from "../util/source.js";
|
|
21
|
+
import { sanitizePacketTimestamp } from "../util/libav-demux.js";
|
|
20
22
|
import { prepareLibavInput, type LibavInputHandle } from "../util/libav-http-reader.js";
|
|
21
23
|
import type {
|
|
22
24
|
MediaInput,
|
|
@@ -304,6 +306,13 @@ async function doLibavRemux(
|
|
|
304
306
|
return ts;
|
|
305
307
|
}, videoTimeBase);
|
|
306
308
|
|
|
309
|
+
// libav demuxes AVI/ASF/FLV H.264 as Annex B (start-code framed),
|
|
310
|
+
// but mediabunny's fMP4 muxer expects AVCC (length-prefixed). Convert
|
|
311
|
+
// on the fly. The check is cheap: isAnnexB reads 4 bytes at the head.
|
|
312
|
+
if (videoTrackInfo && (videoTrackInfo.codec === "h264" || videoTrackInfo.codec === "h265") && isAnnexB(pkt.data)) {
|
|
313
|
+
pkt.data = annexBToAvcc(pkt.data);
|
|
314
|
+
}
|
|
315
|
+
|
|
307
316
|
const mbPacket = libavPacketToMediAbunny(mb, pkt);
|
|
308
317
|
await videoSource.add(
|
|
309
318
|
mbPacket,
|
|
@@ -377,41 +386,6 @@ async function doLibavRemux(
|
|
|
377
386
|
};
|
|
378
387
|
}
|
|
379
388
|
|
|
380
|
-
// ── Packet timestamp sanitizer (from hybrid/decoder.ts) ─────────────────────
|
|
381
|
-
|
|
382
|
-
function sanitizePacketTimestamp(
|
|
383
|
-
pkt: LibavPacket,
|
|
384
|
-
nextUs: () => number,
|
|
385
|
-
fallbackTimeBase?: [number, number],
|
|
386
|
-
): void {
|
|
387
|
-
const lo = pkt.pts ?? 0;
|
|
388
|
-
const hi = pkt.ptshi ?? 0;
|
|
389
|
-
const isInvalid = (hi === -2147483648 && lo === 0) || !Number.isFinite(lo);
|
|
390
|
-
if (isInvalid) {
|
|
391
|
-
const us = nextUs();
|
|
392
|
-
pkt.pts = us;
|
|
393
|
-
pkt.ptshi = 0;
|
|
394
|
-
pkt.time_base_num = 1;
|
|
395
|
-
pkt.time_base_den = 1_000_000;
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
const tb = fallbackTimeBase ?? [1, 1_000_000];
|
|
399
|
-
const pts64 = hi * 0x100000000 + lo;
|
|
400
|
-
const us = Math.round((pts64 * 1_000_000 * tb[0]) / tb[1]);
|
|
401
|
-
if (Number.isFinite(us) && Math.abs(us) <= Number.MAX_SAFE_INTEGER) {
|
|
402
|
-
pkt.pts = us;
|
|
403
|
-
pkt.ptshi = us < 0 ? -1 : 0;
|
|
404
|
-
pkt.time_base_num = 1;
|
|
405
|
-
pkt.time_base_den = 1_000_000;
|
|
406
|
-
return;
|
|
407
|
-
}
|
|
408
|
-
const fallback = nextUs();
|
|
409
|
-
pkt.pts = fallback;
|
|
410
|
-
pkt.ptshi = 0;
|
|
411
|
-
pkt.time_base_num = 1;
|
|
412
|
-
pkt.time_base_den = 1_000_000;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
389
|
// ── Helpers ─────────────────────────────────────────────────────────────────
|
|
416
390
|
|
|
417
391
|
/** @internal Exported for use by transcode(). */
|