URL
This commit is contained in:
@@ -82,7 +82,9 @@ export const fetchFilesData = async (
|
||||
*
|
||||
* Unlike {@link fetchFilesData}, this uses a HTTP GET request.
|
||||
*
|
||||
* Returns `undefined` if no video preview has been generated for this file yet.
|
||||
* Returns `undefined` if no file data of the given type has been uploaded for
|
||||
* this file yet (e.g. if type was "vid_preview", this would indicate that a
|
||||
* video preview has been generated for this file yet).
|
||||
*/
|
||||
export const fetchFileData = async (
|
||||
type: FileDataType,
|
||||
@@ -134,3 +136,54 @@ export const putFileData = async (
|
||||
});
|
||||
ensureOk(res);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch the preview file data the given file.
|
||||
*
|
||||
* @param type The {@link FileDataType} which we want.
|
||||
*
|
||||
* @param fileIDs The id of the files for which we want the file preview data.
|
||||
*
|
||||
* @returns the (presigned) URL to the preview data, or undefined if there is
|
||||
* not preview data of the given type for the given file yet.
|
||||
*
|
||||
* [Note: File data vs file preview data]
|
||||
*
|
||||
* In museum's ontology, there is a distinction between two concepts:
|
||||
*
|
||||
* S3 metadata (museum term, the APIs call it "file data") is data that museum
|
||||
* uploads on behalf of the client. e.g.,
|
||||
*
|
||||
* - ML data.
|
||||
*
|
||||
* - Preview video playlist.
|
||||
*
|
||||
* S3 file data (museum term, the APIs call it "file preview data") is data that
|
||||
* a client itself uploads. e.g.,
|
||||
*
|
||||
* - The preview video itself.
|
||||
*
|
||||
* - Additional preview images.
|
||||
*
|
||||
* [Note: Video playlist and preview]
|
||||
*
|
||||
* For a streaming video, both these concepts are needed:
|
||||
*
|
||||
* - The encrypted HLS playlist is stored as "file data" of type "vid_preview",
|
||||
*
|
||||
* - The encrypted video chunks that the playlist refers to are stored as "file
|
||||
* preview data" of type "vid_preview".
|
||||
*/
|
||||
export const fetchFilePreviewData = async (
|
||||
type: FileDataType,
|
||||
fileID: number,
|
||||
): Promise<string | undefined> => {
|
||||
const params = new URLSearchParams({ type, fileID: fileID.toString() });
|
||||
const url = await apiURL("/files/data/preview");
|
||||
const res = await fetch(`${url}?${params.toString()}`, {
|
||||
headers: await authenticatedRequestHeaders(),
|
||||
});
|
||||
if (res.status == 404) return undefined;
|
||||
ensureOk(res);
|
||||
return z.object({ url: z.string() }).parse(await res.json()).url;
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ import { FileType } from "@/media/file-type";
|
||||
import { gunzip } from "@/new/photos/utils/gzip";
|
||||
import { ensurePrecondition } from "@/utils/ensure";
|
||||
import { z } from "zod";
|
||||
import { fetchFileData } from "./file-data";
|
||||
import { fetchFileData, fetchFilePreviewData } from "./file-data";
|
||||
|
||||
/**
|
||||
* Return a HLS playlist that can be used to stream playback of thne given video
|
||||
@@ -17,26 +17,7 @@ import { fetchFileData } from "./file-data";
|
||||
* @returns The HLS playlist as a string, or `undefined` if there is no video
|
||||
* preview associated with the given file.
|
||||
*
|
||||
* [Note: Video playlist and preview]
|
||||
*
|
||||
* In museum's ontology, there is a distinction between two concepts:
|
||||
*
|
||||
* S3 metadata is the data that museum uploads (on behalf of the client):
|
||||
* - ML data.
|
||||
* - Preview video playlist.
|
||||
*
|
||||
* S3 file data is the data that client uploads:
|
||||
* - Preview video itself.
|
||||
* - Additional preview images.
|
||||
*
|
||||
* Because of this separation, there are separate code paths dealing with the
|
||||
* two parts we need to play streaming video:
|
||||
*
|
||||
* - The encrypted HLS playlist (which is stored as file data of type
|
||||
* "vid_preview"),
|
||||
*
|
||||
* - And the encrypted video chunks that it (the playlist) refers to (which are
|
||||
* stored as file preview data of type "vid_preview").
|
||||
* See: [Note: Video playlist and preview]
|
||||
*/
|
||||
export const hlsPlaylistForFile = async (file: EnteFile) => {
|
||||
ensurePrecondition(file.metadata.fileType == FileType.video);
|
||||
@@ -44,11 +25,17 @@ export const hlsPlaylistForFile = async (file: EnteFile) => {
|
||||
const playlistFileData = await fetchFileData("vid_preview", file.id);
|
||||
if (!playlistFileData) return undefined;
|
||||
|
||||
const videoURL = await fetchFilePreviewData("vid_preview", file.id);
|
||||
if (!videoURL) return undefined;
|
||||
|
||||
// See: [Note: strict mode migration]
|
||||
//
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const { playlist } = await decryptPlaylistJSON(playlistFileData, file);
|
||||
const { playlist: playlistTemplate } = await decryptPlaylistJSON(
|
||||
playlistFileData,
|
||||
file,
|
||||
);
|
||||
|
||||
// [Note: HLS playlist format]
|
||||
//
|
||||
@@ -102,6 +89,7 @@ export const hlsPlaylistForFile = async (file: EnteFile) => {
|
||||
// (AES-128 for us), URI and IV attributes. The URI attribute value is a
|
||||
// quoted string containing a URI that specfies how to obtain the key.
|
||||
|
||||
const playlist = playlistTemplate.replaceAll("output.ts", videoURL);
|
||||
log.debug(() => ["hlsPlaylistForFile", playlist]);
|
||||
return file.id;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user