Er packte um, was gar nicht am Umpacken lag
Der Browser bekam stillschweigend Apples Geräteprofil — und mit ihm HEVC, AC3 und EAC3, von denen er keines öffnet. Der Server packte die Datei pflichtschuldig nach MP4 um, liess Bild und Ton dabei unberührt, und heraus kam eine tadellose Datei, mit der Chrome nichts anfangen konnte. Umpacken fasst das Bild nun einmal nicht an. Jetzt sagt das Gerät selbst, was es kann, und es gibt einen zweiten Weg neben der fertigen Datei: HLS, das nach Sekunden anfängt statt nach Minuten. Dasselbe Rohr erledigt beides — mkv nach fMP4 mit „-c:v copy", 4K nach 480p mit libx264 — und eine MP4, die der Browser ohnehin öffnet, geht ganz ohne ffmpeg hinaus. Dazu eine eigene Steuerleiste: Tonspur und Untertitel während der Wiedergabe umschaltbar, vier Auflösungsstufen, Tastenkürzel, und bei einem Fehler ein deutscher Satz statt eines schwarzen Bildes. Gemessen statt vermutet: Chromium antwortet auf canPlayType für HLS mit "maybe" und kann es dann doch nicht — deshalb entscheidet Hls.isSupported(). hls.js wiegt 372 KB und wird erst beim Abspielen geholt; die Oberfläche bleibt bei 109. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
557708b769
commit
4853200d5c
@@ -494,6 +494,50 @@ export const favorit = (id: string, wert: boolean) =>
|
||||
|
||||
export const downloadAdresse = (datei: string) => `/api/v1/files/${datei}/download`;
|
||||
|
||||
/* ---------- Strom ---------- */
|
||||
|
||||
/** Eine wählbare Spur, so wie sie im Menü steht. */
|
||||
export type Spurauskunft = {
|
||||
index: number; label: string; language: string | null; isDefault: boolean;
|
||||
};
|
||||
|
||||
export type Stromauskunft = {
|
||||
sessionId: string;
|
||||
url: string;
|
||||
/** „direct", „remux" oder „transcode". */
|
||||
method: 'direct' | 'remux' | 'transcode';
|
||||
/** Ab welcher Sekunde des Films dieser Strom beginnt — der Spieler zählt ab null. */
|
||||
startSeconds: number;
|
||||
height: number | null;
|
||||
audioStream: number | null;
|
||||
audioStreams: Spurauskunft[];
|
||||
subtitleStreams: Spurauskunft[];
|
||||
};
|
||||
|
||||
export type Stromwunsch = {
|
||||
containers: string[]; videoCodecs: string[]; audioCodecs: string[];
|
||||
height?: number | null;
|
||||
audioStream?: number | null;
|
||||
startSeconds?: number;
|
||||
};
|
||||
|
||||
/** Legt einen Strom an, der sofort anfängt.
|
||||
*
|
||||
* **Das Gerät sagt, was es kann.** Ohne diese Angabe nimmt der Server Apples
|
||||
* Profil an — und das erlaubt HEVC und EAC3, von denen kein Browser etwas
|
||||
* öffnet. */
|
||||
export const stromStarten = (datei: string, wunsch: Stromwunsch) =>
|
||||
anfrage<Stromauskunft>(`/files/${datei}/stream`, {
|
||||
method: 'POST', body: JSON.stringify(wunsch),
|
||||
});
|
||||
|
||||
/** Beendet einen Strom und räumt seinen Kratzplatz weg. */
|
||||
export const stromBeenden = (sitzung: string) =>
|
||||
anfrage<void>(`/stream/${sitzung}`, { method: 'DELETE' });
|
||||
|
||||
export const untertitelAdresse = (datei: string, spur: number) =>
|
||||
`/api/v1/files/${datei}/subtitles/${spur}.vtt`;
|
||||
|
||||
/* ---------- Verwaltung ---------- */
|
||||
|
||||
export const bibliotheken = () => anfrage<Bibliothek[]>('/libraries');
|
||||
|
||||
Reference in New Issue
Block a user