2016-05-15 4 views
1

У меня есть текстовый файл, который содержит номера кадров по строкам, и я использую скрипт bash и ffmpeg для циклического перехода по каждой строке и попытки распечатать миниатюру каждого кадра.Почему мой скрипт bash останавливается с ffmpeg?

Каждый раз, когда я запускаю скрипт bash в моем терминале, он останавливается с ошибкой, создавшей первый миниатюру. Кажется, ему не дано thumbnail уникальное имя. Что я делаю не так?

Мой Баш скрипт:

#!/bin/bash 
source text.txt 
while read name 
do 
ffmpeg -i result.mp4 -vf "setpts=N+1,select='eq(n,$name)'" -vframes 1 frames-$i.jpg 
done <text.txt 

Ошибка:

File 'frames-.jpg' already exists. Overwrite ? [y/N] Not overwriting - exiting 
+0

Переменная '$ i' пуста, вы ее никогда не определяли. Чего вы хотите? – Jahid

+1

Пожалуйста, посмотрите: http://www.shellcheck.net/ – Cyrus

+0

$ 1 может быть последовательным номером, например 1,2,3 .... – JulianJ

ответ

1

Во-первых, я предполагаю, что вы не нуждаясь в source файл текста .txt в вашем скрипте. Когда файл получен от source filename или . filename, строки кода в файле выполняются, как если бы они были напечатаны в командной строке. Таким образом, я удалил этот раздел вашего скрипта.

Во-вторых, как отметили другие, вы не указали или не обновили переменную $i. Модификация как таковая может работать для вас:

#!/bin/bash 

i="0" 
while read -r name || [[ -n "${name}" ]]; do # allows for last line with no newline 
    ffmpeg -i result.mp4 -vf "setpts=N+1,select='eq(n,${name})'" -vframes 1 frames-${i}.jpg 
    if [ "$?" -eq "0" ]; then 
     printf -- 'ffmpeg succeeded - creating frames-%s.jpg for %s\n' "${i}" "${name}" 
    else 
     printf -- 'ffmpeg failed - was unable to create frames-%s.jpg for %s\n' "${i}" "${name}" 
    fi 
    let i+="1" 
done <text.txt 

Некоторые дополнительные замечания по сценарию выше:

  1. Рекомендуется использовать -r с read отключить интерпретацию восьмеричные и линии продолжения в данные считываются. Это может удержать вас от чумы проблем, если у вашего входа есть bash экранируемых символов.

  2. Я добавил || [[ -n "${name}" ]] к условию while, чтобы последняя строка в вашем входном файле не имела символа новой строки в качестве последнего символа. В противном случае последняя строка будет проигнорирована стандартным процессом чтения, так как в конце каждой строки требуется символ новой строки.

  3. Я добавил чек встроенной переменной bash $?. Возвращаемое значение предыдущей команды сохраняется в $?. 0 указывает на успех, другие указывают на ошибку.


EDIT

Если вы хотите, чтобы помочь устранить то, что FFmpeg делает, вы можете попробовать следующий измененный скрипт:

#!/bin/bash 

set -x # activate bash debugging output 

while read -r frame_number || [[ -n "${frame_number}" ]]; do # allows for last line with no newline 
    ffmpeg -i result.mp4 -vf "setpts=N+1,select='eq(n,${frame_number})'" -vframes 1 frames-${frame_number}.jpg 
    if [ $? -eq 0 ]; then 
     printf -- 'ffmpeg succeeded - creating frames-%s.jpg\n' "${frame_number}" 
    else 
     printf -- 'ffmpeg failed - was unable to create frames-%s.jpg\n' "${frame_number}" 
    fi 
done <text.txt 

Правки включают:

  1. Упорядочение сценария для использования номеров кадров из text.txt для имени файла jpeg.
  2. Включено bash отладка путем добавления set -x.

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

+0

Это большое спасибо и за объяснение. Но немного странно, что я получаю только 22 кадра, если в текстовом файле 34? – JulianJ

+0

У всех 22 кадров есть порядковые номера в их именах (например, frames-0.jpg, frames-1.jpg, frames-2.jpg, frames-3.jpg, ...)? Или есть пробелы (например, frames-0.jpg, frames-1.jpg, frames-7.jpg, frames-9.jpg ...)? –

+0

Да, кадры последовательны, как вы описали, но, как ни странно, кадры, которые я захватываю, на самом деле не корреспондируют с кадрами в текстовом файле. – JulianJ

1

Попробуйте определения $i:

i=0 
while read name 
do 
((i++)) 
ffmpeg -i result.mp4 -vf "setpts=N+1,select='eq(n,$name)'" -vframes 1 frames-$i.jpg 
done <text.txt 
Смежные вопросы