Скрипт bash для преобразования ffmpeg не зацикливается

У меня есть этот скрипт bash для пакетного преобразования некоторых файлов mp4:

#!/bin/bash
ls dr*.mp4 | grep -v -E "\.[^\.]+\." | sed "s/.mp4//g" | while read f 
do
    TARGET="$f.ffmpeg.mp4"
    if ! [ -f $TARGET ]
    then
        echo $TARGET
        ffmpeg  -nostdin -i $f.mp4 -s 320x180 -vc h264 -acodec copy -f mp4 -y $TARGET
    fi

    TARGET="$f.ffmpeg.flv"
    if ! [ -f $TARGET ]
    then
        echo $TARGET
        ffmpeg  -nostdin -i $f.mp4 -s 320x180 -acodec copy -y $TARGET
    fi

    TARGET="$f.jpg"
    if ! [ -f $TARGET ]
    then
        echo $TARGET
        ffmpeg -nostdin -i $f.ffmpeg.mp4 -ss 0 -vframes 1 -f image2 $TARGET
    fi

    TARGET="$f.ffmpeg.ogv"
    if ! [ -f $TARGET ]
    then
        echo $TARGET
        ffmpeg  -nostdin -i $f.mp4 -s 320x176 -ar 11025 -acodec libvorbis -y $TARGET
    fi
done 

Он запускается один раз, но преобразует имя входного файла в 4 разных формата, но не переходит к следующему имени входного файла. Я пытался перетасовать порядок различных преобразований, но все равно скрипт запускается ровно один раз для одного имени файла. Я пытался запустить ffmpeg с флагом -nostdin, но он говорит

"Unrecognized option 'nostdin'"

Версия ffmpeg — это версия ffmpeg 0.10.6-6:0.10.6-0ubuntu0jon1~lucid2. Я просто обновляю пакет ffmpeg с http://ppa.launchpad.net/jon-severinsson/ffmpeg/ubuntu и не может найти более новую версию. Базовая система

Distributor ID: Ubuntu 
Description:    Ubuntu 10.04.1 LTS 
Release:        10.04 
Codename:       lucid

person Alex Monthy    schedule 23.05.2013    source источник
comment
Каков результат ls dr*.mp4 | grep -v -E "\.[^\.]+\." | sed "s/.mp4//g"?   -  person slhck    schedule 25.05.2013


Ответы (2)


Не анализируйте вывод ls, вместо этого вы можете использовать globbing. Вы также должны указать свои переменные, чтобы учесть возможные пробелы в именах файлов:

for input in dr*.mp4; do
    output=${input%.mp4}.ffmpeg.mp4
    [ -f "${output}" ] || ffmpeg -nostdin -i "${input}" -s 320x180 -vc h264 -acodec copy -f mp4 -y "${output}"

    output=${input%.mp4}.ffmpeg.flv
    [ -f "${output}" ] || ffmpeg -nostdin -i "${input}" -s 320x180 -acodec copy -y "${output}"

    [...]
done

Что касается ошибки, которую вы получаете, согласно ChangeLog параметр -nostdin был добавлен в ffmpeg 1.0, поэтому вам необходимо обновить установку ffmpeg с 0.1x до 1.0.x.

person Adrian Frühwirth    schedule 30.05.2013

Я столкнулся с той же проблемой с циклом while, потому что мне не хватало флага -nostdin в одной из моих команд ffmpeg. Я думаю, потому что read читает из стандартного ввода, что наличие команды ffmpeg там потребляло часть данных. В моем случае мой цикл while выглядел так:

find /tmp/dir -name '*-video' | while read -r file; do
    # note: I forgot -nostdin on the ffmpeg command
    ffmpeg -i "$file" -filter:v "amazing_filtergraph" out.mp4
done

И я получаю сообщение об ошибке tmp/dir/1-video not found (обратите внимание, что в пути отсутствует начальная косая черта). Как только я добавил -nostdin проблема была решена.

Также обратите внимание, что в цикле while вы практически всегда хотите использовать флаг -r в противном случае могут возникнуть неожиданные продолжения новой строки.

person Doug Richardson    schedule 12.09.2015