当我准备使用ffmpeg截取视频帧时出现了如题错误提示。
使用命令如下:
ffmpeg -ss 15.683 -i /storage/emulated/0/test.mp4 -y -f image2 -t 0.001 /storage/emulated/0/0.jpg
为了便于理解,在说解决方法之前,先解释一下这个命令的各参数用处:
-ss 15.683 :将视频指向 15.683 秒,也就是从 15.683 秒开始
-i /storage/emulated/0/test.mp4 :输入 test.mp4 文件
-y:强制覆盖文件(防止因为重名出错)
-f image2:文件格式
-t 0.001 :持续时间(在本例中就相当于只取原视频的第 15.683秒-15.684秒)
/storage/emulated/0/0.jpg:输出文件路径
输入该命令会概率性的输出空文件,并提示以下错误:
ffmpeg version n3.0.1 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 4.8 (GCC)
configuration: --target-os=linux --cross-prefix=/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/bin/arm-linux-androideabi- --arch=arm --cpu=cortex-a8 --enable-runtime-cpudetect --sysroot=/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/sysroot --enable-pic --enable-libx264 --enable-libass --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-fontconfig --enable-pthreads --disable-debug --disable-ffserver --enable-version3 --enable-hardcoded-tables --disable-ffplay --disable-ffprobe --enable-gpl --enable-yasm --disable-doc --disable-shared --enable-static --pkg-config=/home/vagrant/SourceCode/ffmpeg-android/ffmpeg-pkg-config --prefix=/home/vagrant/SourceCode/ffmpeg-android/build/armeabi-v7a --extra-cflags='-I/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/include -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fstack-protector-all' --extra-ldflags='-L/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/lib -Wl,-z,relro -Wl,-z,now -pie' --extra-libs='-lpng -lexpat -lm' --extra-cxxflags=
libavutil 55. 17.103 / 55. 17.103
libavcodec 57. 24.102 / 57. 24.102
libavformat 57. 25.100 / 57. 25.100
libavdevice 57. 0.101 / 57. 0.101
libavfilter 6. 31.100 / 6. 31.100
libswscale 4. 0.100 / 4. 0.100
libswresample 2. 0.101 / 2. 0.101
libpostproc 54. 0.100 / 54. 0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/storage/emulated/0/DCIM/SportsCamera/YDTL0254.mp4':
Metadata:
major_brand : avc1
minor_version : 0
compatible_brands: avc1isom
creation_time : 2018-11-21 06:19:31
Duration: 00:00:17.98, start: 0.000000, bitrate: 60305 kb/s
Stream #0:0(eng): Video: h264 (Main) (avc1 / 0x31637661), yuvj420p(pc, bt709), 3840x2160, 60301 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
Metadata:
creation_time : 2018-11-21 06:19:31
handler_name : XiaoYi AVC
encoder : Ambarella AVC encoder
Output #0, image2, to '/storage/emulated/0/Android/data/com.equationl.videoshotpro/cache/3.jpg':
Metadata:
major_brand : avc1
minor_version : 0
compatible_brands: avc1isom
encoder : Lavf57.25.100
Stream #0:0(eng): Video: mjpeg, yuvj420p(pc), 3840x2160, q=2-31, 200 kb/s, 29.97 fps, 29.97 tbn, 29.97 tbc (default)
Metadata:
creation_time : 2018-11-21 06:19:31
handler_name : XiaoYi AVC
encoder : Lavc57.24.102 mjpeg
Side data:
unknown side data type 10 (24 bytes)
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> mjpeg (native))
Press [q] to stop, [?] for help
frame= 0 fps=0.0 q=0.0 Lsize=N/A time=00:00:00.00 bitrate=N/A speed= 0x
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
搜索了一圈没有发现类似的问题,而且令人费解的是,该问题是概率性出现,并且出现时间几乎找不到任何规律。
虽然网上没有发现有类似的问题,但是我却发现我的写法似乎有点奇怪:
一般来说,使用 ffmpeg 会首先使用 -i 参数输入文件再使用 -ss 参数将其指向需要的位置,但是这样写的话效率比较低(具体原因网上有很多解释,我就不多说了),所以我先使用 -ss 移动指针再 -i 输入文件,问题似乎就出在这了,我看见网上几乎所有人的写法都是 -ss 参数 和 -t 参数连在一起使用的,而我不知道为什么,居然把他们分开了...
所以当我将其放在一起后,就正常了:
ffmpeg -ss 15.683 -t 0.001 -i /storage/emulated/0/test.mp4 -y -f image2 /storage/emulated/0/0.jpg
所以说,解决方案就是按照错误提示所说的,检查一下你的 -ss -t -frames 参数如果你有使用这些参数的话。
不过令我费解的是为什么 -ss 和 -t 分开后会概率性的出现输出空文件而不是直接100%输出错误呢?希望有大佬能不吝指教。
下面给大家附上几个ffmpeg常见错误和解决方法吧,让大家能少踩坑。(下文转自:https://trac.ffmpeg.org/wiki/Errors)
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
When encountered this message is usually the last line in the console output. By itself is not very informative, but it is always accompanied by a more specific message that explains the actual issue, so scroll up for the actual error.
Invalid input file index: 2
The -map option is used to choose what inputs you want when default stream selection behavior does not fit your needs. This message can occur when the -map option is used to reference an input that does not exist. For example, if you have two inputs, but you're tyring to map a non-existing third input with -map 2 (note that ffmpeg starts counting from 0) then this error will appear.
Properly define your -map file index values. See the -map option documentation and FFmpeg Wiki: Map for more examples.
Stream map '0:a:0' matches no streams
Similar to the above error, but instead of an incorrect file index there is an incorrect stream index. For example, if the first input contains four video streams, but you use -map 0:v:4, then you are referencing a non-existing video stream (note that ffmpeg starts counting from 0).
Properly define your -map stream index values. See the -map option documentation and FFmpeg Wiki: Map for more examples. Alternatively, add a trailing ? to your map option, such as -map 0:v:4?, to make the map optional.
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
The -ss option allows you to skip to a certain point. This message is often seen when the -ss option value is greater than the duration of the input. For example, if -ss 30 is used for a 15 second input you may see this message.
Make sure your -ss, -t, -to, and/or -frames value does not exceed the input duration.
Unknown encoder 'foo'
Your ffmpeg build does not support the encoder you are trying to use.
Use a current ffmpeg build. You may need to compile it to support your desired encoder. Alternatively, you may simply download a static build of ffmpeg–these builds usually support the most common encoders.
Trailing options were found on the commandline
This message is often overlooked by users and is caused by improper option placement. Placement of options matters, and trailing options are often ignored. Placement is as follows:
ffmpeg [global options] [input options] -i input [output options] output
The documentation will often specify if an option is global, input, and/or output.
Place your options in the correct location. Options before -i will be applied to the input, and options before the output name will be applied to the output. Options after the last output may be ignored.
No pixel format specified, yuv444p for H.264 encoding chosen. Use -pix_fmt yuv420p for compatibility with outdated media players.
Your input and output may vary in supported pixel formats. ffmpeg will attempt to choose the "best" supported pixel format for your encoder. For libx264 it may use a pixel format that is not decodable by many non-FFmpeg based media players.
Adding -pix_fmt yuv420p or -vf format=yuv420p will ensure compatibility with dumb players.
[image2 @ 0x2e43320] Could not open file : images/output.png.tmp av_interleaved_write_frame(): Input/output error
In this example the output was images/output.png, but the images directory did not exist.
Check that your directory exists and/or that the permissions are correct.
[image2 @ 0x3841320] Could not get frame filename number 2 from pattern 'output.png' (either set updatefirst or use a pattern like %03d within the filename pattern) av_interleaved_write_frame(): Invalid argument
This usually occurs because the output name is incorrect or some option was omitted.
[mp4 @ 0x563cd3fa4700] Could not find tag for codec foo in stream #0, codec not currently supported in container
As the message says, the particular codec is not supported in your output container format.
Change the codec and/or output container format.
Streamcopy requested for output stream 0:0, which is fed from a complex filtergraph. Filtering and streamcopy cannot be used together
You can't stream copy (-c copy, -codec copy, etc) an output from a filter.
Remove this option or change copy to your desired encoder.