1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2024-12-29 15:11:58 +00:00

add extension to tmp path

This commit is contained in:
mertalev 2024-05-27 18:47:36 -04:00
parent dda736840b
commit f48318168b
No known key found for this signature in database
GPG key ID: 9181CD92C0A1C5E3
2 changed files with 26 additions and 11 deletions

View file

@ -293,7 +293,7 @@ describe(MediaService.name, () => {
await sut.handleGeneratePreview({ id: assetStub.video.id }); await sut.handleGeneratePreview({ id: assetStub.video.id });
expect(storageMock.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se'); expect(storageMock.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se');
expect(mediaMock.transcode).toHaveBeenCalledWith('/original/path.ext', expect.stringMatching(/.*\.tmp/), { expect(mediaMock.transcode).toHaveBeenCalledWith('/original/path.ext', expect.stringMatching(/.*\.tmp\.jpeg/), {
inputOptions: ['-skip_frame nokey', '-sws_flags accurate_rnd+full_chroma_int'], inputOptions: ['-skip_frame nokey', '-sws_flags accurate_rnd+full_chroma_int'],
outputOptions: [ outputOptions: [
'-fps_mode vfr', '-fps_mode vfr',
@ -305,7 +305,7 @@ describe(MediaService.name, () => {
twoPass: false, twoPass: false,
}); });
expect(assetMock.update).toHaveBeenCalledWith({ id: 'asset-id', previewPath }); expect(assetMock.update).toHaveBeenCalledWith({ id: 'asset-id', previewPath });
expect(storageMock.rename).toHaveBeenCalledWith(expect.stringMatching(/.*\.tmp/), previewPath); expect(storageMock.rename).toHaveBeenCalledWith(expect.stringMatching(/.*\.tmp\.jpeg/), previewPath);
}); });
it('should tonemap thumbnail for hdr video', async () => { it('should tonemap thumbnail for hdr video', async () => {
@ -316,7 +316,7 @@ describe(MediaService.name, () => {
await sut.handleGeneratePreview({ id: assetStub.video.id }); await sut.handleGeneratePreview({ id: assetStub.video.id });
expect(storageMock.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se'); expect(storageMock.mkdirSync).toHaveBeenCalledWith('upload/thumbs/user-id/as/se');
expect(mediaMock.transcode).toHaveBeenCalledWith('/original/path.ext', expect.stringMatching(/.*\.tmp/), { expect(mediaMock.transcode).toHaveBeenCalledWith('/original/path.ext', expect.stringMatching(/.*\.tmp\.jpeg/), {
inputOptions: ['-skip_frame nokey', '-sws_flags accurate_rnd+full_chroma_int'], inputOptions: ['-skip_frame nokey', '-sws_flags accurate_rnd+full_chroma_int'],
outputOptions: [ outputOptions: [
'-fps_mode vfr', '-fps_mode vfr',
@ -328,7 +328,7 @@ describe(MediaService.name, () => {
twoPass: false, twoPass: false,
}); });
expect(assetMock.update).toHaveBeenCalledWith({ id: 'asset-id', previewPath }); expect(assetMock.update).toHaveBeenCalledWith({ id: 'asset-id', previewPath });
expect(storageMock.rename).toHaveBeenCalledWith(expect.stringMatching(/.*\.tmp/), previewPath); expect(storageMock.rename).toHaveBeenCalledWith(expect.stringMatching(/.*\.tmp\.jpeg/), previewPath);
}); });
it('should always generate video thumbnail in one pass', async () => { it('should always generate video thumbnail in one pass', async () => {
@ -341,7 +341,7 @@ describe(MediaService.name, () => {
await sut.handleGeneratePreview({ id: assetStub.video.id }); await sut.handleGeneratePreview({ id: assetStub.video.id });
expect(mediaMock.transcode).toHaveBeenCalledWith('/original/path.ext', expect.stringMatching(/.*\.tmp/), { expect(mediaMock.transcode).toHaveBeenCalledWith('/original/path.ext', expect.stringMatching(/.*\.tmp\.jpeg/), {
inputOptions: ['-skip_frame nokey', '-sws_flags accurate_rnd+full_chroma_int'], inputOptions: ['-skip_frame nokey', '-sws_flags accurate_rnd+full_chroma_int'],
outputOptions: [ outputOptions: [
'-fps_mode vfr', '-fps_mode vfr',
@ -353,7 +353,7 @@ describe(MediaService.name, () => {
twoPass: false, twoPass: false,
}); });
expect(assetMock.update).toHaveBeenCalledWith({ id: 'asset-id', previewPath }); expect(assetMock.update).toHaveBeenCalledWith({ id: 'asset-id', previewPath });
expect(storageMock.rename).toHaveBeenCalledWith(expect.stringMatching(/.*\.tmp/), previewPath); expect(storageMock.rename).toHaveBeenCalledWith(expect.stringMatching(/.*\.tmp\.jpeg/), previewPath);
}); });
it('should run successfully', async () => { it('should run successfully', async () => {

View file

@ -188,7 +188,7 @@ export class MediaService {
const { image, ffmpeg } = await this.configCore.getConfig(); const { image, ffmpeg } = await this.configCore.getConfig();
const size = type === AssetPathType.PREVIEW ? image.previewSize : image.thumbnailSize; const size = type === AssetPathType.PREVIEW ? image.previewSize : image.thumbnailSize;
const path = StorageCore.getImagePath(asset, type, format); const path = StorageCore.getImagePath(asset, type, format);
const tmpPath = StorageCore.getTempPathInDir(dirname(path)); const tmpPath = `${StorageCore.getTempPathInDir(dirname(path))}.${format}`;
this.storageCore.ensureFolders(path); this.storageCore.ensureFolders(path);
switch (asset.type) { switch (asset.type) {
@ -204,6 +204,9 @@ export class MediaService {
const inputPath = useExtracted ? extractedPath : asset.originalPath; const inputPath = useExtracted ? extractedPath : asset.originalPath;
await this.mediaRepository.generateThumbnail(inputPath, tmpPath, imageOptions); await this.mediaRepository.generateThumbnail(inputPath, tmpPath, imageOptions);
} catch (error) {
await this.storageRepository.unlink(tmpPath);
throw error;
} finally { } finally {
if (didExtract) { if (didExtract) {
await this.storageRepository.unlink(extractedPath); await this.storageRepository.unlink(extractedPath);
@ -222,7 +225,12 @@ export class MediaService {
const mainAudioStream = this.getMainStream(audioStreams); const mainAudioStream = this.getMainStream(audioStreams);
const config = ThumbnailConfig.create({ ...ffmpeg, targetResolution: size.toString() }); const config = ThumbnailConfig.create({ ...ffmpeg, targetResolution: size.toString() });
const options = config.getCommand(TranscodeTarget.VIDEO, mainVideoStream, mainAudioStream); const options = config.getCommand(TranscodeTarget.VIDEO, mainVideoStream, mainAudioStream);
await this.mediaRepository.transcode(asset.originalPath, tmpPath, options); try {
await this.mediaRepository.transcode(asset.originalPath, tmpPath, options);
} catch (error) {
await this.storageRepository.unlink(tmpPath);
throw error;
}
break; break;
} }
@ -354,9 +362,16 @@ export class MediaService {
`Error occurred during transcoding. Retrying with ${ffmpeg.accel.toUpperCase()} acceleration disabled.`, `Error occurred during transcoding. Retrying with ${ffmpeg.accel.toUpperCase()} acceleration disabled.`,
); );
} }
const config = BaseConfig.create({ ...ffmpeg, accel: TranscodeHWAccel.DISABLED });
command = config.getCommand(target, mainVideoStream, mainAudioStream); try {
await this.mediaRepository.transcode(input, tmpPath, command); const config = BaseConfig.create({ ...ffmpeg, accel: TranscodeHWAccel.DISABLED });
command = config.getCommand(target, mainVideoStream, mainAudioStream);
await this.mediaRepository.transcode(input, tmpPath, command);
} catch (error) {
this.logger.error(error);
await this.storageRepository.unlink(tmpPath);
return JobStatus.FAILED;
}
} }
await this.storageRepository.rename(tmpPath, output); await this.storageRepository.rename(tmpPath, output);