TL;DR: https://github.com/yaroslaff/smugglerjpg . Из фото делаем слайдшоу видео и его заливаем (можно unlisted/private, чтобы никто не видел). Затем, если надо - скачиваем видео и извлекаем фото.

На картинке два изображения, оригинальное (слева) и после запаковки-загрузки-скачивания-извлечения (справа). Второе изображение имеет меньшее разрешение, поэтому для сравнения разрешения подогнаны по высоте
На видеохостингах можно хостить огромные видео, но нельзя фото… В мессенджерах можно отправлять и хранить фото, но неудобно работать с коллекциями фото (папками, группами).
Решение: делаем из фоток - слайдшоу, причем таким образом, чтобы потом было удобно нарезать на фотки обратно (либо без потери в качестве, либо с небольшой потерей).
Ты должен сделать добро из зла, потому что его больше не из чего делать
Раз уж у нас есть Макс и Рутуб и мы все равно их оплатили налогами - почему бы не использовать их как фотохостинги? Хоть на что-то сгодятся.
SmugglerJPG - пакуем галерею в одно видео
Будем использовать вот этот мой проектик - smugglerjpg.
Ставим
pipx install smugglerjpg
Если нет pipx - apt install pipx. Если вы на Windows - наверное, тоже как-то можно поставить. Не пробовал. Еще потребуется ffmpeg на линуксе.
Делаем видео
smugglerjpg create /tmp/testgallery/ -a ~/tmp/bgmusic/ -o out.mp4
-a - можно добавить музыку (тогда можно будет даже самому смотреть и почти не скучно)
-d - продолжительность каждого слайда. (по-умолчанию, 5 секунд)
Если хотите чтобы фото шли в определенном порядке, можно указать либо --sort name / --sort mtime , либо -f filelist.txt
Дальше заливаем его куда хотим.
Распаковываем нашу контрабанду обратно
Скачиваем наше видео, или из студии, или прямо через yt-dlp . Распаковываем:
smugglerjpg extract out-ytdlp.webm -o /tmp/extracted/
И у нас снова те же картинки (с небольшой потерей в качестве, на мой глаз - не заметно).
Контроль качества
Исходное фото для примера:
mediainfo testgallery/IMG20260513193409.jpg
$ mediainfo testgallery/IMG20260513193409.jpg General Complete name : testgallery/IMG20260513193409.jpg Format : JPEG File size : 10.8 MiB Image Format : JPEG Width : 3 072 pixels Height : 4 096 pixels Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Compression mode : Lossy Stream size : 10.8 MiB (100%) ColorSpace_ICC : RGB
Наш локальный видеофайл:
mediainfo out.mp4
$ mediainfo out.mp4 General Complete name : out.mp4 Format : MPEG-4 Format profile : Base Media Codec ID : isom (isom/iso2/avc1/mp41) File size : 18.8 MiB Duration : 35 s 0 ms Overall bit rate : 4 517 kb/s Frame rate : 30.000 FPS Writing application : Lavf61.7.103 Video ID : 1 Format : AVC Format/Info : Advanced Video Codec Format profile : Constrained Baseline@L5.1 Format settings : 1 Ref Frames Format settings, CABAC : No Format settings, Reference frames : 1 frame Codec ID : avc1 Codec ID/Info : Advanced Video Coding Duration : 35 s 0 ms Bit rate : 4 378 kb/s Width : 3 840 pixels Height : 2 160 pixels Display aspect ratio : 16:9 Frame rate mode : Constant Frame rate : 30.000 FPS Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Scan type : Progressive Bits/(Pixel*Frame) : 0.018 Stream size : 18.3 MiB (97%) Writing library : x264 core 165 Encoding settings : cabac=0 / ref=1 / deblock=0:0:0 / analyse=0:0 / me=dia / subme=0 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=0 / me_range=16 / chroma_me=1 / trellis=0 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=0 / threads=6 / lookahead_threads=1 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=0 / weightp=0 / keyint=250 / keyint_min=25 / scenecut=0 / intra_refresh=0 / rc=crf / mbtree=0 / crf=23.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / ip_ratio=1.40 / aq=0 Codec configuration box : avcC Audio ID : 2 Format : AAC LC Format/Info : Advanced Audio Codec Low Complexity Codec ID : mp4a-40-2 Duration : 34 s 993 ms Source duration : 35 s 16 ms Bit rate mode : Constant Bit rate : 132 kb/s Channel(s) : 2 channels Channel layout : L R Sampling rate : 44.1 kHz Frame rate : 43.066 FPS (1024 SPF) Compression mode : Lossy Stream size : 564 KiB (3%) Source stream size : 565 KiB (3%) Default : Yes Alternate group : 1
Файл после yt-dlp с youtube:
mediainfo out-ytdlp.webm
$ mediainfo out-ytdlp.webm General Complete name : out-ytdlp.webm Format : WebM Format version : Version 4 File size : 12.3 MiB Duration : 35 s 48 ms Overall bit rate : 2 941 kb/s Frame rate : 30.000 FPS Writing application : Lavf61.7.103 Writing library : Lavf61.7.103 Video ID : 1 Format : AV1 Format/Info : AOMedia Video 1 Format profile : Main@L5.0 Codec ID : V_AV1 Duration : 35 s 0 ms Width : 3 840 pixels Height : 2 160 pixels Display aspect ratio : 16:9 Frame rate mode : Constant Frame rate : 30.000 FPS Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Title : ISO Media file produced by Google Inc. Default : Yes Forced : No Color range : Limited Color primaries : BT.709 Transfer characteristics : BT.709 Matrix coefficients : BT.709 VENDOR_ID : [0][0][0][0] Audio ID : 2 Format : Opus Codec ID : A_OPUS Duration : 35 s 41 ms Channel(s) : 2 channels Channel layout : L R Sampling rate : 48.0 kHz Bit depth : 32 bits Compression mode : Lossy Delay relative to video : 7 ms Language : English Default : Yes Forced : No
Параметры извлеченной картинки:
mediainfo /tmp/extracted/extracted_slide_003.jpg
$ mediainfo /tmp/extracted/extracted_slide_003.jpg General Complete name : /tmp/extracted/extracted_slide_003.jpg Format : JPEG File size : 967 KiB Image Format : JPEG Width : 1 620 pixels Height : 2 160 pixels Color space : YUV Chroma subsampling : 4:2:0 Bit depth : 8 bits Compression mode : Lossy Stream size : 967 KiB (100%)
Замечания, советы
Видео на ютубе можно хранить как unlisted или private. Или вообще как Draft!
Разрешение видео на практике - все-таки одно на всю продолжительность видео. Таким образом, если мы в видео держим одновременно и вертикальные и горизонтальные фотки - потери качества будут выше. С другой стороны, сейчас в телефонах столько мегапикселей что я после этой процедуры не замечаю разницы.
Делалось LLM’кой, так что, сами понимаете.
Пользуйтесь, и храните свои приятные воспоминания!
