воскресенье, 22 ноября 2009 г.

Linux: массовый конверт mp3 в ogg (mp32ogg)

Внимание! Прежде чем копипастить отсюда дочитайте до конца.
День начался с огорчений... Меня разбудил телефонный звонок, по телефону мне напомнили, что у меня сегодня запланирована съемка... Времени на сборы оставалось мало, как мог быстро, я оделся и обжигаясь выдул кружку кофе. Сижу жду когда за мной заедут, раздается второй звонок, выясняется, что за мной заедут только в течении получаса :) Ну, что делать? Чтобы не терять времени попусту я решил запустить скрипт конвертирования mp3 в ogg который нашел еще вчера. Пока то се, думаю, переконвертит мне пару гигабайт. Запустил mp32ogg --help:

mp32ogg v0.11-gentoo-r2
(c) 2000-2002 Nathan Walp
Released without warranty under the terms of the Artistic License

Usage: /home/serpent/bin/mp32ogg [options] dir1 dir2 file1 file2 ...

Options:
--quality=[-1..10] Set Ogg/Vorbis quality level
Defaults to bitrate of original .mp3
--delete Delete files after converting
--rename=format Instead of simply replacing the .mp3 with
.ogg for the output file, produce output
filenames in this format, replacing %a, %t
and %l with artist, title, and album name
for the track
--lowercase Force lowercase filenames when using --rename
--verbose Verbose output
--help Display this help message

Все ясно - как день, и думать нечего. Но проверить в работе все же надо. перешел в какую-то папочку, запустил mp32ogg *.mp3 результат отличный, папка наполнилась конвертированными файлами. Проверил теги, вся информация перенеслась без потерь. Убедился что битрейт источника и назначения одинаковый, как написано в краткой справке: "если битрейт не указан используется битрейт оригинального .mp3 файла", порадовался... попробовал добавить флаг --delete, все отлично, конвертирование закончилось, оригинальные файлы удалены. Ну можно запускать глобальный перекодинг, подумал я, и тут раздался третий звонок, который означал что за мной приехали и мне пора выходить. Из корня моей музыкальной коллекции запустил :

find -iname '*.mp3' -print0 | xargs -0 mp32ogg -v --delete

и уехал.
Вернулся я часа через три, подошел к компу, дернул мышкой, убедился что процесс идет и отправился обедать. После обеда все тоже было как-то не досуг, пока то се прошло еще часа два - три. И вот, когда я наконец добрался до компьютера, уселся и решил послушать свою любимую музыку, в новом формате... случилось это! Вернее случилось то, что я понял, что "это!" случалось с моими файлами все время с момента запуска перекодирования. В папках файлов не было. Результат перекодирования вываливался прямо в корень моей музыкальной коллекции. Я остановил процесс и начал судорожные попытки вычленить файлы по признаку принадлежности к автору или альбому в этом 10 гигабайтовом месиве. В конце концов я убедился, что это займет гораздо больше времени чем я могу себе позволить. Все это, еще раз, напомнило мне о том, что *nix не терпит суеты. Ну пропало, и пропало, надо как то дальше жить. Порысков по поисковикам я не нашел решения, для того как заставить этот скрипт работать с большим деревом каталогов. Встречались какие-то не внятные попытки заставить обходить каталоги с помощью выражений типа : ./ ./* * , и множественных их повторений, но суть подхода я так и не смог понять, а в общем то и сам автор признавался в том, что не вполне понимает как это работает. В итоге я решил написать скрипт на перле, который по моей задумке должен был, производить рекурсивный обход каталогов, и запускать скрипт в каждом из тех где имелись .mp3 файлы. Но вовремя одумался, ведь mp32ogg это и есть скрипт, зачем что то писать и выдумывать, когда можно только чуть-чуть подправить то, что уже написано. Так и сделал, скрипт оказался на удивление просто и внятно написан. Вообще перл, это страшная сила, бывало так, что уже в процессе разработки перестаешь понимать, что ты там 2 часа назад понаписал и как это работает. Может быть по этому править чужие скрипты на перле всегда боязно.

--- ./mp32ogg_original 2009-11-21 23:40:08.000000000 +0400
+++ ./mp32ogg 2009-11-22 01:12:29.000000000 +0400
@@ -6,6 +6,10 @@
#

# ChangeLog
+# 0.11-gentoo-r2-serpent
+# * Bobylev Roman
+# Support for output to same directory
+#
# 0.11-gentoo-r2
# * Mathias Hablützel :
# Support for german umlaut
@@ -297,33 +301,34 @@

$oggoutputfile_escaped = shell_quote($oggoutputfile);
$mp3file_escaped = shell_quote($mp3file);
- $result = system("$mpg123 -q -s $mp3file_escaped 2>/dev/null | $oggenc -q $quality --quiet --raw --raw-rate=$frequency --raw-chan=$channels -o $oggoutputfile_escaped $infostring -");
+ $dirname_escaped = shell_quote($dirname);
+ $result = system("$mpg123 -q -s $mp3file_escaped 2>/dev/null | $oggenc -q $quality --quiet --raw --raw-rate=$frequency --raw-chan=$channels -o $dirname_escaped$oggoutputfile_escaped $infostring -");

if(!$result) {
- open(CHECK,"$ogginfo $oggoutputfile_escaped |");
+ open(CHECK,"$ogginfo $dirname_escaped$oggoutputfile_escaped |");
while()
{
if($_ eq "file_truncated=true\n")
{
- warn "Conversion failed ($oggoutputfile truncated).\n";
+ warn "Conversion failed ($dirname$oggoutputfile truncated).\n";
close CHECK;
exit 1;
}
elsif($_ eq "header_integrity=fail\n")
{
- warn "Conversion failed ($oggoutputfile header integrity check failed).\n";
+ warn "Conversion failed ($dirname$oggoutputfile header integrity check failed).\n";
close CHECK;
exit 1;
}
elsif($_ eq "stream_integrity=fail\n")
{
- warn "Conversion failed ($oggoutputfile header integrity check failed).\n";
+ warn "Conversion failed ($dirname$oggoutputfile header integrity check failed).\n";
close CHECK;
exit 1;
}
}
close CHECK;
- print "$oggoutputfile done!\n";
+ print "$dirname$oggoutputfile done!\n";
if($delete) {
unlink($mp3file);
}

Вот и весь пач. Вся суть исправлений заслешировать $dirname и подставить результат этой операции($dirname_escaped) перед имением файла в параметры oggenc, все остальные подставления, для валидатора, являются косметическими и на суть не виляют. Теперь можно использовать find в связке с mp32ogg. Пропатченый файл http://votkinsk.net/sites/default/files/mp32ogg.tar_.bz2 , вдруг кому пригодится.

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