Try to prefer transmux instead of transcode (not sure yet)

This commit is contained in:
Zoe Roux 2024-02-18 15:38:37 +01:00
parent 7f6721147a
commit 79dc4e5f33
5 changed files with 61 additions and 55 deletions

View File

@ -27,7 +27,7 @@
"expo-image-picker": "~14.7.1",
"expo-linear-gradient": "^12.7.1",
"expo-modules-core": "^1.11.8",
"hls.js": "^1.5.2",
"hls.js": "^1.5.6",
"i18next": "^23.7.20",
"jassub": "^1.7.15",
"jotai": "^2.6.3",

View File

@ -49,10 +49,8 @@ function uuidv4(): string {
let client_id = typeof window === "undefined" ? "ssr" : uuidv4();
const initHls = async (): Promise<Hls> => {
const initHls = (): Hls => {
if (hls !== null) return hls;
const token = await getToken();
const loadPolicy: LoadPolicy = {
default: {
maxTimeToFirstByteMs: Infinity,
@ -70,12 +68,17 @@ const initHls = async (): Promise<Hls> => {
},
};
hls = new Hls({
xhrSetup: (xhr) => {
xhrSetup: async (xhr) => {
const token = await getToken();
if (token) xhr.setRequestHeader("Authorization", `Bearer: ${token}`);
xhr.setRequestHeader("X-CLIENT-ID", client_id);
},
autoStartLoad: false,
startLevel: Infinity,
abrEwmaDefaultEstimate: 35_000_000,
abrEwmaDefaultEstimateMax: 50_000_000,
// debug: true,
lowLatencyMode: false,
fragLoadPolicy: {
default: {
maxTimeToFirstByteMs: Infinity,
@ -98,9 +101,6 @@ const initHls = async (): Promise<Hls> => {
manifestLoadPolicy: loadPolicy,
steeringManifestLoadPolicy: loadPolicy,
});
hls.on(Hls.Events.MANIFEST_PARSED, () => {
if (hls) hls.startLevel = hls.firstLevel;
});
return hls;
};
@ -149,31 +149,29 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
useSubtitle(ref, subtitle, fonts);
useLayoutEffect(() => {
(async () => {
if (!ref?.current || !source.uri) return;
if (!hls || oldHls.current !== source.hls) {
// Reinit the hls player when we change track.
if (hls) hls.destroy();
hls = null;
hls = await initHls();
hls.loadSource(source.hls!);
oldHls.current = source.hls;
}
if (!source.uri.endsWith(".m3u8")) {
hls.detachMedia();
ref.current.src = source.uri;
} else {
hls.attachMedia(ref.current);
hls.startLoad(source.startPosition ? source.startPosition / 1000 : 0);
hls.on(Hls.Events.ERROR, (_, d) => {
if (!d.fatal || !hls?.media) return;
console.warn("Hls error", d);
onError?.call(null, {
error: { errorString: d.reason ?? d.error?.message ?? "Unknown hls error" },
});
if (!ref?.current || !source.uri) return;
if (!hls || oldHls.current !== source.hls) {
// Reinit the hls player when we change track.
if (hls) hls.destroy();
hls = null;
hls = initHls();
hls.loadSource(source.hls!);
oldHls.current = source.hls;
}
if (!source.uri.endsWith(".m3u8")) {
hls.detachMedia();
ref.current.src = source.uri;
} else {
hls.attachMedia(ref.current);
hls.startLoad(source.startPosition ? source.startPosition / 1000 : 0);
hls.on(Hls.Events.ERROR, (_, d) => {
if (!d.fatal || !hls?.media) return;
console.warn("Hls error", d);
onError?.call(null, {
error: { errorString: d.reason ?? d.error?.message ?? "Unknown hls error" },
});
}
})();
});
}
// onError changes should not restart the playback.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [source.uri, source.hls]);

View File

@ -8465,10 +8465,10 @@ __metadata:
languageName: node
linkType: hard
"hls.js@npm:^1.5.2":
version: 1.5.2
resolution: "hls.js@npm:1.5.2"
checksum: fb03209ca3b691e996c3d0b83dac2bcc63dba468f9c24b7414d1dc9b950c3ac0fdcfc2349d8b16d98a96c6fbe35c2836d5740a832d1844451187be4749469957
"hls.js@npm:^1.5.6":
version: 1.5.6
resolution: "hls.js@npm:1.5.6"
checksum: 685564b223955267194ec1089179717e040354a92e0269dd72150598b422448cede1cb4882c0c63b8124f42d823e156b6433bbd3048443c4d4ff29cae3ec4efa
languageName: node
linkType: hard
@ -14023,7 +14023,7 @@ __metadata:
expo-image-picker: ~14.7.1
expo-linear-gradient: ^12.7.1
expo-modules-core: ^1.11.8
hls.js: ^1.5.2
hls.js: ^1.5.6
i18next: ^23.7.20
jassub: ^1.7.15
jotai: ^2.6.3

View File

@ -153,10 +153,18 @@ func (fs *FileStream) GetMaster() string {
master := "#EXTM3U\n"
// TODO: also check if the codec is valid in a hls before putting transmux
if fs.Info.Video != nil {
var transmux_quality Quality
for _, quality := range Qualities {
if quality.Height() >= fs.Info.Video.Quality.Height() || quality.AverageBitrate() >= fs.Info.Video.Bitrate {
transmux_quality = quality
break
}
}
if fs.CanTransmux {
bitrate := float64(fs.Info.Video.Bitrate)
master += "#EXT-X-STREAM-INF:"
master += fmt.Sprintf("AVERAGE-BANDWIDTH=%d,", fs.Info.Video.Bitrate)
master += fmt.Sprintf("BANDWIDTH=%d,", int(float32(fs.Info.Video.Bitrate)*1.2))
master += fmt.Sprintf("AVERAGE-BANDWIDTH=%d,", int(math.Min(bitrate*0.8, float64(transmux_quality.AverageBitrate()))))
master += fmt.Sprintf("BANDWIDTH=%d,", int(math.Min(bitrate, float64(transmux_quality.MaxBitrate()))))
master += fmt.Sprintf("RESOLUTION=%dx%d,", fs.Info.Video.Width, fs.Info.Video.Height)
master += "AUDIO=\"audio\","
master += "CLOSED-CAPTIONS=NONE\n"

View File

@ -41,21 +41,21 @@ func QualityFromString(str string) (Quality, error) {
func (v Quality) AverageBitrate() uint32 {
switch v {
case P240:
return 400000
return 400_000
case P360:
return 800000
return 800_000
case P480:
return 1200000
return 1_200_000
case P720:
return 2400000
return 2_400_000
case P1080:
return 4800000
return 4_800_000
case P1440:
return 9600000
return 9_600_000
case P4k:
return 16000000
return 16_000_000
case P8k:
return 28000000
return 28_000_000
case Original:
panic("Original quality must be handled specially")
}
@ -65,21 +65,21 @@ func (v Quality) AverageBitrate() uint32 {
func (v Quality) MaxBitrate() uint32 {
switch v {
case P240:
return 700000
return 700_000
case P360:
return 1400000
return 1_400_000
case P480:
return 2100000
return 2_100_000
case P720:
return 4000000
return 4_000_000
case P1080:
return 8000000
return 8_000_000
case P1440:
return 12000000
return 12_000_000
case P4k:
return 28000000
return 28_000_000
case P8k:
return 40000000
return 40_000_000
case Original:
panic("Original quality must be handled specially")
}