refactor: optimize fMP4 detection

pull/27038/head
Qusai Ismael 2026-04-10 15:22:11 +03:00
parent daa8c52fae
commit fa6d9e50ec
3 changed files with 5 additions and 24 deletions

View File

@ -241,9 +241,7 @@ export class MediaRepository {
formatLongName: results.format.format_long_name,
duration: this.parseFloat(results.format.duration),
bitrate: this.parseInt(results.format.bit_rate),
tags: results.format.tags
? Object.fromEntries(Object.entries(results.format.tags).map(([key, value]) => [key, String(value)]))
: undefined,
tags: results.format.tags,
},
videoStreams: results.streams
.filter((stream) => stream.codec_type === 'video' && !stream.disposition?.attached_pic)

View File

@ -2090,7 +2090,7 @@ describe(MediaService.name, () => {
);
});
it('should not include encoding options when remuxing fragmented MP4', async () => {
it('should not include encoding options when remuxing', async () => {
mocks.media.probe.mockResolvedValue(probeStub.fragmentedMp4);
mocks.systemMetadata.get.mockResolvedValue({ ffmpeg: { transcode: TranscodePolicy.Required } });
await sut.handleVideoConversion({ id: 'video-id' });
@ -2107,23 +2107,6 @@ describe(MediaService.name, () => {
);
});
it('should still skip non-MP4 containers that do not need transcoding', async () => {
mocks.media.probe.mockResolvedValue(probeStub.videoStreamVp9);
mocks.systemMetadata.get.mockResolvedValue({
ffmpeg: { transcode: TranscodePolicy.Required, acceptedVideoCodecs: [VideoCodec.Vp9], acceptedContainers: ['matroska,webm'] },
});
await sut.handleVideoConversion({ id: 'video-id' });
expect(mocks.media.transcode).not.toHaveBeenCalled();
});
it('should skip remux for standard MP4s', async () => {
mocks.media.probe.mockResolvedValue(probeStub.videoStreamH264);
mocks.systemMetadata.get.mockResolvedValue({ ffmpeg: { transcode: TranscodePolicy.Required } });
const result = await sut.handleVideoConversion({ id: 'video-id' });
expect(result).toBe(JobStatus.Skipped);
expect(mocks.media.transcode).not.toHaveBeenCalled();
});
it('should not scale resolution if no target resolution', async () => {
mocks.media.probe.mockResolvedValue(probeStub.videoStream2160p);
mocks.systemMetadata.get.mockResolvedValue({

View File

@ -56,7 +56,7 @@ interface UpsertFileOptions {
}
type ThumbnailAsset = NonNullable<Awaited<ReturnType<AssetJobRepository['getForGenerateThumbnailJob']>>>;
const FRAGMENTED_MP4_BRANDS = new Set(['iso5', 'iso6', 'dash', 'msdh', 'msix', 'cmfc']);
const FRAGMENTED_MP4_BRANDS = ['iso5', 'iso6', 'dash', 'msdh', 'msix', 'cmfc'];
@Injectable()
export class MediaService extends BaseService {
@ -772,7 +772,7 @@ export class MediaService extends BaseService {
}
const majorBrand = tags?.major_brand;
if (majorBrand && FRAGMENTED_MP4_BRANDS.has(majorBrand)) {
if (majorBrand && FRAGMENTED_MP4_BRANDS.includes(majorBrand)) {
return true;
}
@ -781,7 +781,7 @@ export class MediaService extends BaseService {
return false;
}
return Array.from(FRAGMENTED_MP4_BRANDS).some((brand) => compatibleBrands.includes(brand));
return FRAGMENTED_MP4_BRANDS.some((brand) => compatibleBrands.includes(brand));
}
isSRGB({