昨天用 ubuntu 20.04 安装的 ffmpeg 进行视频转码时,出现了一个奇葩的问题,用命令行能过的指令,通过 Java 调用死活不行。原来Java 调用的默认允许协议与命令行的竟然不一样(至于为什么不一样,还没有找到答案...)。
Java 调用 FFMPEG 命令时用 url 作为输入源,Linux 下出现 “no such file or directory” 问题的解决
ffmpeg version 4.2.2-1ubuntu1 Copyright (c) 2000-2019 the FFmpeg developers built with gcc 9 (Ubuntu 9.3.0-3ubuntu1) configuration: --prefix=/usr --extra-version=1ubuntu1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass - -enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libf ribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-l ibpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable -libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable -libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec 61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100 "https://video.example.com/video/ece851398dba2dc26df0e9ccba7fbe00/MULTI-ece851398dba2dc26df0e9ccba7fbe00-130961929/videos_200.mp4": No such file or directory
这个 No such file or directory
根本不是文件不存在,下载到本地也会报同样的错
通过'ffmpeg -loglevel debug' 首先增加调试参数。
你会看到错误输出:
ffmpeg version 4.2.2-1ubuntu1 Copyright (c) 2000-2019 the ... Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument 'debug'. 0-130961929/videos_200.mp4"'. Reading option '-vcodec' ... matched as option 'vcodec' (force video codec ('copy' to copy stream)) with argument 'libwebp'. Reading option '-lossless' ... matched as AVOption 'lossless' with argument '0'. Reading option '-qscale' ... matched as option 'qscale' (use fixed quality scale (VBR)) with argument '75'. Reading option '-preset' ... matched as AVOption 'preset' with argument 'default'. Reading option '-loop' ... matched as AVOption 'loop' with argument '0'. Reading option '-an' ... matched as option 'an' (disable audio) with argument '1'. Reading option '-vsync' ... matched as option 'vsync' (video sync method) with argument '0'. Reading option '/tmp/output.webp' ... matched as output url. Finished splitting the commandline. Parsing a group of options: global . Applying option loglevel (set logging level) with argument debug. Applying option vsync (video sync method) with argument 0. Successfully parsed a group of options. Parsing a group of options: input url "https://video.example.com/video/ece851398dba2dc26df0e9ccba7fbe00/MULTI-ece851398dba2dc26df0e9ccba7fbe00-130961929/videos_200 .mp4". Applying option c (codec name) with argument /bin/sh. Successfully parsed a group of options. Opening an input file: "https://video.example.com/video/ece851398dba2dc26df0e9ccba7fbe00/MULTI-ece851398dba2dc26df0e9ccba7fbe00-130961929/videos_200.mp4". [NULL @ 0x55fd7533f440] Opening '"https://video.example.com/video/ece851398dba2dc26df0e9ccba7fbe00/MULTI-ece851398dba2dc26df0e9ccba7fbe00-130961929/videos_200.mp4" ' for reading [file @ 0x55fd7533fec0] Setting default whitelist 'file,crypto' "https://video.example.com/video/ece851398dba2dc26df0e9ccba7fbe00/MULTI-ece851398dba2dc26df0e9ccba7fbe00-130961929/videos_200.mp4": No such file or directory
这里最重要的信息是
Setting default whitelist 'file,crypto'
在搜索过程以下两个链接非常有帮助:
https://blog.yo1.dog/fix-for-...
https://stackoverflow.com/a/1...
可以通过参数 '-report' 将完整的命令行和控制台输出转储到当前目录中名为 program-YYYYMMDD-HHMMSS.log 的文件中。该文件对于调试错误很有用。它默认为 -loglevel verbose
级别的日志输出。也可以通过设置 FFREPORT
环境变量来实现同样的效果:
FFREPORT="level=32:file=abc.log" ffmpeg -v verbose ...
以下是上面第一个链接的翻译:
使用 -safe 0
和 -protocol_whitelist file,http,https,tcp,tls
参数。完整示例在最底部。
我试图像这样使用FFmpeg的concat多路分配器:
# inputs.txt file 'http://www.example1.com/video1.mp4' file 'https://www.example2.com/video2.mp4'
ffmpeg -f "concat" -i "./inputs.txt" -codec "copy" "./concated.mp4"
首先我得到了错误:
[concat @ 0x00] Unsafe file name 'http://www.example1.com/video1.mp4' ./inputs.txt: Operation not permitted
这通过添加 -safe 0
参数来解决。然后我得到了错误:
[http @ 0x00] Protocol not on whitelist 'file,crypto'! [concat @ 0x00] Impossible to open 'http://www.example1.com/video1.mp4' ./inputs.txt: Invalid argument
我以为我可以通过简单的添加来解决这个问题, -protocol_whitelist file,http,https
但是错误变成了:
[tcp @ 0x00] Protocol not on whitelist 'file,http,https'! [concat @ 0x00] Impossible to open 'http://www.example1.com/video1.mp4' ./inputs.txt: Invalid argument
我不明白为什么我的HTTP协议输入仍然被拒绝。 http
显然在协议白名单中。然后,我注意到前两个错误之间的差别很小。看那些错误中的第一个单词。 http
VS tcp
。我意识到错误之前括号中的第一个单词是被拒绝的协议。
解决方案是也要添加 tcp
到协议白名单中( tls
如果要支持HTTPS ,也要添加到协议白名单中)。这是我的最终命令:
ffmpeg -f "concat" -safe "0" -protocol_whitelist "file,http,https,tcp,tls" -i "./inputs.txt" -codec "copy" "./concated.mp4"