mirror of
https://github.com/immich-app/immich.git
synced 2025-01-04 02:46:47 +01:00
fix(server): hevc tag being set when copying a non-hevc stream (#8582)
This commit is contained in:
parent
0d130b8957
commit
55b9acca78
3 changed files with 74 additions and 3 deletions
|
@ -747,6 +747,67 @@ describe(MediaService.name, () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not include hevc tag when target is hevc and video stream is copied from a different codec', async () => {
|
||||||
|
mediaMock.probe.mockResolvedValue(probeStub.videoStreamH264);
|
||||||
|
configMock.load.mockResolvedValue([
|
||||||
|
{ key: SystemConfigKey.FFMPEG_TARGET_VIDEO_CODEC, value: VideoCodec.HEVC },
|
||||||
|
{ key: SystemConfigKey.FFMPEG_ACCEPTED_VIDEO_CODECS, value: [VideoCodec.H264, VideoCodec.HEVC] },
|
||||||
|
{ key: SystemConfigKey.FFMPEG_ACCEPTED_AUDIO_CODECS, value: [AudioCodec.AAC] },
|
||||||
|
]);
|
||||||
|
assetMock.getByIds.mockResolvedValue([assetStub.video]);
|
||||||
|
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||||
|
expect(mediaMock.transcode).toHaveBeenCalledWith(
|
||||||
|
'/original/path.ext',
|
||||||
|
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||||
|
{
|
||||||
|
inputOptions: [],
|
||||||
|
outputOptions: [
|
||||||
|
'-c:v copy',
|
||||||
|
'-c:a aac',
|
||||||
|
'-movflags faststart',
|
||||||
|
'-fps_mode passthrough',
|
||||||
|
'-map 0:0',
|
||||||
|
'-map 0:1',
|
||||||
|
'-v verbose',
|
||||||
|
'-preset ultrafast',
|
||||||
|
'-crf 23',
|
||||||
|
],
|
||||||
|
twoPass: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should include hevc tag when target is hevc and copying hevc video stream', async () => {
|
||||||
|
mediaMock.probe.mockResolvedValue(probeStub.matroskaContainer);
|
||||||
|
configMock.load.mockResolvedValue([
|
||||||
|
{ key: SystemConfigKey.FFMPEG_TARGET_VIDEO_CODEC, value: VideoCodec.HEVC },
|
||||||
|
{ key: SystemConfigKey.FFMPEG_ACCEPTED_VIDEO_CODECS, value: [VideoCodec.H264, VideoCodec.HEVC] },
|
||||||
|
{ key: SystemConfigKey.FFMPEG_ACCEPTED_AUDIO_CODECS, value: [AudioCodec.AAC] },
|
||||||
|
]);
|
||||||
|
assetMock.getByIds.mockResolvedValue([assetStub.video]);
|
||||||
|
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||||
|
expect(mediaMock.transcode).toHaveBeenCalledWith(
|
||||||
|
'/original/path.ext',
|
||||||
|
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||||
|
{
|
||||||
|
inputOptions: [],
|
||||||
|
outputOptions: [
|
||||||
|
'-c:v copy',
|
||||||
|
'-c:a aac',
|
||||||
|
'-movflags faststart',
|
||||||
|
'-fps_mode passthrough',
|
||||||
|
'-map 0:0',
|
||||||
|
'-map 0:1',
|
||||||
|
'-tag:v hvc1',
|
||||||
|
'-v verbose',
|
||||||
|
'-preset ultrafast',
|
||||||
|
'-crf 23',
|
||||||
|
],
|
||||||
|
twoPass: false,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should copy audio stream when audio matches target', async () => {
|
it('should copy audio stream when audio matches target', async () => {
|
||||||
mediaMock.probe.mockResolvedValue(probeStub.audioStreamAac);
|
mediaMock.probe.mockResolvedValue(probeStub.audioStreamAac);
|
||||||
configMock.load.mockResolvedValue([{ key: SystemConfigKey.FFMPEG_TRANSCODE, value: TranscodePolicy.OPTIMAL }]);
|
configMock.load.mockResolvedValue([{ key: SystemConfigKey.FFMPEG_TRANSCODE, value: TranscodePolicy.OPTIMAL }]);
|
||||||
|
|
|
@ -37,9 +37,12 @@ class BaseConfig implements VideoCodecSWConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
getBaseOutputOptions(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo) {
|
getBaseOutputOptions(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo) {
|
||||||
|
const videoCodec = [TranscodeTarget.ALL, TranscodeTarget.VIDEO].includes(target) ? this.getVideoCodec() : 'copy';
|
||||||
|
const audioCodec = [TranscodeTarget.ALL, TranscodeTarget.AUDIO].includes(target) ? this.getAudioCodec() : 'copy';
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
`-c:v ${[TranscodeTarget.ALL, TranscodeTarget.VIDEO].includes(target) ? this.getVideoCodec() : 'copy'}`,
|
`-c:v ${videoCodec}`,
|
||||||
`-c:a ${[TranscodeTarget.ALL, TranscodeTarget.AUDIO].includes(target) ? this.getAudioCodec() : 'copy'}`,
|
`-c:a ${audioCodec}`,
|
||||||
// Makes a second pass moving the moov atom to the
|
// Makes a second pass moving the moov atom to the
|
||||||
// beginning of the file for improved playback speed.
|
// beginning of the file for improved playback speed.
|
||||||
'-movflags faststart',
|
'-movflags faststart',
|
||||||
|
@ -61,7 +64,10 @@ class BaseConfig implements VideoCodecSWConfig {
|
||||||
options.push(`-g ${this.getGopSize()}`);
|
options.push(`-g ${this.getGopSize()}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.config.targetVideoCodec === VideoCodec.HEVC) {
|
if (
|
||||||
|
this.config.targetVideoCodec === VideoCodec.HEVC &&
|
||||||
|
(videoCodec !== 'copy' || videoStream.codecName === 'hevc')
|
||||||
|
) {
|
||||||
options.push('-tag:v hvc1');
|
options.push('-tag:v hvc1');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
server/test/fixtures/media.stub.ts
vendored
4
server/test/fixtures/media.stub.ts
vendored
|
@ -173,4 +173,8 @@ export const probeStub = {
|
||||||
bitrate: 0,
|
bitrate: 0,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
videoStreamH264: Object.freeze<VideoInfo>({
|
||||||
|
...probeStubDefault,
|
||||||
|
videoStreams: [{ ...probeStubDefaultVideoStream[0], codecName: 'h264' }],
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue