From 3c7c14e11c311cb0ded19538a95bc122bf8323c9 Mon Sep 17 00:00:00 2001 From: Manav Rathi Date: Mon, 13 May 2024 16:18:03 +0530 Subject: [PATCH] conv --- desktop/src/main/services/ffmpeg.ts | 57 ++++++++------------------ desktop/src/main/stream.ts | 7 ++-- web/apps/photos/src/services/ffmpeg.ts | 40 ++++++++++-------- 3 files changed, 45 insertions(+), 59 deletions(-) diff --git a/desktop/src/main/services/ffmpeg.ts b/desktop/src/main/services/ffmpeg.ts index ad2ce16fa..ddbb31e4c 100644 --- a/desktop/src/main/services/ffmpeg.ts +++ b/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 => { - // 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. + inputFilePath: string, + outputFilePath: string, +): Promise => { + const command = [ + ffmpegPathPlaceholder, + "-i", + inputPathPlaceholder, + "-preset", + "ultrafast", + outputPathPlaceholder, + ]; - const { - path: inputFilePath, - isFileTemporary: isInputFileTemporary, - writeToTemporaryFile: writeToTemporaryInputFile, - } = await makeFileForDataOrPathOrZipItem(dataOrPathOrZipItem); + const cmd = substitutePlaceholders(command, inputFilePath, outputFilePath); - const outputFilePath = await makeTempFilePath(outputFileExtension); - try { - await writeToTemporaryInputFile(); - - const cmd = substitutePlaceholders( - command, - inputFilePath, - outputFilePath, - ); - - if (timeoutMS) await withTimeout(execAsync(cmd), timeoutMS); - else await execAsync(cmd); - - return fs.readFile(outputFilePath); - } finally { - if (isInputFileTemporary) - await deleteTempFileIgnoringErrors(inputFilePath); - await deleteTempFileIgnoringErrors(outputFilePath); - } + await withTimeout(execAsync(cmd), 30 * 1000); }; diff --git a/desktop/src/main/stream.ts b/desktop/src/main/stream.ts index 86a7a8614..207ca33d0 100644 --- a/desktop/src/main/stream.ts +++ b/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); diff --git a/web/apps/photos/src/services/ffmpeg.ts b/web/apps/photos/src/services/ffmpeg.ts index 4dfdb3f64..e9841b599 100644 --- a/web/apps/photos/src/services/ffmpeg.ts +++ b/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