воскресенье, 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 , вдруг кому пригодится.

Linux: UTF-8 и ID3v2 в музыкальной коллекции.

Когда музыкальная коллекция становиться довольно объемной и в ней набирается большое количество разношерстных файлов, возникает желание все это дело как то привести к общему виду. Уже довольно давно, я собирался взяться за уборку в своей папке music и вот руки наконец таки дошли.
В первую очередь меня беспокоили абракадабры в плай листах. Хотелось чтобы все было красиво и по русски. Во вторую: ID3v1, которые в последнее время все чаще стали игнорироваться некоторыми плеерами.
Я уж было собирался взяться, за написание матерого перлового скрипта, и уже совсем было полез искать для него подходящие модули... но по ходу поиска модулей, я попал как раз туда куда было мне надо, хотя и не туда, куда хотел. Как оказалась все уже давно написано(хотя если подумать это не "оказалось", это всегда так есть, но не всегда про нашу честь ;) ).
mid3iconv скрипт на питоне, заточенный специально под наши цели, расспрастраняется в составе пакета mutagen ( http://code.google.com/p/mutagen/ ), базируется на id3iconv (http://www.cs.berkeley.edu/~zf/id3iconv/), очень прост в использовании и эффективен в работе.


Usage: mid3iconv [OPTION] [FILE]...

Mutagen-based replacement the id3iconv utility, which converts ID3 tags from
legacy encodings to Unicode and stores them using the ID3v2 format.

Options:
--version show program's version number and exit
-h, --help show this help message and exit
-e ENCODING, --encoding=ENCODING
Specify original tag encoding (default is UTF-8)
-p, --dry-run Do not actually modify files
--force-v1 Use an ID3v1 tag even if an ID3v2 tag is present
--remove-v1 Remove v1 tag after processing the files
-q, --quiet Only output errors
-d, --debug Output updated tags

Files are updated in-place, so use --dry-run first.


Для нас конечно ключевым является флаг --encoding . Большая часть музыки попадает ко мне с id3 тегами в кодировке windows-cp1251, я укажу ее. О другой части файлов с id3 тегами utf-8, беспокоится не нужно, с ними ничего не случится. Если у вас имеются файлы в кодировке koi8-r вам соответственно придется вычленить их из общего числа и перекодировать отдельно. Другой флаг который заслуживает внимания это --remove-v1 , архи нужная в нашем деле вещь, после перезаписи в id3 версии 2 , в случаи если этот флаг установлен, id3 версии 1 удаляется.
Умные люди из Интернетов используют эту утилиту таким образом:

find -iname '*.mp3' -print0 | xargs -0 mid3iconv -eCP1251 --remove-v1

Суть думаю ясна без комментариев. Запускаем из каталога в котором необходимо перекодировать id3 , и очень быстро, получаем нужный результат.
С задачей которая изначально стояла передо мной я справился так быстро, что мне даже поскучнело... ...В плеере красивые русские буковки... ни одного файла со старыми id3v1... так... с кодировками и тегами покончено и что дальше?

А дальше мы займется перекодированием файлов формата mp3 в его свободный аналог ogg, но это будет завтра... ;) а сейчас пора спать :)