Для того, чтобы из анимированного GIFа сделать видеофайл, я недавно использовал
gifsicle
(чтобы разоптимизировать GIF и разбить на кадры) и
ffmpeg
(чтобы сделать из кадров видео):
gifsicle -U --explode "input.gif"
for f in *.gif.* ; do mv "$f" "$f.gif" ; done
ffmpeg -r 25 -i "input.gif.%03d.gif" -sameq -s 320x240 output.flv
Если нужно добавить чёрных полей (до нужного размера), действую примерно так (в данном случае, хочу получить 320×240):
ffmpeg -i input.file -s 320x180 -padtop 30 -padbottom 30 output.file
Дополнение: с новыми версиями ffmpeg (например, 0.6.90), поля к видео добавляются с помощью видеофильтра pad:
ffmpeg -i input.file -vf "scale=320:180,pad=320:240:0:30" output.file
Я не использую для разделения на кадры ImageMagick (convert), потому что мне кажется, что
gifsicle
работает быстрее и требует меньше памяти.
(in English)
Задача: отслеживать в скриптах изменения файла или файлов и выполнять какие-нибудь команды, когда файлы изменяются.
Пример: пересобирать документ LaTeX при изменении (сохранении) одного из исходных файлов.
Решение: остлеживать изменения можно с помощью утилит inotify-tools. Одна утилита,
inotifywait
ждёт указанных изменений и после этого завершается с тем или иным кодом возврата. Если произошло ожидаемое событие, код возврата
0
(успех). Именно
inotifywait
и используется в моём примере ниже. Другая утилита,
inotifywatch
, наблюдает за файлами и
собирает информацию об изменениях, на выходе выводит табличку того, что заметила. Примеры применения этой утилиты смотрите на сайте inotify-tools, там же есть и дополнительные примеры использования
inotifywait
.
Пример использования: в данном случае я предполагаю, что все исходные файлы документа LaTeX лежат в текущем каталоге, а для сборки достаточно использовать
pdflatex
и
bibtex
. Вечный цикл: ждём любых изменений файлов текста или библиографии (первая команда цикла), в случае успеха (обнаруженных изменений) исполняем все нужные команды сборки документа (вторая команда цикла).
while true ; do \
inotifywait *.tex *.bib \
&& ( pdflatex -interaction=nonstopmode mypaper && \
bibtex mypaper && \
pdflatex -interaction=nonstopmode mypaper ) \
done
Естественно, применять можно для чего угодно, не только для LaTeX.
P.S. Вариант запуска LaTeX с опцией
-interaction=nonstopmode
позволяет с одной стороны избежать запроса интерактивного ввода в случае ошибки компиляции, а с другой стороны, позволяет эти ошибки компиляции всё же увидеть.
P.P.S. Рецепт работает только в линуксе. Для *BSD есть библиотечка pnotify и kqueue.
Для просмотра какого-нибудь XML часто нужно автоматически его отформатировать (чтобы отступы слева соответствовали вложенности элементов). Особенно это полезно, когда весь исходный XML записан в одну большую строку. Такие файлы — это нечитаемая каша, которую, однако, легко привести в порядок.
Первый способ — используем XSLT
Есть у меня файл с вот таким XSL-преобразованием:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:param name="indent-increment" select="' '" />
<xsl:template match="*">
<xsl:param name="indent" select="'
'"/>
<xsl:value-of select="$indent"/>
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates>
<xsl:with-param name="indent"
select="concat($indent, $indent-increment)"/>
</xsl:apply-templates>
<xsl:value-of select="$indent"/>
</xsl:copy>
</xsl:template>
<xsl:template match="comment()|processing-instruction()">
<xsl:copy />
</xsl:template>
<!-- WARNING: this is dangerous. Handle with care -->
<xsl:template match="text()[normalize-space(.)='']"/>
</xsl:stylesheet>
Код взял здесь (предложил Николай Григорьев). Там ещё несколько вариантов есть.
В дополнение к XSL-файлу есть у меня ещё и скрипт-однострочник, который это преобразование применяет. Я выполняю XSL с помощью любимого мной
xmlstarlet
. Это программка с интерфейсом командной строки для работы с XML.
#!/bin/sh
# указать правильный путь к файлу с преобразованием!
xmlstarlet tr ~/bin/indent-xml.xsl
Пользуюсь этим скриптом так:
$ xmlindent < исходный.xml | view -
И всё, можно читать любой XML с правильными отступами. И подсветкой синтаксиса (
view
— это Vim!). Кроме
xmlstarlet
есть и другие XSLT-процессоры. На память приходит
xsltproc
и библиотечки для разных языков программирования. Вот, например, однострочник на Python.
Второй способ — используем xmllint
В пакете
libxml2-utils
есть программка для проверки и форматирования XML —
xmllint
. Для форматирования использовать так:
$ xmllint --format исходный.xml
Так даже проще.
Третий способ — xmlindent
xmlindent
— отдельная утилита, написанная на чистом Си. Говорят, работает и с задачей справляется.
По теме:
Редактирование HTML и XML в Vim (
добавил про HTML Entities)
Выделение HTML-тегов, строк и блоков кода в Vim
Vim в терминале: сохранение отступов вставленного текста
Иногда нужно замедлить (растянуть) видеоролик, чтобы он игрался как будто в режиме замедленного воспроизведения, а иногда нужно наоборот, показать «на перемотке» слишком длинный ролик, выбросить часть кадров и ускорить воспроизведение. О том как это сделать — сия заметка.
Изменить частоту кадров в видеопотоке позволяет программа
yuvfps
из пакета
mjpegtools
. Как и большинство утилит пакета она принимает и отдаёт видеопоток в формате YUV4MPEG. И
ffmpeg
, и
mencoder
тоже умеют работать с YUV4MPEG (и умеют читать и писать всякие другие форматы). Я приведу пример использования
ffmpeg
.
Итак, чтобы ускорить видео, нужно взять исходный файл и посмотреть, какая в нём частота кадров
$ ffmpeg -i normal.ogg
FFmpeg version SVN-r13582, Copyright (c) 2000-2008 Fabrice Bellard, et al.
...
Input #0, ogg, from 'normal.ogg':
Duration: 00:00:10.49, start: 0.000000, bitrate: 150 kb/s
Stream #0.0: Video: theora, yuv420p, 320x240 [PAR 1:1 DAR 4:3], 30.00 tb(r)
Must supply at least one output file
В данном случае исходный файл — 30 кадров в секунду. Затем нужно решить, во сколько раз уменьшить число кадров (исходя из желаемой длительности ролика). Потом берём исходный файл (
normal.ogg
в примере) и преобразовываем его в YUV4MPEG-поток (первый вызов
ffmpeg
), после нужно дважды вызвать
yuvfps
, первый раз, чтобы изменить число кадров в потоке (
yuvfps -s 5:2 -r 1:1
сокращает исходные 2.5 кадра до одного), второй раз, чтобы перезаписать заголовок потока, указав скорость воспроизведения (
yuvfps -r 30:1 -c
устанавливает скорость 30 кадров в секунду). В конце опять вызываем
ffmpeg
и кодируем в нужный формат (я сохранил в формате Ogg/Theora, чтобы можно было вставлять в веб-странички тэгом
<video>
). Всё вместе:
$ ffmpeg -i normal.ogg -sameq -f yuv4mpegpipe - | \
yuvfps -s 5:2 -r 1:1 | yuvfps -r 30:1 -c | \
ffmpeg -f yuv4mpegpipe -i - -sameq -y fast.ogg
Аналогично можно увеличить число кадров. Дополнительные кадры интерполируются:
$ ffmpeg -i normal.ogg -sameq -f yuv4mpegpipe - | \
yuvfps -s 1:3 -r 1:1 | yuvfps -r 30:1 -c | \
ffmpeg -f yuv4mpegpipe -i - -sameq -y slow.ogg
В этот раз видео замедляется в 3 раза: на каждую «треть» исходного кадра (
-s 1:3
) создаётся целый кадр (
-r 1:1
). Вообще, как легко заметить, в качестве частоты кадров для
yuvfps
можно указывать любые дроби в виде числитель:знаменатель.
Немного более гладкой интерполяции при увеличении числа кадров вроде бы можно добиться, если использовать yuvmotionfps, но чудес он не делает.
Теперь можно сравнить все три видео. Для просмотра нужен современный браузер с поддержкой тэга
<video/>
.
Исходное видео:
Ускоренное в 2.5 раза:
И замедленное в 3 раза:
P.S. В качестве иллюстрации использовал ролик Breitenlee-VESTAS-V-52.