diff --git a/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts b/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts index 711580387..d92d0fdbc 100644 --- a/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts +++ b/src/queue.worker/nft.worker/queue/job-services/thumbnails/nft.thumbnail.service.ts @@ -117,8 +117,14 @@ export class NftThumbnailService { private async extractScreenshotFromVideo(buffer: Buffer, nftIdentifier: string): Promise { // we try to extract frames at 0, 10, 30 seconds, and we take the frame that has the biggest size // (i.e. the bigger the size, the more "crisp" an image should be, since it contains more details) + // + // Screenshots are written as PNG (RGB) rather than JPEG on purpose: the MJPEG/JPEG encoder + // (strict since ffmpeg 8.0) rejects limited-range ("tv") YUV videos with "Non full-range YUV + // is non-standard ..." and fails to open the encoder (-22). PNG has no such range constraint, + // so it works for every video format. The final JPEG thumbnail is produced downstream by sharp + // in extractThumbnailFromImage, so the intermediate format does not affect the output. const frames = [0, 10, 30]; - const filePaths = frames.map(x => path.join(this.apiConfigService.getTempUrl(), `${nftIdentifier}.screenshot.${x}.jpg`)); + const filePaths = frames.map(x => path.join(this.apiConfigService.getTempUrl(), `${nftIdentifier}.screenshot.${x}.png`)); const videoPath = path.join(this.apiConfigService.getTempUrl(), nftIdentifier); await FileUtils.writeFile(buffer, videoPath);