Introduce ability to play mp4 files as they download

This commit is contained in:
Scott Nonnenberg
2025-01-14 15:22:40 +10:00
committed by GitHub
parent bab1ceb831
commit 16bbcc2c50
30 changed files with 1304 additions and 141 deletions

View File

@@ -1,15 +1,18 @@
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { AttachmentType } from '../types/Attachment';
import { isNumber } from 'lodash';
import { strictAssert } from './assert';
import type { AttachmentType } from '../types/Attachment';
export enum AttachmentDisposition {
Attachment = 'attachment',
Temporary = 'temporary',
Draft = 'draft',
Sticker = 'sticker',
AvatarData = 'avatarData',
Draft = 'draft',
Download = 'download',
Sticker = 'sticker',
Temporary = 'temporary',
}
export type GetLocalAttachmentUrlOptionsType = Readonly<{
@@ -20,20 +23,41 @@ export function getLocalAttachmentUrl(
attachment: Partial<
Pick<
AttachmentType,
'version' | 'path' | 'localKey' | 'size' | 'contentType'
| 'contentType'
| 'digest'
| 'downloadPath'
| 'incrementalMac'
| 'chunkSize'
| 'key'
| 'localKey'
| 'path'
| 'size'
| 'version'
>
>,
{
disposition = AttachmentDisposition.Attachment,
}: GetLocalAttachmentUrlOptionsType = {}
): string {
strictAssert(attachment.path != null, 'Attachment must be downloaded first');
let { path } = attachment;
if (disposition === AttachmentDisposition.Download) {
strictAssert(
attachment.incrementalMac && attachment.chunkSize,
'To view downloads, must have incrementalMac/chunkSize'
);
path = attachment.downloadPath;
}
strictAssert(path != null, `${disposition} attachment was missing path`);
// Fix Windows paths
const path = attachment.path.replace(/\\/g, '/');
path = path.replace(/\\/g, '/');
let url: URL;
if (attachment.version !== 2) {
if (disposition === AttachmentDisposition.Download) {
url = new URL(`attachment://v2/${path}`);
} else if (attachment.version !== 2) {
url = new URL(`attachment://v1/${path}`);
} else {
url = new URL(`attachment://v${attachment.version}/${path}`);
@@ -53,5 +77,32 @@ export function getLocalAttachmentUrl(
if (disposition !== AttachmentDisposition.Attachment) {
url.searchParams.set('disposition', disposition);
}
if (disposition === AttachmentDisposition.Download) {
if (!attachment.key) {
throw new Error('getLocalAttachmentUrl: Missing attachment key!');
}
url.searchParams.set('key', attachment.key);
if (!attachment.digest) {
throw new Error('getLocalAttachmentUrl: Missing attachment digest!');
}
url.searchParams.set('digest', attachment.digest);
if (!attachment.incrementalMac) {
throw new Error(
'getLocalAttachmentUrl: Missing attachment incrementalMac!'
);
}
url.searchParams.set('incrementalMac', attachment.incrementalMac);
if (!isNumber(attachment.chunkSize)) {
throw new Error(
'getLocalAttachmentUrl: Missing attachment incrementalMac!'
);
}
url.searchParams.set('chunkSize', attachment.chunkSize.toString());
}
return url.toString();
}