forked from Cutlery/immich
		
	fix(server): extract duration from video as ISO time (#6863)
* fix(server): extract duration from video as ISO time * feedback and add test * fix test
This commit is contained in:
		
							parent
							
								
									2d278d9ab8
								
							
						
					
					
						commit
						b768eef44d
					
				@ -547,6 +547,22 @@ describe(MetadataService.name, () => {
 | 
				
			|||||||
      );
 | 
					      );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('should handle duration in ISO time string', async () => {
 | 
				
			||||||
 | 
					      assetMock.getByIds.mockResolvedValue([assetStub.image]);
 | 
				
			||||||
 | 
					      metadataMock.readTags.mockResolvedValue({ Duration: '00:00:08.41' });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      await sut.handleMetadataExtraction({ id: assetStub.image.id });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      expect(assetMock.getByIds).toHaveBeenCalledWith([assetStub.image.id]);
 | 
				
			||||||
 | 
					      expect(assetMock.upsertExif).toHaveBeenCalled();
 | 
				
			||||||
 | 
					      expect(assetMock.save).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        expect.objectContaining({
 | 
				
			||||||
 | 
					          id: assetStub.image.id,
 | 
				
			||||||
 | 
					          duration: '00:00:08.410',
 | 
				
			||||||
 | 
					        }),
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('should handle duration as an object without Scale', async () => {
 | 
					    it('should handle duration as an object without Scale', async () => {
 | 
				
			||||||
      assetMock.getByIds.mockResolvedValue([assetStub.image]);
 | 
					      assetMock.getByIds.mockResolvedValue([assetStub.image]);
 | 
				
			||||||
      metadataMock.readTags.mockResolvedValue({ Duration: { Value: 6.2 } });
 | 
					      metadataMock.readTags.mockResolvedValue({ Duration: { Value: 6.2 } });
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,6 @@ import { IBaseJob, IEntityJob, ISidecarWriteJob, JOBS_ASSET_PAGINATION_SIZE, Job
 | 
				
			|||||||
import {
 | 
					import {
 | 
				
			||||||
  ClientEvent,
 | 
					  ClientEvent,
 | 
				
			||||||
  DatabaseLock,
 | 
					  DatabaseLock,
 | 
				
			||||||
  ExifDuration,
 | 
					 | 
				
			||||||
  IAlbumRepository,
 | 
					  IAlbumRepository,
 | 
				
			||||||
  IAssetRepository,
 | 
					  IAssetRepository,
 | 
				
			||||||
  ICommunicationRepository,
 | 
					  ICommunicationRepository,
 | 
				
			||||||
@ -555,11 +554,15 @@ export class MetadataService {
 | 
				
			|||||||
    return bitsPerSample;
 | 
					    return bitsPerSample;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private getDuration(seconds?: number | ExifDuration): string {
 | 
					  private getDuration(seconds?: ImmichTags['Duration']): string {
 | 
				
			||||||
    let _seconds = seconds as number;
 | 
					    let _seconds = seconds as number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (typeof seconds === 'object') {
 | 
					    if (typeof seconds === 'object') {
 | 
				
			||||||
      _seconds = seconds.Value * (seconds?.Scale || 1);
 | 
					      _seconds = seconds.Value * (seconds?.Scale || 1);
 | 
				
			||||||
 | 
					    } else if (typeof seconds === 'string') {
 | 
				
			||||||
 | 
					      _seconds = Duration.fromISOTime(seconds).as('seconds');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Duration.fromObject({ seconds: _seconds }).toFormat('hh:mm:ss.SSS');
 | 
					    return Duration.fromObject({ seconds: _seconds }).toFormat('hh:mm:ss.SSS');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -26,7 +26,7 @@ export interface ImmichTags extends Omit<Tags, 'FocalLength' | 'Duration'> {
 | 
				
			|||||||
  MediaGroupUUID?: string;
 | 
					  MediaGroupUUID?: string;
 | 
				
			||||||
  ImagePixelDepth?: string;
 | 
					  ImagePixelDepth?: string;
 | 
				
			||||||
  FocalLength?: number;
 | 
					  FocalLength?: number;
 | 
				
			||||||
  Duration?: number | ExifDuration;
 | 
					  Duration?: number | string | ExifDuration;
 | 
				
			||||||
  EmbeddedVideoType?: string;
 | 
					  EmbeddedVideoType?: string;
 | 
				
			||||||
  EmbeddedVideoFile?: BinaryField;
 | 
					  EmbeddedVideoFile?: BinaryField;
 | 
				
			||||||
  MotionPhotoVideo?: BinaryField;
 | 
					  MotionPhotoVideo?: BinaryField;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user