Manav Rathi 1 year ago
parent
commit
3c7c14e11c

+ 18 - 39
desktop/src/main/services/ffmpeg.ts

@@ -114,47 +114,26 @@ const ffmpegBinaryPath = () => {
  * handle the MP4 conversion of large video files.
  *
  * See: [Note: Convert to MP4]
- *
- * @param command
- * @param dataOrPathOrZipItem
- * @param outputFileExtension
- * @param timeoutMS
- * @returns
+
+ * @param inputFilePath The path to a file on the user's local file system. This
+ * is the video we want to convert.
+ * @param inputFilePath The path to a file on the user's local file system where
+ * we should write the converted MP4 video.
  */
 export const ffmpegConvertToMP4 = async (
-    command: string[],
-    dataOrPathOrZipItem: Uint8Array | string | ZipItem,
-    outputFileExtension: string,
-    timeoutMS: number,
-): Promise<Uint8Array> => {
-    // TODO (MR): This currently copies files for both input (when
-    // dataOrPathOrZipItem is data) and output. This needs to be tested
-    // extremely large video files when invoked downstream of `convertToMP4` in
-    // the web code.
-
-    const {
-        path: inputFilePath,
-        isFileTemporary: isInputFileTemporary,
-        writeToTemporaryFile: writeToTemporaryInputFile,
-    } = await makeFileForDataOrPathOrZipItem(dataOrPathOrZipItem);
-
-    const outputFilePath = await makeTempFilePath(outputFileExtension);
-    try {
-        await writeToTemporaryInputFile();
-
-        const cmd = substitutePlaceholders(
-            command,
-            inputFilePath,
-            outputFilePath,
-        );
+    inputFilePath: string,
+    outputFilePath: string,
+): Promise<void> => {
+    const command = [
+        ffmpegPathPlaceholder,
+        "-i",
+        inputPathPlaceholder,
+        "-preset",
+        "ultrafast",
+        outputPathPlaceholder,
+    ];
 
-        if (timeoutMS) await withTimeout(execAsync(cmd), timeoutMS);
-        else await execAsync(cmd);
+    const cmd = substitutePlaceholders(command, inputFilePath, outputFilePath);
 
-        return fs.readFile(outputFilePath);
-    } finally {
-        if (isInputFileTemporary)
-            await deleteTempFileIgnoringErrors(inputFilePath);
-        await deleteTempFileIgnoringErrors(outputFilePath);
-    }
+    await withTimeout(execAsync(cmd), 30 * 1000);
 };

+ 4 - 3
desktop/src/main/stream.ts

@@ -10,6 +10,7 @@ import { Readable } from "node:stream";
 import { ReadableStream } from "node:stream/web";
 import { pathToFileURL } from "node:url";
 import log from "./log";
+import { ffmpegConvertToMP4 } from "./services/ffmpeg";
 import { ensure } from "./utils/common";
 import {
     deleteTempFile,
@@ -158,7 +159,7 @@ const handleWrite = async (path: string, request: Request) => {
  *
  * The returned promise resolves when the write completes.
  *
- * @param filePath The local filesystem path where the file should be written.
+ * @param filePath The local file system path where the file should be written.
  *
  * @param readableStream A web
  * [ReadableStream](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream).
@@ -233,9 +234,9 @@ const handleConvertToMP4Write = async (request: Request) => {
     const inputTempFilePath = await makeTempFilePath();
     await writeStream(inputTempFilePath, ensure(request.body));
 
-    const outputTempFilePath = await makeTempFilePath();
+    const outputTempFilePath = await makeTempFilePath("mp4");
     try {
-        //
+        await ffmpegConvertToMP4(inputTempFilePath, outputTempFilePath);
     } catch (e) {
         await deleteTempFileIgnoringErrors(inputTempFilePath);
         await deleteTempFileIgnoringErrors(outputTempFilePath);

+ 23 - 17
web/apps/photos/src/services/ffmpeg.ts

@@ -98,8 +98,8 @@ const makeGenThumbnailCommand = (seekTime: number) => [
  * of videos that the user is uploading.
  *
  * @param uploadItem A {@link File}, or the absolute path to a file on the
- * user's local filesytem. A path can only be provided when we're running in the
- * context of our desktop app.
+ * user's local file sytem. A path can only be provided when we're running in
+ * the context of our desktop app.
  */
 export const extractVideoMetadata = async (
     uploadItem: UploadItem,
@@ -234,22 +234,28 @@ const ffmpegExecWeb = async (
  *
  * @param blob The video blob.
  *
- * @returns The mp4 video data.
+ * @returns The mp4 video blob.
  */
-export const convertToMP4 = async (blob: Blob) =>
-    ffmpegExecNativeOrWeb(
-        [
-            ffmpegPathPlaceholder,
-            "-i",
-            inputPathPlaceholder,
-            "-preset",
-            "ultrafast",
-            outputPathPlaceholder,
-        ],
-        blob,
-        "mp4",
-        30 * 1000,
-    );
+export const convertToMP4 = async (blob: Blob) => {
+    const electron = globalThis.electron;
+    if (electron) {
+        //
+    } else {
+        return ffmpegExecWeb(
+            [
+                ffmpegPathPlaceholder,
+                "-i",
+                inputPathPlaceholder,
+                "-preset",
+                "ultrafast",
+                outputPathPlaceholder,
+            ],
+            blob,
+            "mp4",
+            30 * 1000,
+        );
+    }
+};
 
 /**
  * Run the given FFmpeg command using a native FFmpeg binary when we're running