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:
parent
5262e92b9f
commit
8eb82836b9
@ -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';
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
20
server/libs/common/src/utils/asset-utils.spec.ts
Normal file
20
server/libs/common/src/utils/asset-utils.spec.ts
Normal 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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -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 };
|
||||||
|
Loading…
Reference in New Issue
Block a user