воскресенье, 31 июля 2011 г.

Грабим и конвертим

Задача довольно типичная: сграбить видео с камеры Mini-DV и получить что-нибудь удобоваримое (будем считать эталонным выходом DVD, хотя, конечно же, каждому своё).
Традиционное решение --- то, что я видел, что делают другие --- это:
  1. использовать kino для того, чтобы списать содержимое ленты на жёсткий диск (как говорят, "сграбить" в файлы *.dv)
  2. использовать ещё одну GUI-программу, чтобы сконвертить эти файлы в то, что нужно
Такое решение неуклюже: использование графических оболочек, кучи места для промежуточных файлов. Поэтому поставлю задачу: в командной строке сделать всё за один проход без промежуточных файлов. Амбициозно? надеюсь, что да. Реально? совершенно точно: ДА. И это --- хорошая демонстрация unix-way.
С чего начну? с инструментария, очевидно. Попробуем так:
  • dvgrab --- "грабит" из командной строки
  • ffmpeg --- прекрасно и гибко конвертит

Небольшое отступление: в процессе "хакинга" проблемы захотелось проделать банальную операцию: выделить звуковую дорожку из видео-файла. Возможно, многие вспомнят, что это можно сделать из avidemux. Прочь окна и менюшки! В командной строке:
$ ffmpeg -i mov016.dv -vn -acodec copy /tmp/1.wav
Получается WAV с одной дорожкой аудио, что и требовалось.
Итак, несколько кирпичиков, из которых я построил решение:
  • Простая конвертация файла видео в формат DVD (vob):
    $ ffmpeg -i mov016.dv -target dvd mov016.vob
  • unix-way ffmpeg: использование pipe-ов:
    $ ffmpeg -i mov016.dv -vn -acodec copy -f wav pipe: > /tmp/1.wav
  • заменить звуковую дорожку при конвертации:
    $ ffmpeg -i mov016.dv -i /tmp/1.wav -map 0:0 -map 1:0 mov016.avi
А теперь полностью задача и моё решение:
Задача: сконвертить готовый MiniDV-граб, записанный на DVD. При этом, почему-то, конверторы считают, что звук имеет частоту сэмплирования 48кГц (должно быть, это граббер напортачил). Надо вернуть звук в правильные 32кГц. (Это удалось выяснить, выделив 20 сек. звуковой дорожки, и проанализировав звук в audacity)
Решение:
$ mkfifo /tmp/v/a ; for f in `ls /media/cdrom/`; do screen -d -m bash -c "ffmpeg -i /media/cdrom/$f -vn -acodec copy -f s16le pipe: > /tmp/v/a" ; idlewrap ffmpeg -i /media/cdrom/$f -f s16le -ar 32000 -i pipe: -map 0:0 -map 1:0 -deinterlace -target dvd $f.vob < /tmp/v/a ; done ; while true; do aplay ~/Documents/sound/Масяня/Па-ба-бам-па-бам\ \(типа\,\ труба\).wav ; sleep 30 ; done
Не хочу объяснять, как это работает. Кто не сможет разобраться, тем лучше пока не пытаться писать длинные выражения в шелле. Впрочем, уважая читателя, я приведу ту же команду в отформатированном виде:
mkfifo /tmp/v/a ;
for f in `ls /media/cdrom/`; do
  screen -d -m bash -c "ffmpeg -i /media/cdrom/$f -vn -acodec copy -f s16le pipe: > /tmp/v/a" ;
  idlewrap ffmpeg -i /media/cdrom/$f -f s16le -ar 32000 -i pipe: -map 0:0 -map 1:0 -deinterlace -target dvd $f.vob < /tmp/v/a ;
done ;
while true; do
  aplay ~/Documents/sound/Масяня/Па-ба-бам-па-бам\ \(типа\,\ труба\).wav ;   sleep 30 ;
done

Следующий шаг: добавить граббинг, уместив полный цикл в одну строку без промежуточных файлов.

понедельник, 11 июля 2011 г.

iso_mount.sh : монтируем ISO-образ из-под пользователя

Задача: примонтировать ISO-файл(ы) без прав суперпользователя.

0. Устанавливаем пакеты fuseiso, cdrkit-utils (опционально notify-send и notification-daemon)
1. Кладём в $HOME/bin файл:
#!/bin/bash

MYMNT=~/mnt
VOLID=`isoinfo -d -i "$1" |
grep '^Volume id: ' |
sed "s|^Volume id: ||"`

if [[ $VOLID == "" ]]; then
VOLID=`basename "$1" | sed "s|\.iso$||"`
fi

VOLID=`echo "$VOLID" |
sed "s|[^[:alnum:] .,()-]|_|g"`

mount | grep -q "$MYMNT/$VOLID" && {
nautilus file://"$MYMNT/$VOLID"
exit 0 ;
}

mkdir -p "$MYMNT"
fuseiso -p "$1" "$MYMNT/$VOLID" &&
{ nautilus file://"$MYMNT/$VOLID" ; } ||
notify-send -u critical -i cdrom_unmount -t 60000 "Failed to mount $VOLID"

2. в файловом менеджере "открываем" файл iso этим скриптом.
3. отмонтировать можно командой `fusermount -u "%f"' (подставляем папку, куда монтировали в %f)

для операций 2 и 3 я использую nautilus и nautilus-actions. Если у Вас другой файловый менеджер (напр. KDE файло), в скрипте нужно заменить nautilus на него.

/data покорёжен, boot loop. Что делать?

Android-2.2
Ситуация: рискнул покорёжить /data (это раздел с пользовательскими данными на внутренней флешке). В результате - boot loop. Что делать?
а) перепрошивка не помогает *)
б) в recovery, в котором есть возможность форматирования /data, тоже не зайдёшь (можно зайти только из нормальной загрузки командой adb reboot recovery).

А есть ли выход?
Выход есть! и очень простой: вспоминаем, что recovery --- это тот же boot, только с другим initramfs (который не монтирует /system и всё такое). Поэтому просто переименовываем recovery.img -> boot.img и вшиваем. Загружаемся, форматируем /data, после чего вшиваем настоящий boot назад. Вот так просто...

*) по крайней мере, той прошивкой, которая была