Reputation: 11936
Trying to convert a bunch of files with ffmpeg and find.
find -name "*.mkv" | while read f
do ffmpeg -i "$f" -c copy -y "${f%.*}.mp4"
done
This should work right? It results in:
+ read f
+ ffmpeg -i '/file.mkv' -c copy -y '/file.mp4'
ffmpeg version N-61155-g61ff043 Copyright (c) 2000-2014 the FFmpeg developers
built on Mar 7 2014 19:17:59 with gcc 4.8 (Debian 4.8.2-16)
/file.mkv: No such file or directory
So I naturally try sticking the missing dot in front of the variable:
find -name "*.mkv" | while read f
do ffmpeg -i ".$f" -c copy -y ".${f%.*}.mp4"
done
The result:
+ read f
+ ffmpeg -i '../file.mkv' -c copy -y '../file.mp4'
ffmpeg version N-61155-g61ff043 Copyright (c) 2000-2014 the FFmpeg developers
built on Mar 7 2014 19:17:59 with gcc 4.8 (Debian 4.8.2-16)
../file.mkv: No such file or directory
It's specifically removing the dot at the worst possible time. Any idea what's causing this and how to fix it?
PS: -print0
in find has the same problem, and none of the files have newlines etc.
Edit: As requested, the echo. The echo works as expected:
find -name "*.mkv" | while read f
do echo ffmpeg -i "$f" -c copy -y "${f%.*}.mp4"
done
+ read f
+ echo ffmpeg -i './file.mkv' -c copy -y './file.mp4'
ffmpeg -i ./file.mkv -c copy -y ./file.mp4
Edit2: With a file with a space and one without, the filename without is changed. If I rm
the one with a space the one without works fine.
$ ls
+ ls
file.mkv file two.mkv
$ find -name "*.mkv" | while read f; do ffmpeg -i "$f" -c copy -y "${f%.*}.mp4"; done
+ find -name '*.mkv'
+ read f
+ ffmpeg -i './file two.mkv' -c copy -y './file two.mp4'
ffmpeg version N-61155-g61ff043 Copyright (c) 2000-2014 the FFmpeg developers
built on Mar 7 2014 19:17:59 with gcc 4.8 (Debian 4.8.2-16)
configuration: --arch=amd64 --enable-pthreads --enable-libopencv --enable-librtmp --enable-libopenjpeg --enable-libopus --enable-libspeex --enable-libtheora --enable-vaapi --enable-runtime-cpudetect --enable-libvorbis --enable-zlib --enable-swscale --enable-libcdio --enable-bzlib --enable-libdc1394 --enable-frei0r --enable-gnutls --enable-libgsm --enable-libmp3lame --enable-libpulse --enable-vdpau --enable-libvpx --enable-gpl --enable-x11grab --enable-libx264 --enable-filters
libavutil 52. 66.101 / 52. 66.101
libavcodec 55. 52.102 / 55. 52.102
libavformat 55. 33.101 / 55. 33.101
libavdevice 55. 11.100 / 55. 11.100
libavfilter 4. 3.100 / 4. 3.100
libswscale 2. 5.101 / 2. 5.101
libswresample 0. 18.100 / 0. 18.100
libpostproc 52. 3.100 / 52. 3.100
Input #0, matroska,webm, from './file two.mkv':
Metadata:
COMPATIBLE_BRANDS: isommp42
MAJOR_BRAND : mp42
MINOR_VERSION : 0
ENCODER : Lavf55.33.101
Duration: 00:08:15.54, start: 0.000000, bitrate: 194 kb/s
Stream #0:0(und): Audio: aac, 44100 Hz, stereo, fltp (default)
Metadata:
CREATION_TIME : 2014-03-07 04:33:17
LANGUAGE : und
HANDLER_NAME : IsoMedia File Produced by Google, 5-11-2011
Output #0, mp4, to './file two.mp4':
Metadata:
COMPATIBLE_BRANDS: isommp42
MAJOR_BRAND : mp42
MINOR_VERSION : 0
encoder : Lavf55.33.101
Stream #0:0(und): Audio: aac ([64][0][0][0] / 0x0040), 44100 Hz, stereo (default)
Metadata:
CREATION_TIME : 2014-03-07 04:33:17
LANGUAGE : und
HANDLER_NAME : IsoMedia File Produced by Google, 5-11-2011
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Press [q] to stop, [?] for help
size= 11698kB time=00:08:15.53 bitrate= 193.4kbits/s
video:0kB audio:11614kB subtitle:0 data:0 global headers:0kB muxing overhead 0.724668%
+ read f
+ ffmpeg -i /file.mkv -c copy -y /file.mp4
ffmpeg version N-61155-g61ff043 Copyright (c) 2000-2014 the FFmpeg developers
built on Mar 7 2014 19:17:59 with gcc 4.8 (Debian 4.8.2-16)
configuration: --arch=amd64 --enable-pthreads --enable-libopencv --enable-librtmp --enable-libopenjpeg --enable-libopus --enable-libspeex --enable-libtheora --enable-vaapi --enable-runtime-cpudetect --enable-libvorbis --enable-zlib --enable-swscale --enable-libcdio --enable-bzlib --enable-libdc1394 --enable-frei0r --enable-gnutls --enable-libgsm --enable-libmp3lame --enable-libpulse --enable-vdpau --enable-libvpx --enable-gpl --enable-x11grab --enable-libx264 --enable-filters
libavutil 52. 66.101 / 52. 66.101
libavcodec 55. 52.102 / 55. 52.102
libavformat 55. 33.101 / 55. 33.101
libavdevice 55. 11.100 / 55. 11.100
libavfilter 4. 3.100 / 4. 3.100
libswscale 2. 5.101 / 2. 5.101
libswresample 0. 18.100 / 0. 18.100
libpostproc 52. 3.100 / 52. 3.100
/file.mkv: No such file or directory
+ read f
Upvotes: 1
Views: 1701
Reputation: 23
Alternatively, you could execute ffmepg on each file as it's found:
find . -type f -name "*.mkv" -exec bash -c 'ffmpeg -i "$0" -codec copy "${0%.*}.mp4"' "{}" \;
Upvotes: 0
Reputation: 531075
ffmpeg
, for reasons I do not know, reads from standard input. Redirect from /dev/null
to avoid interfering with the read
statement in the while loop.
find -name "*.mkv" | while read f
do ffmpeg -i "$f" -c copy -y "${f%.*}.mp4" < /dev/null
done
Upvotes: 4