Фото и видеофайлы в домашней коллекции — обработка и хранение

Предисловие

Думаю, каждый фотолюбитель вроде меня сталкивался с выбором оптимального способа обработки и хранения своих фотографий. В данной статье я хочу затронуть эту тему и предложить свой вариант. Очень хочу услышать другие варианты использования.
Так получилось, что мне уютно находиться и выполнять задачи в Linux-системах, поэтому все скрипты для линукса. Но ось — не главное, главное — правильный подход.

Я фотографирую на любительскую зеркалку в RAW, потом все перевожу в JPG, которые вместе с оригиналами хранятся на NAS. Все отсортировано по датам, отдельные события помечены тэгами для удобства поиска в дальнейшем. Также снимаю на видекамеру в 1080p.
SD-карта с фотика/видеокамеры вставляется в неттоп на Linux, работающий круглосуточно, который и является главным действующим лицом. Далее через udev присваивается имя устройства, чтобы можно было обозвать карточку по-своему и выполнить заранее подготовленный скрипт (подробнее про составление udev-правил можно ознакомиться здесь). Мой вариант правил выглядит следующим образом:
$ cat /etc/udev/rules.d/81-local.rules

KERNEL=="sdb1", SUBSYSTEM=="block", ATTR{size}=="63395840", NAME="SDcard_camcorder", RUN+="/usr/bin/zprocess_sd.sh"
KERNEL=="sdb1", SUBSYSTEM=="block", ATTR{size}=="7919616", NAME="SDcard_camera", RUN+="/usr/bin/zprocess_sd.sh"


я присваиваю разные имена (NAME) карточкам, в зависимости от их размера (ATTR{size}), после чего запускается скрипт (RUN). Параметры устройства можно узнать, воспользовавшись udevinfo или udevadm (в зависимости от дистрибутива):
udevadm info -a -p `udevadm info -q path -n /dev/sdb`
(вместо /dev/sdb поставьте свое устройство)
При составлении правил важно однозначно определить девайс, иначе команда, указанная после RUN+= будет запускаться более одного раза, что будет вводить сумятицу.
Udev запускает простой скрипт /usr/bin/zprocess.sh, который перемещает информацию с SD-карты и производит сортировку:
#!/bin/bash
{
sleep 10
su igor -c "/home/igor/scripts/move_from_sd.pl";
umount /dev/SDcard_cam*;
su igor -c "/home/igor/scripts/sort.pl";
} &


move_from_sd.pl перемещает содержимое карточки в to_sort папку на NAS, пишет в лог, по завершении работы пищит пять раз — можно вытаскивать карту:
#!/usr/bin/perl -w

use strict;
use File::Copy;
use File::Find;
my $today = `date +%F_%T`;
my $logfile = "/mnt/tank/media/move_from_sd_$today.log";
my @mount_string = split /\s+/, `mount|grep -i sdcard`;
my $to_sort_folder = "/mnt/tank/media/to_sort/";
open LOGFILE, ">>$logfile" or die "Cannot create logfile: $!";
select LOGFILE;
if (defined $mount_string[2]) {
	print "SD card is mounted on $mount_string[2]\n";
	find(\&movefiles, $mount_string[2]);
	} else {
	print "SD card is not mounted!\n";
}
sub movefiles {
        if (/(\.CR2$|\.MTS$)/) {
		print "Old file: $_\n";
                my $newfile = $to_sort_folder . $_;
		print "New file: $newfile\nMoving file...\n";
		if (-e $newfile) {
                	$newfile = "$newfile"."_1";
                	move ($_, $newfile);
                	print "Done! Had to rename to $newfile\n";
        	} elsif (move ($_, $newfile)) {
        		print "Done!\n";
        	} else {
                print "moving $_ to $newfile failed: $!\n";
        	}
        }
}
`beep -D 300 -l 700 -r 5`;


Этим скриптом я также скидываю и AVCHD-файлы с видеокамеры. Поставьте ваши типы файлов вместо CR2 и MTS. Я не программист, так что не рубите сгоряча за код.

sort.pl сортирует файлы по папкам по дате, месяцу и году, используя exiftool:

#!/usr/bin/perl -w
use strict;
my $today = `date +%F_%T`;
my $logfile = "/mnt/tank/media/sort_$today.log";
my $raw_video_dir = "/mnt/tank/media/AVCHD";
my $video_dir = "/mnt/tank/media/Videos";
my $raw_photo_dir = "/mnt/tank/media/RAW";
my $photo_dir = "/mnt/tank/media/Pictures";
my $to_sort_dir = "/mnt/tank/media/to_sort";
open LOGFILE, ">>$logfile" or die "Cannot create logfile: $!";
select LOGFILE;
foreach (<$to_sort_dir/*.MTS>) {
	if (! /\d+_\d+\.MTS/) {
	print "Renaming file $_..\n";
	`exiftool '-FileName<DateTimeOriginal' -d %Y%m%d_%H%M%S%%-c.%%e $_`;
	}
}
foreach (<$to_sort_dir/*.MTS>) {
chdir($raw_video_dir);
print "Copying video file $_ into AVCHD ($raw_video_dir) folder..\n";
`exiftool -o . '-Directory<DateTimeOriginal' -d %Y/%m/%d $_`;
chdir($video_dir);
print "Moving video file $_ into Videos ($video_dir) folder..\n";
`exiftool '-Directory<DateTimeOriginal' -d %Y/%m/ $_`;
}
foreach (<$to_sort_dir/*.CR2>) {
chdir($raw_photo_dir);
print "Copying photo file $_ into RAW ($raw_photo_dir) folder..\n";
`exiftool -o . '-Directory<DateTimeOriginal' -d %Y/%m/%d $_`;
chdir($photo_dir);
print "Moving photo file $_ into Pictures ($photo_dir) folder..\n";
`exiftool '-Directory<DateTimeOriginal' -d %Y/%m/ $_`;
}


Сначала переименовываю файлы с видеокамеры в YYYYMMDD_HHMMSS. Все оригиналы из to_sort — RAW и AVCHD файлы — копирую в соответствии с датой снимка DateTimeOriginal в год/месяц/день папки RAW и AVCHD соответственно. Затем перемещаю все в Pictures и Videоs папки — таким же способом, но в год/месяц. Получается примерно такое распределение файлов по папкам:
-->RAW-->2011-->11-->12
IMG1234.CR2
IMG1236.CR2
-->AVCHD-->2011-->11-->10
20111110_112323.MTS
-->Pictures-->2011-->11
IMG1234.CR2
IMG1236.CR2
-->Videos-->2011--11
20111110_112323.MTS
Конвертирование буду производить уже внутри Pictures и Videos папок, а оригиналы трогать не буду.

Конвертирование

Фото конвертируется в папке Pictures. Для обработки RAW я использую RAWTherapee.
В настройках программы стоит «Save Processing Parameters next to file», поэтому после изменения RAW файла появляется такой же файл с расширением pp3, являющийся профилем преобразования. Конвертирование в JPG происходит 3 раза в сутки по крону следующим скриптом, сам RAW-файл удаляется по завершении:

#/usr/bin/perl
use strict;
use warnings;
use File::Find;
my $today = `date +%F_%T`;
my $logfile = "/mnt/tank/media/raw_conversion_$today.log";
my $photo_dir = "/mnt/tank/media/Pictures/";
my $rt_path = "/home/igor/RawTherapee/rawtherapee";
open LOGFILE, ">>$logfile" or die "Cannot create logfile: $!";
select LOGFILE;
find(\&convert, $photo_dir);
sub convert {
if (/\.CR2$/) {
	print "----"x7 . "\n";
	print "Converting $_ into jpeg..\n";
	print (my $result = `$rt_path/rawtherapee -o . -S -j67 -c $_ 2>&1`);
	(my $picture = $_) =~ s/CR2/jpg/;
	my $pp3 = $_ . ".pp3";
	if (-e "$picture") {
		unlink $_;
		unlink $pp3;
		}
	} 
}


Само конвертирование — это команда rawtherapee -o. -S -j67 -c
конвертирующая в JPG с компрессией 67 в ту же директорию (-o .), в batch mode (-c). Опция -S означает, что rawtherapee будет пропускать RAW-файл, если нет соответствующего pp3 файла (-S) (т. е. только просмотренные/измененные RAW-файлы). Можно ставить флаг -s и указывать через -p название профиля, который будет использован для преобразования.

Видео конвертируется в папке Videos — все имеющиеся MTS-файлы конвертируются в MKV при помощи HandBrakeCLI. Запускается два раза в сутки по крону.

#!/usr/bin/perl -w
use strict;
use File::Find;
my $today = `date +%F_%T`;
my $logfile = "/mnt/tank/media/mts_conversion_$today.log";
my $video_dir = "/mnt/tank/media/Videos";
open LOGFILE, ">>$logfile" or die "Cannot create logfile: $!";
select LOGFILE;
find(\&convert, $video_dir);
sub convert {
if (/MTS$/) {
	(my $outfile = $_) =~ s/MTS/mkv/;
	print "Converting $_ into $outfile ...\n";
	`HandBrakeCLI -e x264 -q 20 -f mkv -i $_ -o $outfile`;
	unlink $_;
	} 
}


В итоге в папках Pictures и Videos лежат JPG и MKV.
Дальнейший просмотр и оценку, расставление тэгов и загрузку в Picasa/Flickr делаю в Shotwell.

Заключение

Этим способом я разгрузил свой рабочий ноутбук, теперь вся конвертация происходит автоматически на другом хосте в домашней сети. Все мои фото и видео хранятся на NAS на RAID-6, поэтому не переживаю, если что-нибудь случится с моим ноутбуком.
Как говорится, Tim Towdy, поэтому буду рад услышать как вы обрабатываете и храните ваши фото и видео файлы, особенно используя средства ОС GNU/Linux.

Комментарии 13

    +1
    для bash можно использовать тэги

    <source lang="bash">
    yum update && yum upgrade
    </source>
    

    тогда смотреться будет лучше
      0
      Спасибо! Подправил.
      +9
      Я понимаю смысл хранить равы, понимаю смысл хранить жпеги, которые появляются после обработки равов (lightroom'ом например). Но не понимаю смысл хранить автоконвертированные жпеги, удаляя равы. Из этих жпегов потом все равно многого не выжмешь.

      Поэтому у меня примерно так процесс строится: флешку вставил — импортировал равы лайтрумом, потом, когда есть время/настроение обработал их, экспортировал в папочку (в соотв. с принятой сортировкой).
      Скопировал и то и другое на второе хранилище (старые равы иногда подчищаю с ноутбука, но не часто).
        +2
        > rawtherapee будет пропускать RAW-файл, если нет соответствующего pp3 файла (-S) (т. е. только просмотренные/измененные RAW-файлы)

        Ох, посыпаю голову пеплом. Невнимательно читал.
        Получается, что вы сначала скидываете равы, потом обрабатываете их, а потом уже создается жпег с удалением исходника. Неплохая схема )
          0
          Да, необработанные RAW-файлы останутся в «рабочей» папке. Все оригинальные RAW-файлы хранятся в отдельной («архивной») директории, а конвертация происходит в «рабочей» папке. В RAWtherapee выставляю нужный тип файлов для сканирования — отображаются только RAW-файлы (необработанные).
        +2
        Как фотограф, который еще и неплохо знаком с программированием, так же люблю все и вся автоматизировать.
        Недавно сделал себе веселый костыль:
        Использую lightroom на windows и стало напрягать, когда приходится ждать, пока завершится экспорт, чтоб приступить к новой партии. Выделил себе отдельную машину для экспорта, поставил туда lightroom и написал пару скриптов. Теперь по нажатию на кнопку, каталог с равками, а так же лайтрумовский каталог копируется по сетке на соседний комп, правится каталог (это sqlite3 база данных) на предмет изменившихся путей к файлам и по сокету дается команда скрипту на второй машине. Там уже скрипт запускает лайтрум с нужным каталогом, делает ctrl+a, ctrl+shift+alt+e.
          0
          Экспортированные изображения хранятся на другой машине? Можно хранить RAW на отдельной машине и редактировать на основном компе через SMB, тогда не нужно будет копировать.
          0
          >Все отсортировано по датам, отдельные события помечены тэгами для удобства поиска в дальнейшем.
          Хотелось бы про тэги подробнее? на какой стадии ставятся тэги, и где хранятся? привязаны ли они к чему то (аккаунт пикасы, или база программы обработки фото) или тэги в самих файлах остаются (exif?)
            +1
            Тэги расставляю уже для конечных изображений (jpg) в Shotwell, причем сохраняю в exif файла (можно просто хранить в базе программы, а файлы оставлять нетронутыми). Это удобно, когда, например, импортируешь в Shotwell с другого компа — все тэги уже будут на месте. В Picasa тэги, созданные в Shotwell видны в поле «ключевые слова». F-Spot, насколько я помню, пишет туда же.
            0
            Извините что не по теме. Посоветуйте пожалуйста софтину, которая умеет из отсканированной пачки фоток (3-4 фотографии в 1 изображении) автоматически вырезать несколько снимков и сохранять каждый отдельно?

            Отцифровал родным альбом из прошлого, они мне еще 9 принесли. Это на пару суток, если руками перебирать, обрезать, сохранять…
              +1
              Спасибо за статью! Уверен, что у многих свои решения, поэтому подкину своих балалаек.

              1. Сортирую файлы я в каталоги вида 2011/2011-09-27, с учетом того, что снимаю я в месяц не более 10 дней, к концу года в каталоге 20YY собирается не более 120 каталогов, и число кликов радикально уменьшается. Метод такой же (bash+exiftool).
              2. Снимаю я raw+jpeg, что конечно уменьшает доступный объем карты, но ценой примерно 20%, так что я пренебрег, просто взял карточку побольше. Поэтому этап конвертации отсутствует.
              3. Я параноик: у меня два NAS, одно у меня в квартире, второе почти такое же — у родителей (5 км). Между ними репликация средствами zfs. Там свои любопытные скрипты, с созданием снапшотов. Но я и защищаюсь не от выхода диска из строя, а от грабежа/потопа/пожара.
              4. Из-за п.3 я боюсь стирать фотографии с карты, пока они не уехали на удалённое хранилище. И тут надо бы как-то автоматизировать процесс, потому что пока нет. Но Вы дали отличную идею, буду думать.

              Спасибо ещё раз!
                0
                У моего фотоаппарата плохо с авто балансом белого в помещении, поэтому в jpeg снимать могу только если при естественном освещении. Частенько приходится корректировать экспозицию, поэтому только в raw снимаю.
                Думаю, п.3 не даст 100% надежности, нужно поддерживать оба NAS, лучше синхронизировать в облако, но это дорогостоящее удовольствие. С ZFS — интересно, я обычно пользуюсь rsync для подобных целей.
                  0
                  Я рассматривал rsync, более того, по сравнению с репликацией снапшотов zfs у него есть свой плюс: всё-таки бекап идёт на уровне файлов, а не блоков файловой системы. Но zfs подкупила своей простотой в части работы с raidz, эффективной реализацией удаленной репликации и простотой обработки ситуации переименования файлов и каталогов. Да, у rsync есть патч, который обрабатывает такую ситуацию, но он почему-то до сих пор не в официальной ветке.

                  Пока что я утешаю себя scrubbing-ом по cron раз в две недели на обоих хранилищах.

                  А что значит «нужно поддерживать оба NAS»? Второй NAS практически необслуживаемый, у родителей под столом под UPS. Шлет письма изредка, о том, как ему живется.

                  Единственное, чего я боюсь — ошибки консистентности файловой системы, тем более, что репорты такого рода проблем были. Но тут я придерживаюсь дисциплины: никаких русских имён файлов и длинных (более 255 символов) путей.

              Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

              Самое читаемое