Cont
This commit is contained in:
@@ -298,20 +298,25 @@ const handleGenerateHLSWrite = async (
|
||||
inputTempFilePath,
|
||||
outputFilePathPrefix,
|
||||
);
|
||||
|
||||
const videoFilePath = result.videoPath;
|
||||
try {
|
||||
await uploadVideoSegments(videoFilePath, objectUploadURL);
|
||||
|
||||
const playlistToken = randomUUID();
|
||||
pendingVideoResults.set(playlistToken, result.playlistPath);
|
||||
|
||||
const { dimensions, videoSize } = result;
|
||||
return new Response(
|
||||
JSON.stringify({ playlistToken, dimensions, videoSize }),
|
||||
{ status: 200 },
|
||||
);
|
||||
} finally {
|
||||
await deleteTempFileIgnoringErrors(videoFilePath);
|
||||
}
|
||||
} finally {
|
||||
await deleteTempFileIgnoringErrors(inputTempFilePath);
|
||||
}
|
||||
|
||||
await uploadVideoSegments(result.videoPath, objectUploadURL);
|
||||
|
||||
const playlistToken = randomUUID();
|
||||
pendingVideoResults.set(playlistToken, result.playlistPath);
|
||||
|
||||
const { dimensions, videoSize } = result;
|
||||
return new Response(
|
||||
JSON.stringify({ playlistToken, dimensions, videoSize }),
|
||||
{ status: 200 },
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -324,21 +329,20 @@ const handleGenerateHLSWrite = async (
|
||||
*
|
||||
* ---
|
||||
*
|
||||
* This is an inlined reimplementation of `retryEnsuringHTTPOkOr4xx` from
|
||||
* `web/packages/base/http.ts`.
|
||||
* This is an inlined but bespoke reimplementation of `retryEnsuringHTTPOkOr4xx`
|
||||
* from `web/packages/base/http.ts` (we don't have the rest of the scaffolding
|
||||
* used by that function, which is why it is inlined bespoked).
|
||||
*
|
||||
* It is included here for the specific use of uploading videos since generating
|
||||
* the HLS stream is a fairly expensive operation, so a retry to discount
|
||||
* transient network issues is called for.
|
||||
*
|
||||
* We don't currently have rest of the scaffolding used by
|
||||
* `retryEnsuringHTTPOkOr4xx`, which is why we just inline it bespoke.
|
||||
* It handles the specific use case of uploading videos since generating the HLS
|
||||
* stream is a fairly expensive operation, so a retry to discount transient
|
||||
* network issues is called for. There are only 2 retries for a total of 3
|
||||
* attempts, and the retry gaps are more spaced out.
|
||||
*/
|
||||
export const uploadVideoSegments = async (
|
||||
videoFilePath: string,
|
||||
objectUploadURL: string,
|
||||
) => {
|
||||
const waitTimeBeforeNextTry = [2000, 5000, 10000];
|
||||
const waitTimeBeforeNextTry = [5000, 20000];
|
||||
|
||||
while (true) {
|
||||
let abort = false;
|
||||
@@ -350,10 +354,12 @@ export const uploadVideoSegments = async (
|
||||
});
|
||||
|
||||
if (res.ok) {
|
||||
/* success */ return;
|
||||
// Success.
|
||||
return;
|
||||
}
|
||||
if (res.status >= 400 && res.status < 500) {
|
||||
abort = true; /* 4xx */
|
||||
// HTTP 4xx.
|
||||
abort = true;
|
||||
}
|
||||
throw new Error(
|
||||
`Failed to upload generated HLS video: HTTP ${res.status} ${res.statusText}`,
|
||||
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
authenticatedPublicAlbumsRequestHeaders,
|
||||
authenticatedRequestHeaders,
|
||||
ensureOk,
|
||||
retryAsyncOperation,
|
||||
type PublicAlbumsCredentials,
|
||||
} from "ente-base/http";
|
||||
import log from "ente-base/log";
|
||||
@@ -10,7 +11,6 @@ import { EnteFile } from "ente-media/file";
|
||||
import { CustomError, handleUploadError } from "ente-shared/error";
|
||||
import HTTPService from "ente-shared/network/HTTPService";
|
||||
import { getToken } from "ente-shared/storage/localStorage/helpers";
|
||||
import { retryAsyncOperation } from "ente-base/http";
|
||||
import { z } from "zod";
|
||||
import { MultipartUploadURLs, UploadFile } from "./upload-service";
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ export const retryAsyncOperation = async <T>(
|
||||
}
|
||||
const t = waitTimeBeforeNextTry.shift();
|
||||
if (!t) throw e;
|
||||
log.info("Will retry potentially transient request failure", e);
|
||||
log.warn("Will retry potentially transient request failure", e);
|
||||
await wait(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -403,7 +403,7 @@ const processQueueItem = async (
|
||||
const { objectID, url: objectUploadURL } =
|
||||
await getFilePreviewDataUploadURL(file);
|
||||
|
||||
log.info(`HLS gen ${fileLogID(file)} | start`);
|
||||
log.info(`Generate HLS for ${fileLogID(file)} | start`);
|
||||
|
||||
// [Note: Upload HLS video segment from node side]
|
||||
//
|
||||
@@ -419,7 +419,7 @@ const processQueueItem = async (
|
||||
//
|
||||
// So instead we provide the presigned upload URL to the node side so that
|
||||
// it can directly upload the generated video segments.
|
||||
const queryParams = new URLSearchParams(objectUploadURL);
|
||||
const queryParams = new URLSearchParams({ objectUploadURL });
|
||||
|
||||
const res = await writeVideoStream(
|
||||
electron,
|
||||
@@ -446,7 +446,7 @@ const processQueueItem = async (
|
||||
|
||||
await putVideoData(file, playlistData, objectID, videoSize);
|
||||
|
||||
log.info(`HLS gen ${fileLogID(file)} | done`);
|
||||
log.info(`Generate HLS for ${fileLogID(file)} | done`);
|
||||
} finally {
|
||||
await Promise.all([videoStreamDone(electron, playlistToken)]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user