[desktop] HLS newlines - Take 2 (#5990)

This commit is contained in:
Manav Rathi
2025-05-20 20:07:22 +05:30
committed by GitHub
2 changed files with 29 additions and 3 deletions

View File

@@ -357,6 +357,18 @@ const ffmpegGenerateHLSPlaylistAndSegments = async (
// - the first line specifies the key URI that is written into the playlist.
// - the second line specifies the path to the local file system file from
// where ffmpeg should read the key.
//
// [Note: ffmpeg newlines]
//
// Tested on Windows that ffmpeg recognizes these lines correctly. In
// general, ffmpeg tends to expect input and write output the Unix way (\n),
// even when we're running on Windows.
//
// - The ffmetadata and the HLS playlist file generated by ffmpeg uses \n
// separators, even on Windows.
// - The HLS key info file, expected as an input by ffmpeg, works fine when
// \n separated even on Windows.
//
const keyInfo = [keyURI, keyPath].join("\n");
// Overview:
@@ -491,6 +503,15 @@ const ffmpegGenerateHLSPlaylistAndSegments = async (
// Note: Depending on the size of the input file, this may take long!
await execAsyncWorker(commandWithRedirection);
// While ffmpeg uses \n as the line separator in the generated playlist
// file on Windows too, add an extra safety check that should fail the
// HLS generation if this doesn't hold. See: [Note: ffmpeg newlines].
if (process.platform == "win32") {
const playlistText = await fs.readFile(playlistPath, "utf-8");
if (playlistText.includes("\r\n"))
throw new Error("Unexpected Windows newlines in playlist");
}
// Determine the dimensions of the generated video from the stderr
// output produced by ffmpeg during the conversion.
dimensions = await detectVideoDimensions(stderrPath);
@@ -544,10 +565,10 @@ const deletePathIgnoringErrors = async (tempFilePath: string) => {
*
* Stream #0:1[0x2](und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(progressive), 480x270 [SAR 1:1 DAR 16:9], 539 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
*/
const videoStreamLineRegex = /Stream #.+: Video:(.+)$/;
const videoStreamLineRegex = /Stream #.+: Video:(.+)\r?\n/;
/** {@link videoStreamLineRegex}, but global. */
const videoStreamLinesRegex = /Stream #.+: Video:(.+)$/g;
const videoStreamLinesRegex = /Stream #.+: Video:(.+)\r?\n/g;
/**
* A regex that matches "<digits> kb/s" preceded by a space. See

View File

@@ -184,8 +184,13 @@ const parseFFmpegExtractedMetadata = (ffmpegOutput: Uint8Array) => {
// with comments and newlines.
//
// https://ffmpeg.org/ffmpeg-formats.html#Metadata-2
//
// On Windows, while I couldn't find it documented anywhere, the generated
// ffmetadata file uses Unix line separators ("\n"). But for the sake of
// extra (albeit possibly unnecessary) safety, handle both \r\n and \n
// separators in the split. See: [Note: ffmpeg newlines]
const lines = new TextDecoder().decode(ffmpegOutput).split("\n");
const lines = new TextDecoder().decode(ffmpegOutput).split(/\r?\n/);
const isPair = (xs: string[]): xs is [string, string] => xs.length == 2;
const kvPairs = lines.map((property) => property.split("=")).filter(isPair);