13 November 2011

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

Image processing
Sandbox
Предисловие

Думаю, каждый фотолюбитель вроде меня сталкивался с выбором оптимального способа обработки и хранения своих фотографий. В данной статье я хочу затронуть эту тему и предложить свой вариант. Очень хочу услышать другие варианты использования.
Так получилось, что мне уютно находиться и выполнять задачи в 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.
Tags:rawtherapeeexiftoolhandbrakeконвертированиеlinux
Hubs: Image processing
+30
3.2k 99
Comments 13