Использование скриптов в Virtual Dub для автоматизации работ с видео
Задача по использованию скриптов у меня возникла, когда мне понадобилось нарезать около 100 фильмов на jpeg-картинки через каждые 5 секунд. С несколькими файлами это можно было бы сделать вручную, но 100 - достаточное количество, чтобы изучить, как можно заставить virtual dub работать по сценарию.
Скрипты и задания
В Virtual Dub можно написать любую задачу по конвертированию видео, а затем не запустить ее, а сохранить как задание (job). Этим я и воспользовался. Job-файл оказался простым текстовым файлом примерно такого вида:
// VirtualDub job list (Sylia script format)
// This is a program generated file -- edit at your own risk.
//
// $numjobs 1
//
// $job "Job 1"
// $input "F:\09003027.mpg"
// $output "*.tga"
// $state 0
// $start_time 0 0
// $end_time 0 0
// $script
VirtualDub.Open("F:\\09003027.mpg","",0);
VirtualDub.audio.SetSource(1);
VirtualDub.audio.SetMode(0);
VirtualDub.audio.SetInterleave(1,500,1,0,0);
VirtualDub.audio.SetClipMode(1,1);
VirtualDub.audio.SetConversion(0,0,0,0,0);
VirtualDub.audio.SetVolume();
VirtualDub.audio.SetCompression();
VirtualDub.audio.EnableFilterGraph(0);
VirtualDub.video.SetDepth(24,24);
VirtualDub.video.SetMode(3);
VirtualDub.video.SetFrameRate(0,1);
VirtualDub.video.SetIVTC(0,0,-1,0);
VirtualDub.video.SetRange(0,0);
VirtualDub.video.SetCompression();
VirtualDub.video.filters.Clear();
VirtualDub.audio.filters.Clear();
VirtualDub.subset.Clear();
VirtualDub.subset.AddRange(0,17596);
VirtualDub.SaveImageSequence("", ".tga", 0, 1);
VirtualDub.Close();
// $endjob
//
//--------------------------------------------------
// $done
Файл заданий представляет собой один большой скрипт на встроенном интуитивно понятном языке Virtual Dub, который комментариями разделен на отдельные задания. Как показали тесты, шапку и завершающий тег $done указывать необязательно, достаточно для каждого скрипта написать теги $script, $job и $endjob.
Скрипт для вашей задачи вы можете получить, сохранив задание в файл. В принципе, можно было бы не оформлять скрипты для нескольких файлов в виде Job-файла, а записать их одним скриптом, если бы не одно "но". Дело в том, что если Virtual Dub выполняя скрипт встретит ошибку, он останавливает скрипт. А вот если выполняется job-файл текущий скрипт останавливается и начинает выполняться следующий. Поэтому если вы хотите запустить конвертацию на всю ночь, лучше дооформить каждый скрипт тегами начала и конца задания, записать его в job-файл и запустить этот job-файл.
Job-файл запускается из меню File - Job conrol - Load Job List. Скрип запускается из меню File-Run script. Кстати job-файл можно запустить как скрипт, ведь теги начала и конца задания оформлены как комментарии. Но этот скрипт остановится на первой же ошибке.
В скрипт-файле есть одна особенность. В именах файлов все бек-слеши "\" заменяются на двойные бек-слеши "\\". Кроме того для русских букв используется кодировка кодов букв, примерно так "F:\\\xd1\x83\xd0\xb4\xd0\xb0\xd0\xbb\xd1\x8f\xd1\x82\xd1\x8c". Это нужно учитывать для правильного указания путей.
Скрипт, создающий скрипт
Окей, мы разобрались, как написать скрипт для одного файла. Если у вас много видеофайлов и всех их нужно обработать одинаково, можно конечно использовать COPY/PASTE и менять только имя файла в скрипте, но гораздо правильнее написать скрипт, который сделает это за вас. Я работаю в Windows и использовал для своей задачи командный файл CMD.
В моей задачке видеофайл сохранялся как последовательность картинок. Папка с картинками должна была располагаться в папке F:\PM и имя папки должно соответствовать имени файла. Кстати, Virtual Dub умеет сохранять картинки только в bmp или tga. Но потом все картинки я конвертировал через ACDSEE.
Итак я создал в одной директории два скрипта dubbing.cmd и test.cmd.
DUBBING.CMD
@echo off
rem %1 - script file
rem %2 - avi file
rem %3 - result dir
set sf=%~1
set workfile=%~2
set workdir=%~3%~n2
echo Script File: %sf%
echo Avi File: %workfile%
echo Result Dir: %workdir%
rem pause
if exist %1 goto skip_create
rem echo> %sf% // VirtualDub job list (Sylia script format)
rem echo>>%sf% // This is a program generated file -- edit at your own risk.
rem echo>>%sf% // $numjobs 1000
:skip_create
:addfile
md>nul "%workdir%"
set workfile1=%workfile:\=\\%
echo %workfile1%
set workdir1=%workdir:\=\\%
echo>> %sf% // $job "Job%workfile1%"
echo>> %sf% // $script
echo>> %sf% VirtualDub.Open("%workfile1%","",0);
echo>> %sf% VirtualDub.audio.SetSource(1);
echo>> %sf% VirtualDub.audio.SetMode(0);
echo>> %sf% VirtualDub.audio.SetInterleave(1,500,1,0,0);
echo>> %sf% VirtualDub.audio.SetClipMode(1,1);
echo>> %sf% VirtualDub.audio.SetConversion(0,0,0,0,0);
echo>> %sf% VirtualDub.audio.SetVolume();
echo>> %sf% VirtualDub.audio.SetCompression();
echo>> %sf% VirtualDub.audio.EnableFilterGraph(0);
echo>> %sf% VirtualDub.video.SetDepth(24,24);
echo>> %sf% VirtualDub.video.SetMode(3);
echo>> %sf% VirtualDub.video.SetFrameRate(0,1);
echo>> %sf% VirtualDub.video.SetTargetFrameRate(450,10000);
echo>> %sf% VirtualDub.video.SetIVTC(0,0,-1,0);
rem echo>> %sf% VirtualDub.video.SetRange(0,0);
echo>> %sf% VirtualDub.video.SetCompression();
echo>> %sf% VirtualDub.video.filters.Clear();
echo>> %sf% VirtualDub.audio.filters.Clear();
rem echo >> %sf% VirtualDub.subset.Clear();
rem echo >> %sf% VirtualDub.subset.AddRange(0,999999);
echo>> %sf% VirtualDub.SaveImageSequence("%workdir1%\\", ".bmp", 3, 0);
echo>> %sf% VirtualDub.Close();
echo>> %sf% // $endjob
Этот скрипт добавляет в файл скрипта %sf% строки со скриптом. Как видите, такой способ удобнее, чем COPY/PASTE - если нужно внести изменения в скрипт, это можно сделать только в этом командном файле и перегенерировать задание. Файл имеет три параметра: первый - имя файла скрипта, второй - имя обрабатываемого avi-файла, третий - папка, куда складывать картинки.
Мне некогда было заниматься преобразовыванием русских букв по шестнадцатиричным кодам, поэтому я работал только с латинскими названиями. В начале блок команд set обрабатывает имена файлов, удаляя из них кавычки, заменяя бекслеши на двойные слеши, извлекая имя видеофайла из его полного пути.. Для уточнения этого момента запустите команду set /? и увидите все возможные режимы работы этой команды в Win 2K.
Файл не удаляет файл задания, он только добавляет в него строки. ПОэтому сначала файл нужно очистить.
TEST.CMD
set sf=F:\_pm\vdub_job.jobs
del %sf%
call dubbing %sf% "F:\Films\Lost Highway CD1.avi" "F:\_pm\"
call dubbing %sf% "F:\Films\Lost Highway CD2.avi" "F:\_pm\"
rem for %%i in (f:\films\*.avi) do call dubbing %sf% %%i "F:\_pm\"
for /R f:\films\ %%i in (*.avi) do call dubbing %sf% %%i "F:\_pm\"
В этом тестовом примере показано, как можно обработать или отдельные файлы, или файлы в папке - команда FOR. Команда FOR с ключем /R перебирает рекурсивно все файлы в папке и подпапках.
Обратите внимание, что в начале файл скрипта удаляется.
Вложение: 2134857.rar