开发者

apply ffmpeg to many files

开发者 https://www.devze.com 2023-02-16 04:50 出处:网络
I have written simple script: #!/bin/bash find . -name \"*.m4a\" | while read filename; do new_filename=$(echo \"$filename\" | sed \"s/^\\(.*\\)m4a$/\\1flac/g\");

I have written simple script:

#!/bin/bash
find . -name "*.m4a" | while read filename;
do
    new_filename=$(echo "$filename" | sed "s/^\(.*\)m4a$/\1flac/g");
    if [ ! -f "$new_filename" ]
    then
            #ffmpeg -i "$filename" -acodec flac "$new_filename" > /dev/null 2>&1;
            #wait $!;
            echo "$filename";
            echo "$new_filename";
    fi
done

it outputs correct result:

./Equilibrium, ALAC [GER] viking.folk/2003 - Demo 2003, ALAC/04 - Met.m4a
./Equilibrium, ALAC [GER] viking.folk/2003 - Demo 2003, ALAC/04 - Met.flac
./Equilibrium, ALAC [GER] viking.folk/2003 - Demo 2003, ALAC/02 - Nach Dem Winter.m4a
./Equilibrium, ALAC [GER] viking.folk/2003 - Demo 2003, ALAC/02 - Nach Dem Winter.flac

if uncomment ffmpeg and wait:

./Equilibrium, ALAC [GER] viking.folk/2003 - Demo 2003, ALAC/04 - Met.m4a
./Equilibrium, ALAC [GER] viking.folk/2003 - Demo 2003, ALAC/04 -开发者_Go百科 Met.flac
uilibrium, ALAC [GER] viking.folk/2003 - Demo 2003, ALAC/02 - Nach Dem Winter.m4a
uilibrium, ALAC [GER] viking.folk/2003 - Demo 2003, ALAC/02 - Nach Dem Winter.flac

And no flacs has been done!

PS

#!/bin/bash
find . -name "*.m4a" | while read filename;
do
    new_filename=$(echo "$filename" | sed "s/^\(.*\)m4a$/\1flac/g");
    if [ ! -f "$new_filename" ]
    then
            ffmpeg -i "$filename" -acodec flac "$new_filename";
            echo "$filename";
            echo "$new_filename";
    fi
    sleep 5;
done

1) encode start but suddenly stop with no error messages

2) encode couldn't start because of "uilibrium" instead of "./Equilibrium"

3) = 1)

4) = 2)

...

last) correctly


suddenly found a solution:

#!/bin/bash
find . -name "*.m4a" | while read filename;
do
        new_filename=$(echo "$filename" | sed "s/^\(.*\)m4a$/\1flac/g");
        if [ ! -f "$new_filename" ]
        then
                ffmpeg -i "$filename" -acodec flac "$new_filename" &
                wait $!;
        fi
done

I don't know why, but if start process in background (&) and than wait for it (wait $!) all works correctly!


Might I suggest that you can provide the following param to ffmpeg. It will process only the current file before moving onto the next file.

ffmpeg's -nostdin option avoids attempting to read user input from stdin otherwise the video file itself is interpreted.

ffmpeg -i <filename> ... -nostdin

The best part about using the above is that you can continue to use verbosity:

ffmpeg -i <filename> ... -nostdin -loglevel panic 

OR if you would rather report the output to a file do so this way:

# Custom log name (optional)
# FFREPORT=./${filename}-$(date +%h.%m.%s).log
ffmpeg -i <filename> ... -nostdin -report

You can also use a combination of the two as well.


Two problems I can see:

ffmpeg -i "$filename" -acodec flac "$new_filename" > /dev/null 2>&1;

Could be printing an error message that you can't see because you're doing > /dev/null 2>&1, which will silence any errors.

And

wait $!

won't do anything useful, because $! is only defined if you ran a command in the background (i.e. something with &).


Oh, euh, just please simplify your sed, it won't correct your bug, but will be more readeable :-P

$ echo m4a.m4a | sed 's/m4a$/flac/g'
m4a.flac
0

精彩评论

暂无评论...
验证码 换一张
取 消