1
0
mirror of https://github.com/immich-app/immich.git synced 2024-12-26 10:50:29 +02:00

feat(server): Support webm videos (#1365)

* feat(server): Support webm without transcoding.

Transcoding result doesn't appear to be used by anything expect for quicktime.

* feat(server): Fix the asset uploader for .avi

It needs to be transcoded.

* feat(server): Most browsers doesn't support avi so use mp4.

* feat(server): Address PR comments

* Addressed the PR comments

I moved the function that checks the mimetype to a central location in asset-utils and made tests for it.

* Rollbacked to the way transcoder was decising things to transcode.
This commit is contained in:
Skyler Mäntysaari 2023-01-21 23:52:40 +02:00 committed by GitHub
parent 5262e92b9f
commit 8eb82836b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 39 additions and 4 deletions

View File

@ -37,7 +37,7 @@ import {
import { GetAssetCountByTimeBucketDto } from './dto/get-asset-count-by-time-bucket.dto'; import { GetAssetCountByTimeBucketDto } from './dto/get-asset-count-by-time-bucket.dto';
import { GetAssetByTimeBucketDto } from './dto/get-asset-by-time-bucket.dto'; import { GetAssetByTimeBucketDto } from './dto/get-asset-by-time-bucket.dto';
import { AssetCountByUserIdResponseDto } from './response-dto/asset-count-by-user-id-response.dto'; import { AssetCountByUserIdResponseDto } from './response-dto/asset-count-by-user-id-response.dto';
import { timeUtils } from '@app/common/utils'; import { assetUtils, timeUtils } from '@app/common/utils';
import { CheckExistingAssetsDto } from './dto/check-existing-assets.dto'; import { CheckExistingAssetsDto } from './dto/check-existing-assets.dto';
import { CheckExistingAssetsResponseDto } from './response-dto/check-existing-assets-response.dto'; import { CheckExistingAssetsResponseDto } from './response-dto/check-existing-assets-response.dto';
import { UpdateAssetDto } from './dto/update-asset.dto'; import { UpdateAssetDto } from './dto/update-asset.dto';
@ -456,7 +456,7 @@ export class AssetService {
await fs.access(videoPath, constants.R_OK | constants.W_OK); await fs.access(videoPath, constants.R_OK | constants.W_OK);
if (query.isWeb && asset.mimeType == 'video/quicktime') { if (query.isWeb && !assetUtils.isWebPlayable(asset.mimeType)) {
videoPath = asset.encodedVideoPath == '' ? String(asset.originalPath) : String(asset.encodedVideoPath); videoPath = asset.encodedVideoPath == '' ? String(asset.originalPath) : String(asset.encodedVideoPath);
mimeType = asset.encodedVideoPath == '' ? asset.mimeType : 'video/mp4'; mimeType = asset.encodedVideoPath == '' ? asset.mimeType : 'video/mp4';
} }

View File

@ -60,6 +60,12 @@ describe('assetUploadOption', () => {
expect(callback).toHaveBeenCalledWith(null, true); expect(callback).toHaveBeenCalledWith(null, true);
}); });
it('should allow webm videos', async () => {
const file = { mimetype: 'video/webm', originalname: 'test.webm' } as any;
fileFilter(mock.userRequest, file, callback);
expect(callback).toHaveBeenCalledWith(null, true);
});
it('should not allow unknown types', async () => { it('should not allow unknown types', async () => {
const file = { mimetype: 'application/html', originalname: 'test.html' } as any; const file = { mimetype: 'application/html', originalname: 'test.html' } as any;
const callback = jest.fn(); const callback = jest.fn();

View File

@ -28,7 +28,7 @@ function fileFilter(req: Request, file: any, cb: any) {
} }
if ( if (
file.mimetype.match( file.mimetype.match(
/\/(jpg|jpeg|png|gif|mp4|x-msvideo|quicktime|heic|heif|dng|x-adobe-dng|webp|tiff|3gpp|nef|x-nikon-nef)$/, /\/(jpg|jpeg|png|gif|mp4|webm|x-msvideo|quicktime|heic|heif|dng|x-adobe-dng|webp|tiff|3gpp|nef|x-nikon-nef)$/,
) )
) { ) {
cb(null, true); cb(null, true);

View File

@ -0,0 +1,20 @@
import { assetUtils } from './asset-utils';
describe('Asset Utilities', () => {
describe('isWebPlayable', () => {
it('Check that it returns true with mimetype webm', () => {
const result = assetUtils.isWebPlayable('video/webm');
expect(result).toBeTruthy();
});
it('Check that returns true with mimetype mp4', () => {
const result = assetUtils.isWebPlayable('video/mp4');
expect(result).toBeTruthy();
});
it('Check that returns false with mimetype quicktime', () => {
const result = assetUtils.isWebPlayable('video/quicktime');
expect(result).toBeFalsy();
});
});
});

View File

@ -36,4 +36,13 @@ const deleteFiles = (asset: AssetEntity | AssetResponseDto) => {
} }
}; };
export const assetUtils = { deleteFiles }; const isWebPlayable = (mimeType: string | null): boolean => {
const WEB_PLAYABLE = ['video/webm', 'video/mp4'];
if (mimeType !== null) {
return WEB_PLAYABLE.includes(mimeType);
}
return false;
};
export const assetUtils = { deleteFiles, isWebPlayable };