Начну с того, что люди не использующие консоль и не пишущие хотя бы мелкие скрипты для своих нужд, могут дальше не читать и смело проходить мимо этой заметки, ибо ничего интересного для себя они тут не найдут. ;) Для остальных же преамбула...
Начать надо наверное с того, что в свое время я написал небольшой скриптик, который копировал просмотренные мной ролики с ютюба мне на диск (к стати скрипт уже переписан, ибо старый вариант перестал работать с выходом нового флеша).
Все бы хорошо, но вот ролики в формате flv очень не любит мой домашний медиацентр в виде компа с установленным на нем XBMC. За то он с удовольствием проглатывает "матрешку", контейнер, который я тоже очень люблю за его удобство и универсальность (в отличии от того же убогого avi). ;) Ну что за проблема перепаковать из одного контейнера в другой старому прожженому любителю ком-строки?! Сказано - сделано! Пишем небольшой скрипт, который из текущей папки переделывает все flv в mkv, делов то! Благо есть чудо инструмент в виде ffmpeg.
А дальше каждый файл с именем ${I} обрабатываем вышеуказанным ffmpeg. И все бы ничего, да вот только не работает цикл! :( Читает первую строку, обрабатывает и вываливается. Честно говоря решить эту головоломку я не смог. И поэтому обратился к "общественному сознанию" в виде гуглового buzz-а, где мы в несколько голов и решили проблему. :) Не буду пересказывать все исследования, скажу только результаты: оказалось, что при перекодировании ffmpeg (точнее его сборка под ubuntu) читает stdin! И соответственно "выгребает" все из трубы. Ну и конечно же цикл благословенно завершается. Вот такие вот мелкие, но поскудные грабли.
Ну а вот готовый рабочий вариант скрипта с небольшими "рюшечками" в виде zenity:
Начать надо наверное с того, что в свое время я написал небольшой скриптик, который копировал просмотренные мной ролики с ютюба мне на диск (к стати скрипт уже переписан, ибо старый вариант перестал работать с выходом нового флеша).
Все бы хорошо, но вот ролики в формате flv очень не любит мой домашний медиацентр в виде компа с установленным на нем XBMC. За то он с удовольствием проглатывает "матрешку", контейнер, который я тоже очень люблю за его удобство и универсальность (в отличии от того же убогого avi). ;) Ну что за проблема перепаковать из одного контейнера в другой старому прожженому любителю ком-строки?! Сказано - сделано! Пишем небольшой скрипт, который из текущей папки переделывает все flv в mkv, делов то! Благо есть чудо инструмент в виде ffmpeg.
find . -type f -name \*.flv -print | while read I
А дальше каждый файл с именем ${I} обрабатываем вышеуказанным ffmpeg. И все бы ничего, да вот только не работает цикл! :( Читает первую строку, обрабатывает и вываливается. Честно говоря решить эту головоломку я не смог. И поэтому обратился к "общественному сознанию" в виде гуглового buzz-а, где мы в несколько голов и решили проблему. :) Не буду пересказывать все исследования, скажу только результаты: оказалось, что при перекодировании ffmpeg (точнее его сборка под ubuntu) читает stdin! И соответственно "выгребает" все из трубы. Ну и конечно же цикл благословенно завершается. Вот такие вот мелкие, но поскудные грабли.
Ну а вот готовый рабочий вариант скрипта с небольшими "рюшечками" в виде zenity:
#!/bin/bash QUANT=`find . -type f -name \*.flv -print | wc -l` STEP=`echo 100/$QUANT | bc -l` INIT=0 ( find . -type f -name \*.flv -print | while read I do NAME=$I ffmpeg -i "${NAME}" -vcodec copy -acodec copy "${NAME}.mkv" >> /dev/null 2>&1 > /dev/null && rename "s/\.flv//" "${NAME}.mkv" INIT=`echo $INIT+$STEP | bc -l` echo $INIT done ) | zenity --progress --text="Идет обработка видео"
Собственно конструкция "> /dev/null" и позволяет решить проблему с чтением stdin.
Так же была предложена еще одна конструкция:
(ffmpeg -i "${NAME}" -vcodec copy -acodec copy "${NAME}.mkv" >> log 2>&1) & wait $!
При таком подходе ffmpeg уходит в бакграунд и тоже не мешает нормальной работе pipe-а, а wait позволяет дождаться окончания выполнения перекодирования.
Надо сказать, что проблема проявляется на ffmpeg версии 0.6. Собраный из git свежий ffmpeg не проявлял излишней рьяности в плане чтения всего и вся из stdin. :)
В общем если кто-то наступит на грабли, в виде не работающего цикла с "пайпом" - имейте в виду: видимо какая-то сволочь читает стандартный ввод! ;)
Ой... Намучились мы с этим разбором полетов хорошо, реально получился вынос мозга :)))
ОтветитьУдалить