Потребовалось мне перекодировать некоторое количество видео-файлов. Для этого я написал следующий сценарий:
Казалось-бы все готово, но я заметил, что загружен только один процессор из двух, а это значит, что этот процесс можно ускорить, раза в два.
Можно задать опции mencoder. Для x264 кодека есть возможность указать количество потоков:
Способ хороший, но не универсальный и возможно ухудшение качества результата.
Способ прост, запускаем процессы параллельно, например так:
Недостаток метода в том, что из-за того что файлы разного размера, время на их обработку может существенно различаться и в итоге один процессор может разгрузиться значительно раньше другого.
Мне хотелось каким-то образом улучшить сценарий, чтобы всегда параллельно работало две задачи и по мере их завершения запускались новые. Размышляя как бы мне это сделать, я вспомнил, что существует замечательная утилита сборки, которая может делать именно то, что мне надо. Получилось следующее:
Makefile:
Получилось на удивление просто и коротко. В начале перечисляется список всех файлов, которые я хочу получить. За ним следует путь до исходных файлов и правило сборки. Запускать командой «make -j 2», чтобы работало одновременно 2 процесса.
(Первая статья на хабре, не судите строго)
#!/bin/bash
recode() {
mencoder -o $2 $1 -ovc x264 -x264encopts bitrate=22000:keyint=50 -oac mp3lame -lameopts vbr=3:br=320 -fps 50
}
recode input/00108.mts 00108.avi
recode input/00109.mts 00109.avi
...
...
Казалось-бы все готово, но я заметил, что загружен только один процессор из двух, а это значит, что этот процесс можно ускорить, раза в два.
Первый способ: распараллеливание средствами mencoder
Можно задать опции mencoder. Для x264 кодека есть возможность указать количество потоков:
- threads=<0-16>
Использовать потоки для кодирования одновременно на нескольких процессорах (по умолчанию: 1). Это немного ухудшает качество кодирования. 0 или 'auto' — автоматически определить количество процессоров и использовать соответствующее количество потоков.
Способ хороший, но не универсальный и возможно ухудшение качества результата.
Второй способ: распараллеливание средствами Bash
Способ прост, запускаем процессы параллельно, например так:
(recode input/00108.mts 00108.avi
recode input/00109.mts 00109.avi
...
...) &
(recode input/00108.mts 00110.avi
recode input/00109.mts 00111.avi
...
...)
Недостаток метода в том, что из-за того что файлы разного размера, время на их обработку может существенно различаться и в итоге один процессор может разгрузиться значительно раньше другого.
Третий способ: распараллеливание средствами GNU make
Мне хотелось каким-то образом улучшить сценарий, чтобы всегда параллельно работало две задачи и по мере их завершения запускались новые. Размышляя как бы мне это сделать, я вспомнил, что существует замечательная утилита сборки, которая может делать именно то, что мне надо. Получилось следующее:
Makefile:
all: 00108.avi 00109.avi 00110.avi 00111.avi 00118.avi 00119.avi 00120.avi 00123.avi
VPATH = input:.
%.avi: %.mts
mencoder -o $@ $< -ovc x264 -x264encopts bitrate=22000:keyint=50 -oac mp3lame -lameopts vbr=3:br=320 -fps 50
Получилось на удивление просто и коротко. В начале перечисляется список всех файлов, которые я хочу получить. За ним следует путь до исходных файлов и правило сборки. Запускать командой «make -j 2», чтобы работало одновременно 2 процесса.
(Первая статья на хабре, не судите строго)