You've already forked immich
							
							
				mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-31 00:18:28 +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:
		
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							5262e92b9f
						
					
				
				
					commit
					8eb82836b9
				
			| @@ -37,7 +37,7 @@ import { | ||||
| import { GetAssetCountByTimeBucketDto } from './dto/get-asset-count-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 { timeUtils } from '@app/common/utils'; | ||||
| import { assetUtils, timeUtils } from '@app/common/utils'; | ||||
| import { CheckExistingAssetsDto } from './dto/check-existing-assets.dto'; | ||||
| import { CheckExistingAssetsResponseDto } from './response-dto/check-existing-assets-response.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); | ||||
|  | ||||
|         if (query.isWeb && asset.mimeType == 'video/quicktime') { | ||||
|         if (query.isWeb && !assetUtils.isWebPlayable(asset.mimeType)) { | ||||
|           videoPath = asset.encodedVideoPath == '' ? String(asset.originalPath) : String(asset.encodedVideoPath); | ||||
|           mimeType = asset.encodedVideoPath == '' ? asset.mimeType : 'video/mp4'; | ||||
|         } | ||||
|   | ||||
| @@ -60,6 +60,12 @@ describe('assetUploadOption', () => { | ||||
|       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 () => { | ||||
|       const file = { mimetype: 'application/html', originalname: 'test.html' } as any; | ||||
|       const callback = jest.fn(); | ||||
|   | ||||
| @@ -28,7 +28,7 @@ function fileFilter(req: Request, file: any, cb: any) { | ||||
|   } | ||||
|   if ( | ||||
|     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); | ||||
|   | ||||
							
								
								
									
										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 }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user