Skip to content

About

Fast 64-bit Total Commander plugin in Rust: a Lister viewer for photos, RAW, PSD, video and audio, plus content fields to find duplicate photos, videos and music by perceptual hashes and audio fingerprints. Also includes EXIF, tag and stream fields for columns, search and renaming.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

58 Commits

Folders and files

Repository files navigation

Mediares — мультимедийный просмотрщик и контентный плагин для Total Commander (WLX + WDX)

Русский | English

Rust Platform Total Commander License: MIT Release Last commit Repo size

Высокопроизводительный 64-битный плагин для Total Commander на языке Rust. Готовые архивы — на странице Releases.

  1. mediares_wlx — плагин 2-в-1 (WLX + WDX) в одном файле: все поля WDX (см. п. 2) плюс быстрый встроенный просмотр изображений, аудио и видео по клавише F3 (Lister) с поддержкой двойной буферизации GDI и тёмного интерфейса.
  2. mediares_wdx — облегчённый Content-плагин (WDX) без просмотрщика: поля EXIF, тегов и параметров потока для колонок, поиска и группового переименования (готовые наборы — ниже), плюс перцептивные хеши (dHash, pHash, CoarseHash, Video/Audio Fingerprint) для поиска дубликатов.

Системные требования

Минимум Комментарий
ОС Windows 10 (1607) x64 Нужна для GetDpiForWindow; Rust 1.78+ ниже Windows 10 не собирает. Для SVG — 1703+. 32-битные Windows и Total Commander не поддерживаются
Total Commander 64-битный (totalcmd64.exe), плагины .wlx64 / .wdx64
Процессор любой x86-64 (SSE2) AVX и прочие расширения не нужны; libmpv варианта x86_64-v3 требует Haswell / Excavator и новее
Память 2 ГБ (минимум самой Windows 10 x64) Кэш фото — до 512 МБ, один кадр — до 64 Мпикс (≈256 МБ в RGBA); для комфортной работы с большими фото — от 4 ГБ
Видеокарта не обязательна D3D11 создаётся на GPU, а при отсутствии — на программном WARP; плавное видео высокого разрешения лучше с аппаратным декодированием
Диск ≈4 МБ mediares.wlx64 ≈3,8 МБ, mediares.wdx64 ≈2,8 МБ
Среда выполнения Microsoft Visual C++ Redistributable 2015–2022 x64 DLL линкуются с VCRUNTIME140.dll; на чистой Windows без него плагин не загрузится (у большинства пользователей он уже стоит)

Всё остальное — системные компоненты Windows 10: Media Foundation (видео, WMA/Opus/AC3, поля WDX), WIC (TIFF, JXR, DDS; HEIC/AVIF/JXL — с расширениями из Store), Direct2D (SVG), WASAPI (звук). В изданиях Windows N / KN нет Media Foundation (mfplat.dll): плагин там не загрузится, пока не установлен «Media Feature Pack». Необязательные libmpv-2.dll и расширения кодеков из Microsoft Store требований не меняют.


Архитектура воркспейса

mediares_wlx/
├── Cargo.toml                  # Workspace root
├── core/                       # Общая библиотека (lib), без Win32-окон:
│   ├── tc_api.rs               # WDX/WLX C ABI структуры и константы
│   ├── ffi.rs                  # catch_unwind-обёртка и конвертация строк на границе с TC
│   ├── probe.rs                # Тип медиа по расширению + единый источник строк детекта
│   ├── image_decode.rs         # Декодирование фото (`image`, WIC, SVG + RAW/PSD превью) с лимитами памяти
│   ├── wic_decode.rs           # HEIC/HEIF, AVIF, JPEG XL, JPEG XR, DDS через кодеки Windows (WIC)
│   ├── svg.rs                  # SVG/SVGZ через Direct2D (ID2D1SvgDocument)
│   ├── svg_css.rs              # Перенос правил <style> в атрибуты style (Direct2D таблицы стилей не читает)
│   ├── heif.rs                 # EXIF из контейнера HEIF (HEIC/AVIF): элемент Exif по iinf/iloc
│   ├── exif.rs                 # Разбор EXIF (JPEG, TIFF/RAW, HEIF) и запись основных полей для «Сохранить как»
│   ├── orientation.rs          # Поворот JPEG без потерь: запись тега EXIF Orientation
│   ├── jpeg.rs                 # Поиск/проверка встроенных JPEG-потоков, замена EXIF-сегмента
│   ├── raw_preview.rs          # Встроенный JPEG из RAW (IFD/SubIFD/strip + сигнатурный fallback)
│   ├── psd_preview.rs          # Композит PSD/PSB (8/16 бит) или миниатюра 0x0409/0x0410
│   ├── hashing.rs              # dHash (64-bit), pHash (DCT 64-bit), CoarseHash (32-bit), пропорции
│   ├── mf_init.rs              # Жизненный цикл COM / Media Foundation
│   ├── video_frame.rs          # Кадры на 25/50/75% через IMFSourceReader и фингерпринт
│   ├── audio_decode.rs         # Декодирование аудио в PCM (symphonia), точная перемотка — фича audio-decode
│   ├── audio_tags.rs           # Теги и обложка (symphonia: ID3v1/v2, APE, Vorbis, MP4, RIFF; починка кодировки cp1251) — фича tags
│   ├── audio_fingerprint.rs    # Поля аудио-дубликатов: отпечаток, хеш PCM, длительность
│   ├── mf_audio.rs             # Аудио через Media Foundation (WMA, AC3, Opus): PCM и параметры потока
│   ├── cache.rs                # Потокобезопасный LRU-кэш анализа и метаданных (ключ: путь + размер + mtime)
│   ├── video_tags.rs           # Теги видео: свой разбор Matroska/WebM (EBML) и MP4/MOV (ilst, QuickTime, 3GPP)
│   └── wdx_api.rs              # Логика полей WDX + макрос export_content_plugin!
├── wdx/                        # Облегчённый WDX-плагин (cdylib): одна строка — export_content_plugin!()
├── combo/                      # Полный 2-в-1 плагин WDX + WLX (cdylib)
│   ├── window.rs               # Окно Lister, обработка сообщений, команды и горячие клавиши
│   ├── state.rs                # Per-HWND состояние, список файлов папки (натуральная сортировка)
│   ├── image_view.rs           # Масштаб/панорама/лупа, GDI double buffering, OSD
│   ├── smooth.rs               # Бикубическое увеличение через Direct2D в буфер GDI
│   ├── osd_template.rs         # Шаблоны OSD: поля, скрываемые блоки, значения EXIF/видео
│   ├── osd_template_dialog.rs  # Редактор шаблона OSD с меню полей
│   ├── image_cache.rs          # BGRA-кэш (LRU по байтам) + пул фоновых декодеров, поворот на 90°
│   ├── file_actions.rs         # Корзина, внешний редактор, Проводник, обои рабочего стола
│   ├── print.rs                # Печать картинки (ListPrint): диалог принтера, вписывание в поля
│   ├── snapshot.rs             # Буфер обмена, сохранение кадра (PNG/JPEG), миниатюры TC
│   ├── save_as.rs              # «Сохранить как» для фото: копия, RAW-превью с EXIF или перекодирование
│   ├── fullscreen.rs           # Полноэкранный режим: отдельное окно на мониторе Lister
│   ├── overlay.rs              # Плавающие панели полноэкранного режима, скрытие курсора
│   ├── media_view.rs           # Общий слой аудио/видео: панель управления, мышь, события, таймеры
│   ├── playback_video.rs       # IMFMediaEngine (frame-server) + D3D11 swap chain
│   ├── video_view.rs           # Поверхность видео (letterbox), скорость, покадровый шаг, события
│   ├── resume.rs               # Позиции остановки длинных видео (mediares_resume.txt)
│   ├── playback_audio.rs       # Аудио: поток-декодер symphonia → поток WASAPI (shared, конвертация формата силами Windows)
│   ├── audio_view.rs           # Обложка + теги; fallback на Media Foundation (WMA, Opus, AC3)
│   ├── playlist.rs             # Очередь: автопереход, повтор, случайный порядок, чтение M3U
│   ├── transport_bar.rs        # Панель управления: ⏮ play/pause ⏭, время, таймлайн, звук
│   ├── config.rs               # Настройки mediares.ini
│   ├── i18n.rs                 # Язык интерфейса: tr("…") по каталогу mediares_ui.lng
│   ├── dialog.rs               # Общие хелперы модальных диалогов
│   ├── gdi.rs                  # Общие GDI-хелперы: двойная буферизация, шрифты, текст, заливки, DPI
│   ├── exif_dialog.rs          # Окно EXIF-метаданных
│   ├── settings_dialog.rs      # Окно настроек
│   └── examples/lister_harness.rs  # Dev-стенд: хост-окно как у TC, сценарий и скриншоты
└── pluginst/                   # Инсталляционные скрипты для TC
    ├── pluginst-wdx.inf        # WDX-only архив
    └── pluginst-wlx.inf        # WLX-архив: combo-файл ставится как Lister-плагин (поля подключаются из настроек)

Просмотрщик (combo, F3)

Фото

JPEG (JPG, JPEG, JPE; THM — миниатюры Canon), PNG, GIF, WEBP, BMP, ICO, TGA, HDR (Radiance); RAW (CR2, CR3, CRW, NEF, ARW, ORF, RW2, DNG, RAF, PEF, RAW) — по встроенному JPEG-превью; PSD/PSB — по композиту.

Через кодеки Windows (WIC), ничего не добавляя к размеру плагина: HEIC/HEIF/HIF и AVIF — нужны расширения из Microsoft Store «HEIF Image Extensions» и «HEVC Video Extensions» (для HEIC) или «AV1 Video Extension» (для AVIF); JXL — «JPEG XL Image Extension»; JXR/WDP/HDP (JPEG XR) и DDS (BC1–BC3, без сжатия) и TIFF/TIF (любое сжатие, включая старое JPEG; у многостраничного — все страницы, каждая со своей ориентацией) — встроены в Windows. Поворот из контейнера HEIF (irot/imir) применяется, EXIF (дата, камера, GPS) читается. Если у формата в стандартном декодере что-то не получилось (например, редкий вариант BMP), файл пробуется ещё раз через WIC.

SVG/SVGZ рисуется движком Direct2D (Windows 10 1703+): фигуры, контуры, градиенты, обтравка, use, стили — в том числе из <style> по простым селекторам (.класс, #id, тег). Не рисуются <text>, фильтры и маски. Маленькие рисунки растеризуются со стороной 1024 px, чтобы оставаться чёткими в режиме «вписать».

OpenEXR подключается cargo-фичей exr (mediares_core) и по умолчанию выключен: он добавляет к плагину ≈0,5 МБ.

Скорость. Окно открывается сразу (ListLoad ≈ 3 мс), фото декодируется в фоне. Пока новый кадр готовится, на экране остаётся предыдущий. Соседние фото (два вперёд по направлению листания и одно назад) заранее декодируются пулом из 1–3 потоков и показываются мгновенно; кэш — до 512 МБ. Если у файла негодный заголовок, ListLoad возвращает NULL и TC пробует другой плагин; если файл не декодировался позже — в окне сообщение. Фото сначала декодируется под размер экрана: JPEG, HEIC и встроенное в RAW превью уменьшаются прямо при декодировании, поворот по EXIF делается там же. Для миниатюр TC из RAW берётся самое маленькое подходящее превью. Целое фото для зума догружается в фоне и бросается, если вы ушли к другому файлу. Список файлов папки читается в фоне — первый файл показывается не дожидаясь его.

Действие Клавиши / мышь
Следующее / предыдущее фото Пробел, PgDn, N / PgUp, Backspace, P; колесо мыши (или наоборот — зум колесом, в настройках); боковые кнопки мыши. ↓ / ↑ — то же, но только в режиме «вписать»: при увеличении они панорамируют
Страницы многостраничного TIFF → / ← и колесо мыши, при увеличении — Ctrl+PgDn / Ctrl+PgUp; после последней страницы — следующий файл, перед первой — предыдущий (он открывается с первой страницы). В файле из одной страницы → / ← листают файлы, при увеличении панорамируют. Ctrl+C на странице кладёт для вставки в папку её PNG, а не весь файл
Масштаб + / −, Ctrl+колесо (к курсору; шаг останавливается на 100 %, или наоборот — колесо зумит, Ctrl+колесо листает, в настройках); Ctrl+1 — 100 %, Ctrl+2 — 200 %, Ctrl+3 — 300 %; Ctrl+0, *, / — вписать
Панорама / лупа стрелки или перетаскивание при увеличении / удержание ЛКМ в режиме «вписать»
Повернуть влево / вправо (только просмотр, файл не меняется) L / R
Сохранять масштаб при листании: следующее фото открывается с тем же зумом на том же месте Z (или меню, настройка)
Сравнить с этим фото: экран делится пополам, слева — запомненное фото, справа — листаемые; зум, панорама и лупа общие C (C ещё раз — выход)
Записать поворот в JPEG без потерь Ctrl+R (или меню)
Полноэкранный режим Enter, F, F11, двойной клик; Esc — выход
OSD вкл/выкл / слайд-шоу O или I / F5
Удалить в корзину и показать следующее Del (подтверждение отключается в настройках)
EXIF / настройки E / S
Место съёмки на OpenStreetMap (фото с GPS) G (или меню; в окне EXIF — кнопка)
Удалить из JPEG метаданные (камера, даты, GPS, XMP), оставив ориентацию и размер; без перекодирования кнопка «Очистить EXIF» в окне EXIF
Копировать картинку Ctrl+C
Сохранить как JPEG / PNG Ctrl+S (или меню)
Печать Ctrl+P (или меню)
Открыть в редакторе / показать в папке F4 / Ctrl+Enter

Листание файлов, независимо от типа и масштаба: N / PgDn — следующий файл, Backspace / PgUp — предыдущий. Пробел, стрелки и колесо мыши заняты листанием только пока ничем другим не заняты (у фото — пока оно вписано в окно; при увеличении стрелки панорамируют; в многостраничном TIFF → / ← и колесо сначала проходят его страницы); у видео и аудио пробел — пауза, стрелки — перемотка и громкость/соседний кадр.

В контекстном меню также: открыть во внешнем редакторе, показать в папке, сделать обоями рабочего стола (JPEG/PNG/BMP — сам файл; RAW, PSD, повёрнутые — сохраняются в mediares_wallpaper.png). Редактор задаётся в настройках отдельно для фото, видео и аудио: путь к программе (в кавычках или без) и при необходимости аргументы, например "C:\Program Files\App\app.exe" -n или code -n --wait %1; %1 — место для файла, без него путь добавляется в конец. Если поле пустое — программа «Изменить» из Windows для этого типа файла, а без неё — программа по умолчанию. Перед запуском редактора или Проводника полноэкранный режим выключается, чтобы окно программы не оказалось под ним.

Сохранить как — JPEG (качество 92) или PNG рядом с исходником. Без потерь, где это возможно: файл того же формата копируется, а RAW → JPEG — это встроенное в RAW превью как есть, с EXIF из RAW (дата, камера, объектив, экспозиция, GPS, ориентация). Иначе файл заново декодируется в полном разрешении, поворачивается как на экране (L / R) и кодируется с основными полями EXIF; прозрачность в JPEG ложится на белый.

Пропускать RAW, у которых есть JPEG (настройка): при съёмке RAW+JPEG каждый кадр встречается при листании один раз. Открытый RAW из списка не выпадает.

Цвет фона вокруг фото (и под прозрачностью PNG/GIF) выбирается в настройках; в палитре заготовлены чёрный, тёмный, средне-серый, светлый и белый. Там же — «Не растягивать маленькие изображения»: в режиме «вписать» картинка меньше окна показывается в 100 %, а не увеличивается.

Сглаживание при увеличении (включено по умолчанию): увеличенное фото и обложка аудио рисуются бикубически через Direct2D прямо в буфер GDI, а не квадратными пикселями. В режиме «вписать» — при любом масштабе; при ручном зуме и лупе — до 400 %, дальше видны настоящие пиксели, чтобы оценивать резкость. Уменьшение, как и раньше, — GDI HALFTONE. Если Direct2D недоступен, картинка рисуется обычным GDI.

Видео и аудио

Видео — MP4, MKV, AVI, MOV/QT, WMV/ASF, WEBM, M4V, 3GP/3G2, FLV, TS, MTS, MPG/MPEG, VOB (в т.ч. DVD-оцифровки MPEG-2 PS), декодирование через системные кодеки Media Foundation.

Аудио — MP3, MP2, FLAC, WAV, OGG/OGA (Vorbis), M4A/M4B (AAC, ALAC), AAC, AIFF/AIFC, CAF, MKA декодируются на чистом Rust (symphonia, вывод напрямую в WASAPI) и не зависят от установленных кодеков. WMA, Opus и AC3, которых нет в symphonia, играются через Media Foundation. Показываются обложка (встроенная или cover/folder/front.jpg из папки), название, исполнитель, альбом, год и параметры потока (symphonia).

Если файл не удаётся открыть, ListLoad возвращает NULL и TC пробует другой плагин.

Необязательно: libmpv. Если рядом с плагином или с totalcmd64.exe лежит 64-битная libmpv-2.dll (полная сборка, например shinchiro или zhongfly), видео играет она — со своими кодеками FFmpeg, независимо от Media Foundation (окно mpv внутри окна просмотра, кэш шейдеров в %LOCALAPPDATA%\mediares\mpv_shader_cache). Аудио, которое не декодирует symphonia, тоже идёт через неё, миниатюры видео берутся из неё, а фото HEIC/HEIF/AVIF/JXL она декодирует, когда в WIC нет расширения из Store. С ней распознаются форматы, которые играет только она: видео M2TS, M2T, RM, RMVB, OGV, DIVX, F4V, MXF, Y4M, DAV, NUT, DV; аудио APE, WV, DSF, DFF, TTA, MPC, TAK, DTS, EAC3, THD, MLP, SPX, SHN, W64, AMR, AU, RA и трекерная музыка MOD, XM, IT, S3M, MPTM — и поля WDX комбо-файла заполняются для них по данным mpv. Библиотека ищется один раз за запуск TC (после добавления — перезапуск); в плагин она не входит. Скачать: архив mpv-dev-x86_64-<дата>.7z (именно mpv-dev, в mpv-x86_64 библиотеки нет) из релизов shinchiro или с SourceForge; вариант x86_64-v3 быстрее, но требует процессор не старше Intel Haswell / AMD Excavator.

Плей-лист — это файлы текущей папки (фото пропускаются) или записи открытого .m3u/.m3u8. По окончании файла включается следующий (автопереход можно отключить); есть повтор списка или одного файла и случайный порядок — в контекстном меню и в настройках.

Действие Клавиши / мышь
Пауза / воспроизведение Пробел, K, клик по видео / обложке, мультимедийная клавиша
Лупа на паузе: кадр крупнее, под курсором та же точка удержание ЛКМ на видео или перетаскивание с ней
Перемотка ±5 с (шаг — в настройках) ← / →, клик или перетаскивание по таймлайну
Следующий / предыдущий ключевой кадр (аудио: ±1 с) ↑ / ↓
Скорость видео 0,25×–2× / обычная [ / ] / \
Кадр назад / вперёд (с паузой; удержание — несколько кадров). В MPG/MPEG/VOB — только вперёд: их источник Media Foundation не перематывает точно , / .
Громкость + / −, колесо мыши над панелью управления или Ctrl+колесо, ползунок; M — без звука
Следующий / предыдущий трек (только аудио/видео) кнопки ⏭ / ⏮ на панели, мультимедийные клавиши
Следующий / предыдущий файл N / P, PgDn / PgUp, Backspace
Полноэкранный режим Enter, F, F11, двойной клик; Esc — выход
Копировать фото / кадр видео / обложку в буфер обмена (вставляется и как картинка, и в папку как файл) Ctrl+C
OSD (имя, разрешение, размер, позиция; у видео — время) вкл/выкл для текущего типа O, I
Сохранить текущий кадр видео рядом с файлом (имя_1-23.456.png; PNG или JPEG — в настройках) Shift+S
Раскадровка: сетка кадров по всей длине (4×4, размер — в настройках) с временем и сведениями о файле (имя_sheet.png) Ctrl+Shift+S
Повтор фрагмента A–B: первое нажатие — начало, второе — конец, третье — выключить A
Следующая аудиодорожка видео B
Текст песни из тегов на месте обложки (ID3 USLT или TXXX:LYRICS, Vorbis LYRICS); длинный прокручивается по ходу трека, колесом мыши — вручную; Y ещё раз — обложка Y
Печать текущего кадра / обложки Ctrl+P
Открыть в редакторе / показать в папке F4 / Ctrl+Enter
Удалить в корзину Del

Шкала видео. При наведении на шкалу над ней всплывает кадр этого места (ближайший ключевой) со временем и названием главы. Главы MKV и MP4 (а с libmpv — любого формата) отмечены разрывами шкалы, концы фрагмента A–B — оранжевыми засечками.

Аудио без пауз. За несколько секунд до конца трека следующий файл очереди декодируется заранее и начинает звучать сразу за ним (если у них одинаковые частота и число каналов). Настройка «Учитывать ReplayGain» выравнивает громкость по тегам REPLAYGAIN_TRACK_GAIN/_PEAK без перегрузки.

Продолжение просмотра. Видео длиннее 5 минут (порог — в настройках) открываются с места, где их закрыли (на панели — «Продолжение с 12:34»); остановка в первые или последние 30 с не запоминается. Отключается в настройках.

Полноэкранный режим. Картинка занимает весь монитор; курсор прячется после 2,5 с бездействия.

  • Видео: панель управления полупрозрачно поверх кадра (или, если отключено, под кадром).
  • Фото: плашка ⏮ ⏯ ⏭ внизу по центру — предыдущее фото, слайд-шоу, следующее.
  • Аудио: панель прибита снизу, как в окне.
  • Кнопка ✕ в правом верхнем углу появляется, когда мышь подходит к верхнему краю экрана, и закрывает Lister (в панели быстрого просмотра Ctrl+Q — только выходит из полноэкранного режима).

С опцией «Скрывать панель при бездействии» панель показывается, только когда мышь подходит к нижнему краю экрана, и прячется через 2,5 с. Всё это — в настройках, группа «Полноэкранный режим».

OSD настраивается выпадающим списком: не показывать / на фото / на видео / на фото и видео. У видео строка рисуется прямо в кадре.

Содержимое OSD задаётся шаблоном — кнопки «Для фото...» / «Для видео...» в настройках. Кнопка «Добавить поле...» вставляет поле из меню (файл, изображение, EXIF; у видео — поток, звук, теги MKV/MP4):

{name}< [ {index} / {count} ]>
<{camera}  >< {exposure}>< {aperture}>< ISO {iso}>< {focal}>
  • {поле} — значение; неизвестное поле выводится как есть, чтобы опечатку было видно.
  • <...> — блок исчезает целиком, если в нём есть пустое поле (например, ISO у фото без EXIF).
  • {{ }} << >> — сами символы; перенос строки в шаблоне — новая строка OSD.

У многостраничного TIFF поле {page_of} даёт «стр. 2 / 5», {page} и {pages} — номер и число страниц; в файле из одной страницы они пустые, и блок с ними исчезает.

EXIF берётся из того же чтения, что нужно для автоповорота, поэтому листание не замедляется. Кодек, битрейт и теги видео читаются один раз на файл и только если шаблон их использует. В mediares.ini шаблоны хранятся в PhotoOSDTemplate / VideoOSDTemplate (перенос — \n); пустое значение — шаблон по умолчанию.

Слайд-шоу: F5, кнопка ⏯ на плашке или контекстное меню. Показываются только фото папки по кругу (аудио и видео пропускаются), интервал задаётся в настройках (по умолчанию 4 с).

Миниатюры TC (режим эскизов в панелях): плагин отдаёт ListGetPreviewBitmap — фото, кадр на 10 % длительности видео, обложку аудио (встроенную или cover.jpg из папки).

Поля WDX (обе сборки)

Поля идут в TC группой mediares в таком порядке: сначала хэши для поиска дубликатов, затем поля по типам контента — Media_Type, фото, видео, аудио; Plugin_Version — последним. Все поля доступны для колонок, подсказок, поиска и группового переименования.

Отложенные поля. Поля, которым нужно декодирование RAW, PSD, видео, аудио или долгое открытие файла через Media Foundation, возвращают FT_DELAYED: TC дочитывает их в фоне, не задерживая листание панели. Обычные фото (JPG, PNG...) декодируются быстро и считаются сразу. Результат кэшируется (ключ: путь + размер + время изменения), поэтому несколько колонок одного файла считаются один раз.

Хэши для поиска дубликатов

Поиск дубликатов в TC сравнивает поля на точное равенство, нечёткого сравнения (расстояния Хэмминга) нет. Поэтому хэш полезен ровно настолько, насколько часто у копии получается то же самое значение, а у разных файлов — разное.

Поле Как считается Что находит
Image_pHash 64 бита: DCT картинки 32×32, знак 8×8 низких частот относительно медианы Пересохранённые и уменьшенные копии. Самый надёжный для фото: ложных совпадений в замерах не было
Image_dHash 64 бита: картинка 9×8, сравнение яркости соседних по горизонтали пикселей То же, чуть чувствительнее к сильному сжатию и уменьшению
Image_CoarseHash 32 бита: то же, что dHash, на сетке 5×8 Самый терпимый: ловит копии с правкой контраста, небольшой обрезкой, превью RAW ↔ JPEG камеры. Платой — редкие совпадения у соседних кадров серии
Video_Fingerprint <секунды>s_<h25>_<h50>_<h75>: длительность и dHash кадров на 25/50/75 % Точные копии и перепаковку в другой контейнер без перекодирования
Video_dHash_Mid dHash кадра на 50 % Мягче отпечатка: не зависит от длительности и двух других кадров
Audio_Fingerprint <секунды>s_<h25>_<h50>_<h75>: спектральные хэши трёх 30-секундных окон на 25/50/75 % звучащей части, 18 бит Перекодированные копии: другой битрейт, кодек (MP3/AAC/Vorbis/FLAC), частота дискретизации, моно, громкость
Audio_PCM_Hash Хэш декодированных сэмплов без тишины по краям Тот же звук в другом контейнере или с другими тегами (WAV ↔ FLAC одной разрядности, перетегированный MP3)

Фото. Хэши считаются по пикселям файла как они записаны: поворот по EXIF не применяется, поэтому фото, повёрнутое тегом, и его копия, повёрнутая «по-настоящему», не совпадут. RAW хэшируется по встроенному JPEG-превью, PSD — по композиту. Доля копий, у которых хэш совпал с оригиналом точно (30 пар ARW+JPG с Sony A7 IV; ложные совпадения — 37 подряд идущих кадров одной съёмки):

Изменение копии dHash pHash CoarseHash
Пересохранение JPEG, качество 75 93 % 100 % 93 %
Пересохранение JPEG, качество 40 70 % 90 % 80 %
Уменьшение вдвое 90 % 93 % 97 %
Уменьшение до 1600 px 83 % 90 % 93 %
Яркость +12 97 % 97 % 100 %
Контраст +15 % 30 % 27 % 53 %
Обрезка 2 % по краям 10 % 0 % 33 %
Поворот на 90°, зеркало ≤3 % 0 % ≤3 %
Превью из RAW ↔ JPEG, снятый камерой рядом 29–57 % 26–70 % 53–80 %
Соседние кадры серии (ложное совпадение) 0 % 0 % 3 %

Практически: для копий, прошедших через мессенджеры, облака и ресайз, — Image_pHash; для «того же кадра в другой обработке» — Image_CoarseHash, просматривая найденное глазами. Обрезанные и повёрнутые копии точное сравнение не находит ни одним хэшем.

Видео. Media Foundation перематывает на ключевой кадр перед нужной точкой, и хэшируется он. У копии, перепакованной без перекодирования, ключевые кадры те же, и отпечаток совпадает; у перекодированной расстановка ключевых кадров обычно другая, и совпадения ждать не стоит. Video_Fingerprint к тому же требует совпадения длительности до секунды.

Аудио. В отпечатке всего 18 бит, подобранных на перекодированных копиях реальных треков: ~99 % копий дают ровно то же значение, что оригинал; ложных совпадений на выборке из ~400 треков не было. Другой мастеринг, live-версия или обрезанная на несколько секунд запись не совпадут. Анализ декодирует файл целиком (~0,4 с на трек 3–5 мин). Audio_PCM_Hash для lossy-форматов стабилен в пределах одной версии плагина. Файлы, которые не открывает symphonia (WMA, Opus, AC3 и всё, для чего в системе есть декодер), декодируются через Media Foundation (IMFSourceReader); их Audio_PCM_Hash зависит от установленных декодеров — стабилен на одной машине, но может отличаться на другой.

Общие

Поле Тип Значение
Media_Type строка Image, Video или Audio — по расширению, без чтения файла
Plugin_Version строка Версия плагина

Фото

EXIF читается из JPEG, TIFF и TIFF-подобных RAW (CR2, NEF, ARW, DNG, ORF, RW2, PEF). Читается только блок метаданных, поэтому поля не откладываются.

Поле Тип Значение
Image_Width, Image_Height число Размер в пикселях, без учёта поворота по EXIF. Для JPG/PNG/... — из заголовка; для RAW — из EXIF (PixelXDimension/PixelYDimension: встроенное превью бывает уменьшенным, у Sony ARW — 1616x1080 при снимке 6000x4000), без него и для PSD — размер превью или композита из анализа (отложенное)
Image_Dimensions строка ШxВ, откуда и ширина с высотой
Image_AspectRatio строка Пропорции: 3:2, 16:9, 4:3, 1:1, 21:9, иначе несократимая дробь до 20 или 1.85:1 (из того же размера)
Image_Bit_Depth число Бит на канал из заголовка: 8; 16 у 16-битных PNG/TIFF; 10–12 у HDR HEIC/AVIF; у RAW и PSD пусто
Image_Has_Alpha да/нет Есть ли канал прозрачности (он может быть и полностью непрозрачным)
Image_Sharpness число Резкость: дисперсия лапласиана снимка, уменьшенного до 1024 пикселей. Абсолютной шкалы нет — сортировка по полю в папке одной съёмки поднимает смазанные и нерезкие кадры наверх. Для JPEG и RAW снимок уменьшается прямо при декодировании (отложенное)
Photo_Make, Photo_Model, Photo_Lens строка Производитель, модель камеры, объектив
Photo_Date_Taken дата/время DateTimeOriginal (если нет — DateTime), в том времени, что стояло на часах камеры
Photo_Exposure строка Выдержка: 1/250, 2.5
Photo_FNumber дробное Диафрагма (2.8)
Photo_ISO число Светочувствительность
Photo_Focal_Length_mm / Photo_Focal_Length_35mm дробное / число Фокусное расстояние и его эквивалент для 35 мм
Photo_Flash да/нет Сработала ли вспышка
Photo_Orientation число Код ориентации EXIF 1–8
Photo_Software строка Программа, записавшая файл
Photo_GPS_Latitude, Photo_GPS_Longitude дробное Координаты в градусах (юг/запад — отрицательные)
Photo_Has_GPS да/нет Есть ли координаты (для фото без EXIF — «нет»)

Видео

Свойства потоков — через Media Foundation, без декодирования кадров. Открытие файла всё равно занимает заметное время, поэтому эти поля отложенные.

Поле Тип Значение
Video_Duration_Sec число Длительность, округлённая до целых секунд, как в Video_Length (из анализа; в Video_Fingerprint дробная часть отбрасывается)
Video_Length время Длительность, ч:мм:сс
Video_Width, Video_Height число Размер кадра
Video_Dimensions строка ШxВ из анализа
Video_Frame_Rate дробное Кадров в секунду (29.97, 25)
Video_Codec строка H.264, HEVC, AV1, VP9, MPEG-4, MPEG-2, VC-1... или FOURCC
Video_HDR строка HDR10 (PQ), HLG или SDR — по передаточной функции потока (MP4 — от Media Foundation, MKV/WebM — из элемента Colour); пусто, если файл её не указывает
Video_Rotation число Поворот при показе по часовой стрелке (0, 90, 180, 270): видео с телефона часто записано боком
Video_Bitrate_kbps число Общий битрейт файла (размер / длительность)
Video_Audio_Codec строка AAC, AC-3, E-AC-3, MP3, DTS, Opus, FLAC...; пусто, если нет звука
Video_Audio_Channels, Video_Audio_Sample_Rate_Hz число Каналы и частота первой звуковой дорожки

Теги — MKV/WebM (название из заголовка и теги всего файла; теги отдельных дорожек, вроде статистики mkvmerge, пропускаются) и MP4/MOV (iTunes ilst, атомы QuickTime ©xxx, 3GPP). Читаются только заголовки, но у MP4 они часто в конце файла: на жёстком диске это перемещение головки на каждый файл, поэтому поля отложенные, пока теги файла не прочитаны; дальше они берутся из кэша сразу.

Поле Тип Значение
Video_Title строка Название фильма
Video_Artist, Video_Director строка Исполнитель / автор, режиссёр
Video_Date строка Дата как записана в файле (2019, 2023-02-17T02:42:42+10:00)
Video_Year число Год из даты — для сортировки и поиска
Video_Genre, Video_Comment строка Жанр; комментарий или описание

Аудио

Теги читает тот же symphonia, что и декодирует: ID3v1/v2, Vorbis comments, MP4, APE, RIFF INFO, Matroska. Текст, записанный в cp1251 или UTF-8 под видом Latin-1, перекодируется. Эти поля читают только заголовки и теги, но ID3v1/APE лежат в конце файла, поэтому до первого чтения поля отложенные. Теги файла кэшируются — несколько колонок читают их один раз, а повторные запросы отвечаются сразу.

Поле Тип Значение
Audio_Duration_Sec число Длительность в целых секундах (из анализа, отложенное)
Audio_Length время Длительность, ч:мм:сс
Audio_Artist_Title строка «исполнитель - название» в нижнем регистре, без знаков препинания — ключ для поиска дубликатов по тегам
Audio_Artist, Audio_Title, Audio_Album, Audio_Album_Artist, Audio_Composer строка Исполнитель, название, альбом, исполнитель альбома, композитор
Audio_Genre, Audio_Comment строка Жанр, комментарий
Audio_Year число Год
Audio_Track, Audio_Track_Total, Audio_Disc, Audio_Disc_Total число Номер трека / всего треков, номер диска / всего дисков
Audio_Has_Cover да/нет Есть ли встроенная обложка
Audio_Codec строка MP3, AAC, ALAC, FLAC, Opus, Vorbis, PCM...
Audio_Lossless да/нет Сжатие без потерь — удобно искать lossless-версии треков
Audio_Bitrate_kbps, Audio_Sample_Rate_Hz, Audio_Channels, Audio_Bit_Depth число Параметры потока

Если файл не открывается symphonia (WMA, AC3), параметры потока (Audio_Length, Audio_Bitrate_kbps, Audio_Sample_Rate_Hz, Audio_Channels, Audio_Bit_Depth, Audio_Codec, Audio_Lossless) берутся из Media Foundation, и такие поля откладываются, как видео.

Готовые наборы колонок

Ниже — три набора для Вид → Настройка колонок панели → Новый: вставляются в поля Headers (заголовки) и Contents (значения) через диалог редактирования набора, либо напрямую строками в wincmd.ini ([Columns0], [Columns1]... секции с Headers0/Contents0 и т. д. — номер подставьте по своим наборам). mediares — имя, под которым плагин зарегистрирован в TC (по умолчанию совпадает с именем файла); если при установке ввели другое, замените префикс на него. tc.size — родное поле TC, не из этого плагина.

Фото (EXIF):

Headers=Разрешение\nКамера\nМодель\nВыдержка\nДиафрагма\nISO\nGPS Широта\nGPS Долгота\nДата снимка\nРазмер
Contents=[=mediares.Image_Dimensions]\n[=mediares.Photo_Make]\n[=mediares.Photo_Model]\n[=mediares.Photo_Exposure]\n[=mediares.Photo_FNumber]\n[=mediares.Photo_ISO]\n[=mediares.Photo_GPS_Latitude]\n[=mediares.Photo_GPS_Longitude]\n[=mediares.Photo_Date_Taken]\n[=tc.size]

Аудио (теги и параметры потока):

Headers=Исполнитель\nНазвание\nАльбом\nДата\nЖанр\nНомер\nБитрейт\nЧастота\nКаналы\nКодек\nПродолжительность\nРазмер
Contents=[=mediares.Audio_Artist]\n[=mediares.Audio_Title]\n[=mediares.Audio_Album]\n[=mediares.Audio_Year]\n[=mediares.Audio_Genre]\n[=mediares.Audio_Track]\n[=mediares.Audio_Bitrate_kbps]\n[=mediares.Audio_Sample_Rate_Hz]\n[=mediares.Audio_Channels]\n[=mediares.Audio_Codec]\n[=mediares.Audio_Length]\n[=tc.size]

Видео (параметры потока):

Headers=Название\nШирина\nВысота\nБитрейт\nКадры\nКодек\nПродолжительность\nРазмер
Contents=[=mediares.Video_Title]\n[=mediares.Video_Width]\n[=mediares.Video_Height]\n[=mediares.Video_Bitrate_kbps]\n[=mediares.Video_Frame_Rate]\n[=mediares.Video_Codec]\n[=mediares.Video_Length]\n[=tc.size]

Установка и настройки

Установка

Архивы собирает build_release.bat (в dist/); каждый открывается в TC и ставится сам:

  • WDX-only (mediares-wdx-*.zip): облегчённый контент-плагин mediares.wdx64 — только поля, без просмотрщика.

  • WLX (mediares-wlx-*.zip, сборка combo): один файл mediares.wlx64, который одновременно является и Lister-, и контент-плагином. Архив ставит его как Lister-плагин (F3); pluginst.inf умеет регистрировать файл только одного типа, поэтому контент-функции (поля поиска дубликатов и тегов) подключаются отдельно — тем же файлом, без второй копии. Проще всего — кнопкой «Зарегистрировать WDX» в настройках плагина (F3 на любом медиафайле → клавиша S или «Настройки...» в контекстном меню): она добавит строку в [ContentPlugins] файла wincmd.ini, после чего TC нужно перезапустить. Вручную:

    1. Закройте Total Commander (при выходе он перезаписывает wincmd.ini).
    2. Откройте wincmd.ini (путь — в «Справка → О программе» или в переменной %COMMANDER_INI%).
    3. В секции [ContentPlugins] добавьте строку со следующим свободным номером, например, если уже есть 0= и 1=:
      [ContentPlugins]
      2=%COMMANDER_PATH%\Plugins\wlx\mediares\mediares.wlx64
      (путь — туда, куда установился Lister-плагин).
    4. Запустите TC: поля появятся в группе mediares (колонки, поиск, групповое переименование).

    Тот же результат без правки ini: «Конфигурация → Настройка → Плагины → Контентные плагины → Настроить → Добавить», в диалоге выбора файла указать «Все файлы» и выбрать mediares.wlx64.

Настройки

Всё настраивается в окне настроек (S), править ini вручную не нужно. mediares.ini ищется рядом с DLL (портативная установка); если его там нет — используется папка плагинных настроек TC (путь из ListSetDefaultParams), т.к. папка плагина часто защищена от записи. Данные, привязанные к конкретному компьютеру, с портативным TC не переезжают и лежат в %LOCALAPPDATA%\mediares: mediares_resume.txt (позиции видео, до 200 записей), mediares_wallpaper.png и mpv_shader_cache.

Ключи секции [Settings] с неочевидным форматом: Language (auto или код секции языка: eng, rus...), PhotoBackground и OSDFontColor (COLORREF 0x00BBGGRR десятичным числом), OSDFontName (имя шрифта), OSDMode (0 — не показывать, 1 — на фото, 2 — на видео, 3 — везде), Repeat (0 — нет, 1 — список, 2 — файл), SeekStep (шаг ← / → в секундах, 1–600), ResumeThreshold (минимальная длина видео для продолжения, в секундах, 10–3600), ContactSheetColumns / ContactSheetRows (сетка раскадровки, 1–10), FrameFormat (png / jpg), PhotoEditor / VideoEditor / AudioEditor (путь к программе, можно с аргументами и %1), PhotoOSDTemplate / VideoOSDTemplate (см. OSD). Флаги — 0/1: StartFullscreen, AutoRotateExif, NoUpscale, SmoothZoom, KeepZoom, SkipRawTwins, ConfirmDelete, ResumeVideo, ReplayGain, AutoAdvance, Shuffle, OverlayPhoto, OverlayVideo, OverlayAutoHide, SeekPreview, WheelZoom.

Интерфейс на русском и английском; другие языки добавляются файлом mediares_ui.lng. auto берёт язык Total Commander (LanguageIni в wincmd.ini: wcmd_rus.lng → секция [Rus]), а без wincmd.ini — язык интерфейса Windows. Строки пишутся в коде по-английски, tr("Settings"), и переводятся по встроенному pluginst/mediares_ui.lng (combo/src/i18n.rs); тест проверяет, что каждый язык переводит каждую строку. Имена полей WDX не переводятся.

Сборка и тестирование

cargo test                 # тесты всего воркспейса
cargo build --release      # бинарники в target/release/ (для релиза — build_release.bat, см. ниже)
build_release.bat          # тесты, сборка и архивы для TC в dist/ (--no-test — без тестов)

В каждый архив кладётся инструкция для пользователя: docs/readme_rus.txt и docs/readme_eng.txt (UTF-8 с BOM, чтобы Lister сразу показал кириллицу). Новое поле WDX нужно описать в обеих: тест test_readmes_list_every_field проверяет, что там упомянуты все поля.

build_release.bat собирает каждую DLL отдельно как чистый cdylib (cargo rustc --release -p … --lib --crate-type cdylib): с типом rlib в придачу (он нужен тестам и примерам) LTO оставляет больше кода, и DLL выходят примерно на 230 КБ больше.

После сборки в target/release/:

  • mediares_wdx.dll → переименовать в mediares.wdx64
  • mediares_combo.dll → переименовать в mediares.wlx64 (он же подключается как контент-плагин)

Dev-стенд

# поля аудио-дубликатов для набора файлов
cargo run --release -p mediares_core --features audio-decode,tags --example audio_fp -- <файлы...>
# поля тегов и кодека аудио
cargo run -p mediares_core --features tags --example audio_tags -- <файлы...>
# свойства видео для полей Video_* (из Git Bash передавайте пути как D:/..., а не /d/...)
cargo run -p mediares_core --example video_meta -- <файлы...>
cargo run -p mediares_combo --example lister_harness -- <файл> <папка_скриншотов> key:4D wait:1500 shot:a key:0D wait:1000 shot:fs

Лицензия

MIT.

About

Fast 64-bit Total Commander plugin in Rust: a Lister viewer for photos, RAW, PSD, video and audio, plus content fields to find duplicate photos, videos and music by perceptual hashes and audio fingerprints. Also includes EXIF, tag and stream fields for columns, search and renaming.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages