2

I am trying to reencode a few hundred videos to X265 but there are many directories that have spaces in the filenames as do some of the files. I have looked at a bunch of scripts and am struggling to find one that works with the spaces and the different directory levels.

This one works, as long as there is no sub directories:

#!/bin/bash
for i in *.avi;
do 
    ffmpeg -i "$i" -c:v libx265 -c:a copy X265_"$i"
done

I have been trying to work with this bash script, but it fails with the whitespaces I am guessing.

#!/bin/bash
inputdir=$PWD
outputdir=$PWD
while IFS= read -r file ; do
  video=`basename "$file"`
  dir=`dirname "$file"`
 ffmpeg -fflags +genpts -i "$file" -c:v libx265 -c:a copy "$dir"/X265_"$video"
done < <(find "$inputdir" -name "*.avi" | head -100)

On this thread it looks like a good solution for windows users, but not linux. FFMPEG - Batch convert subfolders

FOR /r %%i in (*.mp4) DO ffmpeg32 -i "%%~fi" -map 0:0 -map 0:1 -map 0:1 -c:v copy -c:a:0 aac -b:a 128k -ac 2 -strict -2 -cutoff 15000 -c:a:1 copy "%%~dpni(2)%%~xi"

If you can point me to the right solution that is appropriate for bash, I would appreciate it.

Cœur
  • 37,241
  • 25
  • 195
  • 267
Alan
  • 2,046
  • 2
  • 20
  • 43

2 Answers2

2

This is a typical scenario for find and xargs

find /path/to/basedir -name '*.avi' -print0 | xargs -0 convert.sh

where -print0 and -0 ensure the proper handling of names with spaces.

And in convert.sh, you have your for loop, almost the same as in your first script

#!/bin/bash

for i; do
    d=$(dirname "$i")
    b=$(basename "$i")
    ffmpeg -i "$i" -c:v libx265 -c:a copy "$d/X265_$b"
done

for i without anything means the same as "for all arguments given", which are the files passed by xargs.

To prepend the filename with a string, you must split the name into the directory and base part, and then put it together again.

Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • Thanks Olaf, this looks like an elegant solution, but I am getting an error where it is trying to prepend the X265_ to the directory name when it goes to the first directory. I get this error: `X265_./Sub Directory/File with Spaces.avi: No such file or directory` – Alan Oct 04 '16 at 21:45
  • @Alan This might not work properly. Maybe it needs some fiddling with quotes and escaping, but I am not at my computer now to test it. – Olaf Dietsche Oct 04 '16 at 21:54
  • Thanks @Olaf, The edits you made worked out perfect. – Alan Oct 04 '16 at 22:14
0

Using xargs + sh -c, it is also possible to use bourne script replacements by passing the -I variable–—in this case FILE——to sh -c as a positional parameter to be used in as a $1 expansion:

find . -name '*.flac' -print0 | \
xargs -0 -I FILE \
sh -c 'ffmpeg -i "$1" -c:a libfdk_aac -vbr 3 "${1%.flac}.m4a"' -- FILE

Here, I just chop off the .flac extension with ${1%.flac} and add m4a.

Jonathan Komar
  • 2,678
  • 4
  • 32
  • 43