mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-08 02:34:16 -04:00
Try to prefer transmux instead of transcode (not sure yet)
This commit is contained in:
parent
7f6721147a
commit
79dc4e5f33
@ -27,7 +27,7 @@
|
|||||||
"expo-image-picker": "~14.7.1",
|
"expo-image-picker": "~14.7.1",
|
||||||
"expo-linear-gradient": "^12.7.1",
|
"expo-linear-gradient": "^12.7.1",
|
||||||
"expo-modules-core": "^1.11.8",
|
"expo-modules-core": "^1.11.8",
|
||||||
"hls.js": "^1.5.2",
|
"hls.js": "^1.5.6",
|
||||||
"i18next": "^23.7.20",
|
"i18next": "^23.7.20",
|
||||||
"jassub": "^1.7.15",
|
"jassub": "^1.7.15",
|
||||||
"jotai": "^2.6.3",
|
"jotai": "^2.6.3",
|
||||||
|
@ -49,10 +49,8 @@ function uuidv4(): string {
|
|||||||
|
|
||||||
let client_id = typeof window === "undefined" ? "ssr" : uuidv4();
|
let client_id = typeof window === "undefined" ? "ssr" : uuidv4();
|
||||||
|
|
||||||
const initHls = async (): Promise<Hls> => {
|
const initHls = (): Hls => {
|
||||||
if (hls !== null) return hls;
|
if (hls !== null) return hls;
|
||||||
const token = await getToken();
|
|
||||||
|
|
||||||
const loadPolicy: LoadPolicy = {
|
const loadPolicy: LoadPolicy = {
|
||||||
default: {
|
default: {
|
||||||
maxTimeToFirstByteMs: Infinity,
|
maxTimeToFirstByteMs: Infinity,
|
||||||
@ -70,12 +68,17 @@ const initHls = async (): Promise<Hls> => {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
hls = new Hls({
|
hls = new Hls({
|
||||||
xhrSetup: (xhr) => {
|
xhrSetup: async (xhr) => {
|
||||||
|
const token = await getToken();
|
||||||
if (token) xhr.setRequestHeader("Authorization", `Bearer: ${token}`);
|
if (token) xhr.setRequestHeader("Authorization", `Bearer: ${token}`);
|
||||||
xhr.setRequestHeader("X-CLIENT-ID", client_id);
|
xhr.setRequestHeader("X-CLIENT-ID", client_id);
|
||||||
},
|
},
|
||||||
autoStartLoad: false,
|
autoStartLoad: false,
|
||||||
|
startLevel: Infinity,
|
||||||
|
abrEwmaDefaultEstimate: 35_000_000,
|
||||||
|
abrEwmaDefaultEstimateMax: 50_000_000,
|
||||||
// debug: true,
|
// debug: true,
|
||||||
|
lowLatencyMode: false,
|
||||||
fragLoadPolicy: {
|
fragLoadPolicy: {
|
||||||
default: {
|
default: {
|
||||||
maxTimeToFirstByteMs: Infinity,
|
maxTimeToFirstByteMs: Infinity,
|
||||||
@ -98,9 +101,6 @@ const initHls = async (): Promise<Hls> => {
|
|||||||
manifestLoadPolicy: loadPolicy,
|
manifestLoadPolicy: loadPolicy,
|
||||||
steeringManifestLoadPolicy: loadPolicy,
|
steeringManifestLoadPolicy: loadPolicy,
|
||||||
});
|
});
|
||||||
hls.on(Hls.Events.MANIFEST_PARSED, () => {
|
|
||||||
if (hls) hls.startLevel = hls.firstLevel;
|
|
||||||
});
|
|
||||||
return hls;
|
return hls;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -149,31 +149,29 @@ const Video = forwardRef<{ seek: (value: number) => void }, VideoProps>(function
|
|||||||
useSubtitle(ref, subtitle, fonts);
|
useSubtitle(ref, subtitle, fonts);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
(async () => {
|
if (!ref?.current || !source.uri) return;
|
||||||
if (!ref?.current || !source.uri) return;
|
if (!hls || oldHls.current !== source.hls) {
|
||||||
if (!hls || oldHls.current !== source.hls) {
|
// Reinit the hls player when we change track.
|
||||||
// Reinit the hls player when we change track.
|
if (hls) hls.destroy();
|
||||||
if (hls) hls.destroy();
|
hls = null;
|
||||||
hls = null;
|
hls = initHls();
|
||||||
hls = await initHls();
|
hls.loadSource(source.hls!);
|
||||||
hls.loadSource(source.hls!);
|
oldHls.current = source.hls;
|
||||||
oldHls.current = source.hls;
|
}
|
||||||
}
|
if (!source.uri.endsWith(".m3u8")) {
|
||||||
if (!source.uri.endsWith(".m3u8")) {
|
hls.detachMedia();
|
||||||
hls.detachMedia();
|
ref.current.src = source.uri;
|
||||||
ref.current.src = source.uri;
|
} else {
|
||||||
} else {
|
hls.attachMedia(ref.current);
|
||||||
hls.attachMedia(ref.current);
|
hls.startLoad(source.startPosition ? source.startPosition / 1000 : 0);
|
||||||
hls.startLoad(source.startPosition ? source.startPosition / 1000 : 0);
|
hls.on(Hls.Events.ERROR, (_, d) => {
|
||||||
hls.on(Hls.Events.ERROR, (_, d) => {
|
if (!d.fatal || !hls?.media) return;
|
||||||
if (!d.fatal || !hls?.media) return;
|
console.warn("Hls error", d);
|
||||||
console.warn("Hls error", d);
|
onError?.call(null, {
|
||||||
onError?.call(null, {
|
error: { errorString: d.reason ?? d.error?.message ?? "Unknown hls error" },
|
||||||
error: { errorString: d.reason ?? d.error?.message ?? "Unknown hls error" },
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
})();
|
}
|
||||||
// onError changes should not restart the playback.
|
// onError changes should not restart the playback.
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [source.uri, source.hls]);
|
}, [source.uri, source.hls]);
|
||||||
|
@ -8465,10 +8465,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"hls.js@npm:^1.5.2":
|
"hls.js@npm:^1.5.6":
|
||||||
version: 1.5.2
|
version: 1.5.6
|
||||||
resolution: "hls.js@npm:1.5.2"
|
resolution: "hls.js@npm:1.5.6"
|
||||||
checksum: fb03209ca3b691e996c3d0b83dac2bcc63dba468f9c24b7414d1dc9b950c3ac0fdcfc2349d8b16d98a96c6fbe35c2836d5740a832d1844451187be4749469957
|
checksum: 685564b223955267194ec1089179717e040354a92e0269dd72150598b422448cede1cb4882c0c63b8124f42d823e156b6433bbd3048443c4d4ff29cae3ec4efa
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -14023,7 +14023,7 @@ __metadata:
|
|||||||
expo-image-picker: ~14.7.1
|
expo-image-picker: ~14.7.1
|
||||||
expo-linear-gradient: ^12.7.1
|
expo-linear-gradient: ^12.7.1
|
||||||
expo-modules-core: ^1.11.8
|
expo-modules-core: ^1.11.8
|
||||||
hls.js: ^1.5.2
|
hls.js: ^1.5.6
|
||||||
i18next: ^23.7.20
|
i18next: ^23.7.20
|
||||||
jassub: ^1.7.15
|
jassub: ^1.7.15
|
||||||
jotai: ^2.6.3
|
jotai: ^2.6.3
|
||||||
|
@ -153,10 +153,18 @@ func (fs *FileStream) GetMaster() string {
|
|||||||
master := "#EXTM3U\n"
|
master := "#EXTM3U\n"
|
||||||
// TODO: also check if the codec is valid in a hls before putting transmux
|
// TODO: also check if the codec is valid in a hls before putting transmux
|
||||||
if fs.Info.Video != nil {
|
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 {
|
if fs.CanTransmux {
|
||||||
|
bitrate := float64(fs.Info.Video.Bitrate)
|
||||||
master += "#EXT-X-STREAM-INF:"
|
master += "#EXT-X-STREAM-INF:"
|
||||||
master += fmt.Sprintf("AVERAGE-BANDWIDTH=%d,", fs.Info.Video.Bitrate)
|
master += fmt.Sprintf("AVERAGE-BANDWIDTH=%d,", int(math.Min(bitrate*0.8, float64(transmux_quality.AverageBitrate()))))
|
||||||
master += fmt.Sprintf("BANDWIDTH=%d,", int(float32(fs.Info.Video.Bitrate)*1.2))
|
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 += fmt.Sprintf("RESOLUTION=%dx%d,", fs.Info.Video.Width, fs.Info.Video.Height)
|
||||||
master += "AUDIO=\"audio\","
|
master += "AUDIO=\"audio\","
|
||||||
master += "CLOSED-CAPTIONS=NONE\n"
|
master += "CLOSED-CAPTIONS=NONE\n"
|
||||||
|
@ -41,21 +41,21 @@ func QualityFromString(str string) (Quality, error) {
|
|||||||
func (v Quality) AverageBitrate() uint32 {
|
func (v Quality) AverageBitrate() uint32 {
|
||||||
switch v {
|
switch v {
|
||||||
case P240:
|
case P240:
|
||||||
return 400000
|
return 400_000
|
||||||
case P360:
|
case P360:
|
||||||
return 800000
|
return 800_000
|
||||||
case P480:
|
case P480:
|
||||||
return 1200000
|
return 1_200_000
|
||||||
case P720:
|
case P720:
|
||||||
return 2400000
|
return 2_400_000
|
||||||
case P1080:
|
case P1080:
|
||||||
return 4800000
|
return 4_800_000
|
||||||
case P1440:
|
case P1440:
|
||||||
return 9600000
|
return 9_600_000
|
||||||
case P4k:
|
case P4k:
|
||||||
return 16000000
|
return 16_000_000
|
||||||
case P8k:
|
case P8k:
|
||||||
return 28000000
|
return 28_000_000
|
||||||
case Original:
|
case Original:
|
||||||
panic("Original quality must be handled specially")
|
panic("Original quality must be handled specially")
|
||||||
}
|
}
|
||||||
@ -65,21 +65,21 @@ func (v Quality) AverageBitrate() uint32 {
|
|||||||
func (v Quality) MaxBitrate() uint32 {
|
func (v Quality) MaxBitrate() uint32 {
|
||||||
switch v {
|
switch v {
|
||||||
case P240:
|
case P240:
|
||||||
return 700000
|
return 700_000
|
||||||
case P360:
|
case P360:
|
||||||
return 1400000
|
return 1_400_000
|
||||||
case P480:
|
case P480:
|
||||||
return 2100000
|
return 2_100_000
|
||||||
case P720:
|
case P720:
|
||||||
return 4000000
|
return 4_000_000
|
||||||
case P1080:
|
case P1080:
|
||||||
return 8000000
|
return 8_000_000
|
||||||
case P1440:
|
case P1440:
|
||||||
return 12000000
|
return 12_000_000
|
||||||
case P4k:
|
case P4k:
|
||||||
return 28000000
|
return 28_000_000
|
||||||
case P8k:
|
case P8k:
|
||||||
return 40000000
|
return 40_000_000
|
||||||
case Original:
|
case Original:
|
||||||
panic("Original quality must be handled specially")
|
panic("Original quality must be handled specially")
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user