ffmpeg from pngs... Error with subset of PNGS? - ffmpeg

I have about 1200 pngs that I'm converting into a movie. Some of them are missing: i.e. - _00003.png, _00005.png exist, but 1, 2, and 4 do not.
The following command works for other datasets, but not my current set of pngs:
ffmpeg -i pngs/_*.png -y -vcodec mpeg4 -pix_fmt yuv420p -r 25 -filter:v 'setpts=1.2*PTS' p3SN.mp4
I get this error:
Output #61, image2, to 'pngs/_00096.png':
Metadata:
encoder : Lavf57.83.100
Stream #61:0: Video: png, rgba, 3240x2160 [SAR 3937:3937 DAR 3:2], q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
Metadata:
encoder : Lavc57.107.100 png
Output #62, image2, to 'pngs/_00097.png':
Metadata:
encoder : Lavf57.83.100
Stream #62:0: Video: png, rgba, 3240x2160 [SAR 3937:3937 DAR 3:2], q=2-31, 200 kb/s, 25 fps, 25 tbn, 25 tbc
Metadata:
encoder : Lavc57.107.100 png
[png # 0x7fae93170e00] ff_frame_thread_encoder_init failed
Error initializing output stream 63:0 -- Error while opening encoder for output stream #63:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Conversion failed!
at image _00097.png. If I remove it, it just happens a little later (105).
I've checked the images by looking at their dimensions, etc. and all of them in this range look the same (I checked all those with _0009?.png).
Any idea why this is happening?
Here's the offending file (middle) and the one before/after:

Your command will overwrite all of the input files with the first input. This is an example of why to use caution when using -y which will automatically overwrite files without asking you.
You need to tell ffmpeg to use the glob pattern:
ffmpeg -y -pattern_type glob -framerate 25/1.2 -i "pngs/_*.png" -vcodec mpeg4 -pix_fmt yuv420p -r 25 p3SN.mp4
I believe the glob pattern option does not work on Windows, but if it has an equivalent to the Linux cat command you can pipe the output: cat *.png | ffmpeg -i - output.mp4
You can use -framerate and -r instead of setpts if desired.

Related

ffmpeg can't find codec to cut 10 seconds movie

I tried to cut 10 seconds from movie and convert to MP4. But sometimes I have a error like below:
Duration: 00:08:52.40, start: 0.000000, bitrate: 1126 kb/s
Stream #0:0: Audio: wmav2 (a[1][0][0] / 0x0161), 44100 Hz, stereo, fltp, 96 kb/s
Stream #0:1: Video: wmv3 (Main) (WMV3 / 0x33564D57), yuv420p, 640x480, 1000 kb/s, SAR 1:1 DAR 4:3, 29.97 tbr, 1k tbn, 1k tbc
[mp4 # 0x5614bbea1300] Could not find tag for codec wmv3 in stream #0, codec not currently supported in container
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argumentStream mapping:
What does this error mean? Should I install some extra codec?
My exec line looks like:
ffmpeg -i input.wmv -ss 00:00:00 -to 0 -c copy 0:00:10 output.mp4
Could not find tag for codec wmv3 in stream #0, codec not currently supported in container
You're trmiing the file without recompressing, and ffmpeg does not write Windows Media 9 streams into MP4, so either recompress:
ffmpeg -i input.wmv -ss 00:00:00 -to 00:00:10 output.mp4
or output to a different container, like Matroska:
ffmpeg -i input.wmv -ss 00:00:00 -to 00:00:10 -c copy output.mkv

FFMPEG: how to wrap h264 stream into FLV container?

What I want is straightforward: wrap H.264 video stream into a FLV container. However, ffmpeg just decode the input stream and pack raw video stream into FLV. The details are described below:
The input stream is captured from a hardware-encoder video camera, and the FLV will be sent to some video server. Firstly I used following command:
$ ffmpeg -framerate 15 -s 320x240 -i /dev/video1 -f flv "rtmp://some.website.com/receive/path"
However, the resultant stream is suspicious. The watching side don't get any H.264 thing. Then I made a test by writing output to local files.
1: Read raw stream, encode by h264_omx, write to FLV file:
$ ffmpeg -framerate 15 -s 320x240 -i /dev/video0 -codec h264_omx -f flv raw_input_h264_omx.flv
......
Input #0, video4linux2,v4l2, from '/dev/video0':
Duration: N/A, start: 194017.870905, bitrate: 18432 kb/s
Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 320x240, 18432 kb/s, 15 fps, 15 tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (h264_omx))
......
2: Read H264 stream, write to FLV file:
$ ffmpeg -framerate 15 -s 320x240 -i /dev/video1 -f flv h264_input.flv
......
Input #0, video4linux2,v4l2, from '/dev/video1':
Duration: N/A, start: 194610.307096, bitrate: N/A
Stream #0:0: Video: h264 (Main), yuv420p(progressive), 320x240, 15 fps, 15 tbr, 1000k tbn, 2000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> flv1 (flv))
......
Then read the two files correspondingly:
$ ffmpeg -i raw_input_h264_omx.flv
......
Stream #0:0: Video: h264 (High), yuv420p(progressive), 320x240, 200 kb/s, 15 fps, 15 tbr, 1k tbn
$ ffmpeg -i h264_input.flv
......
Stream #0:0: Video: flv1, yuv420p, 320x240, 200 kb/s, 15 fps, 15 tbr, 1k tbn
It is clear when I give a H.264 stream, ffmpeg firstly decodes it, then pack the raw video into FLV. How to avoid that happen, and have the H.264 stream packed directly?
Supplement: I will eventually pushing multiple video streams, so don't ask me to allow ffmpeg's silent decoding, and encode the stream again.
Unless told otherwise, ffmpeg will transcode streams.
Use
ffmpeg -framerate 15 -s 320x240 -i /dev/video1 -c copy -f flv "rtmp://website/receive/path"

lower fps when using ffmpeg to convert mp4 to gif

I am using ffmpeg to convert high quality videos to gif, most of the videos are 60fps and over 720p, but when I use the code below, to convert the video to gif, I get very low fps for the gif output,
#!/usr/bin/env
palette=/tmp/pallete.png
filter="fps=50,scale=480:-1:flags=lanczos"
ffmpeg -y -i test.mov -vf $filter,palettegen=stats_mode=diff $palette
ffmpeg -y -i test.mov -i $palette -lavfi "$filter [x]; [x][1:v] paletteuse" test.gif
another issue I have noted is - as the width increases e.g 720 instead of 480 I get even lower fps.
here is output log example, the output fps is lower than the assigned 50fps
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/tmp/201631203815.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.36.100
Duration: 00:00:05.48, start: 0.016000, bitrate: 1579 kb/s
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 1334x1334, 1576 kb/s, 60.18 fps, 60 tbr, 1000k tbn, 50 tbc (default)
Metadata:
handler_name : VideoHandler
Input #1, png_pipe, from '/tmp/pallete.png':
Duration: N/A, bitrate: N/A
Stream #1:0: Video: png, rgba(pc), 16x16 [SAR 1:1 DAR 1:1], 25 tbr, 25 tbn, 25 tbc
Output #0, gif, to '/tmp/201631203815.gif':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf56.40.101
Stream #0:0: Video: gif, pal8, 480x480, q=2-31, 200 kb/s, 50 fps, 100 tbn, 50 tbc (default)
Metadata:
encoder : Lavc56.60.100 gif
Stream mapping:
Stream #0:0 (h264) -> fps
Stream #1:0 (png) -> paletteuse:palette
paletteuse -> Stream #0:0 (gif)
Press [q] to stop, [?] for help
frame= 275 fps= 32 q=-0.0 Lsize= 2480kB time=00:00:05.50 bitrate=3693.5kbits/s
How do I ensure that the output fps is always whats set by the user?
Any resource on this is highly appreciated.
UPDATE
i have also noticed that the use of a higher fps eg filter="fps=90,scale=480:-1:flags=lanczos" has the effect of slowing down the gif,like a slow motion effect, the output fps is still lower around 15fps,
setting the fps value explicitly gave the same lower fps output
results frame= 346 fps= 24 q=-0.0 Lsize= 6506kB time=00:00:06.92
bitrate=7701.8kbits/s
This is not the output fps! It's the encoding speed. Most players don't properly play GIFs with a fps higher than 50. See the demo showing this behaviour.
I'm not experienced in making GIF files with FFmpeg, but as far as I know, the fps filter has an idividual "fps" parameter for the actual framerate value, so I think it may not work correctly if you omit that.
Just to make sure the filter gets the correct value, you should explicitly set the fps value:
filter="fps=fps=50,scale=480:-1:flags=lanczos"
If it doesn't working, I'd try the regular "rate" option too:
ffmpeg -y -i test.mov -i $palette -lavfi "$filter [x]; [x][1:v] paletteuse" -r 50 test.gif
Otherways, your console output looks good (it indicates the output will be 50fps), so the phenomena is a little bit mysterious.
Working Solution:
All you need to do is to break the process into three individual steps, and use the "-framerate" demux-option.
First, let's generate the palette file:
ffmpeg -i <input_file> -filter_complex "scale=w=480:h=-1:flags=lanczos, palettegen=stats_mode=diff" palette.png
Secondly, break the video frames into image files:
ffmpeg -i <input_file> -r 50 -f image2 image_%06d.png
And finally, join said images into one GIF sequence:
(the important part here is the image2 demuxer's framerate option!)
ffmpeg -framerate 50 -i image_%06d.png -i palette.png -filter_complex "[0]scale=w=400:h=-1[x];[x][1:v] paletteuse" -pix_fmt rgb24 output.gif
Edit: Finally find the answer!
You need to use image2 demuxer's -framerate option! (answer edited accordingly)
Alternative methods:
gifsickle - convert images to gif, can set frame delay
ImageMagic - can convert video to gif directly, excellent gif quality control options.

ffmpeg - extract subtitles (which are unencrypted) when video is encrypted

I have a .wtv file, recorded from Windows Media Center, that I'd like to extract the subtitles from. The video is encrypted, but the subtitles are not (something I've been able to verify by using CCExtractor with it). FFMpeg lists the video as such:
Duration: 00:07:01.72, start: 2.214551, bitrate: 9154 kb/s
Stream #0:0[0xcc](eng): Audio: ac3, 48000 Hz, 5.1(side), fltp, 384 kb/s
Stream #0:1[0xcd]: Video: mpeg2video (Main), yuv420p(tv), 1920x1080 [SAR 1:1 DAR 16:9], Closed Captions, max. 25000 kb/s, 29.97 fps, 29.97 tbr, 10000k tbn, 59.94 tbc
Stream #0:2[0xce]: Subtitle: eia_608
When I try to run
ffmpeg -i myvideofile.wtv -an -vn -map 0:2 -c:s:0 srt test.srt
I see a lot of the following errors:
[wtv # 0x7fef79806e00] encrypted stream detected (st:1), decoding will likely fail
Last message repeated 8 times
[Closed caption Decoder # 0x7fef7982cc00] Data Ignored since exceeding screen width
and eventually:
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
I don't mind it being able to decode the video stream, but is that causing the closed caption error? If it can't decode the video it doesn't know the screen width, perhaps? Is it possible to set the closed caption decoder to ignore such errors and output anyway (it's just in text format after all)?

how to convert videos to flv using ffmpeg in php?

i am trying to convert some different video formats to flv using ffmpeg. But it seems that only some videos go through.
ffmpeg -i /var/www/tmp/91640.avi -ar 22050 -ab 32 -f flv /var/www/videos/91640.flv
here is some debug info:
Seems stream 0 codec frame rate differs from container frame rate: 23.98 (65535/2733) -> 23.98 (5000000/208541)
Input #0, avi, from '/var/www/tmp/91640.avi':
Duration: 00:01:12.82, start: 0.000000, bitrate: 5022 kb/s
Stream #0.0: Video: mpeg4, yuv420p, 1280x528 [PAR 1:1 DAR 80:33], 23.98 tbr, 23.98 tbn, 23.98 tbc
Stream #0.1: Audio: ac3, 48000 Hz, 5.1, s16, 448 kb/s
WARNING: The bitrate parameter is set too low. It takes bits/s as argument, not kbits/s
Output #0, flv, to '/var/www/videos/91640.flv':
Stream #0.0: Video: flv, yuv420p, 1280x528 [PAR 1:1 DAR 80:33], q=2-31, 200 kb/s, 90k tbn, 23.98 tbc
Stream #0.1: Audio: adpcm_swf, 22050 Hz, 5.1, s16, 0 kb/s
Stream mapping:
Stream #0.0 -> #0.0
Stream #0.1 -> #0.1
Error while opening codec for output stream #0.1 - maybe incorrect parameters such as bit_rate, rate, width or height
also, if i try to grab one frame ad convert it to jpeg i get an error as well
ffmpeg -i /var/www/tmp/91640.avi -an -ss 00:00:03 -t 00:00:01 -r 1 -y /var/www/videos/91640.jpg
debug info
...
[mpeg4 # 0x1d7d810]Invalid and inefficient vfw-avi packed B frames detected
av_interleaved_write_frame(): I/O error occurred
Usually that means that input file is truncated and/or corrupted.
im thinking that the image fails because the video conversion failed in the first place, not sure though
any ideas what goes wrong?
Bits, not kbits
From your console output:
WARNING: The bitrate parameter is set too low. It takes bits/s as argument, not kbits/s
Use 32k, not just 32.
Only stereo or mono is supported
The encoder adpcm_swf ony supports mono or stereo, so add -ac 2 as an output option. The console output would have suggested this if you were using a recent ffmpeg build.
Use -vframes 1 for single image outputs
Instead of -t 00:00:01 -r 1 use -vframes 1.
A better encoder
Instead of using the encoders flv and adpcm_swf, I recommend libx264 and libmp3lame:
ffmpeg -i input -vcodec libx264 -preset medium -crf 23 -acodec libmp3lame -ar 44100 -q:a 5 output.flv
-preset – Controls the encoding speed to compression ratio. Use the slowest preset you have patience for: ultrafast,superfast, veryfast, faster, fast, medium, slow, slower, veryslow.
-crf – Constant Rate Factor. A lower value is a higher quality. Range is 0-51 for this encoder. 0 is lossless, 18 is roughly "visually lossless", 23 is default, and 51 is worst quality. Use the highest value that still gives an acceptable quality.
-q:a – Audio quality for libmp3lame. Range is 0-9 for this encoder. A lower value is a higher quality.
Also see
FFmpeg and x264 Encoding Guide
Encoding VBR (Variable Bit Rate) mp3 audio

Resources