Targeting a specific file size in vp8+vorbis encoding using ffmpeg - ffmpeg

I have a couple videos that I want to encode to vp8 for video and Vorbis for audio. This is the FFmpeg command I'm currently using:
ffmpeg -y -i input.mp4 -map 0:v:0 -s 640x360 -filter:v fps=20 -c:v libvpx -crf 10 -b:v 200k -map 0:a:0 -b:a 48k -c:a libvorbis output.webm
I want to have control over output file size and limit it to 3MB without clipping the video, but instead, lose quality. so I cant use -fs 3MB.
How can I determine the file size based on video and audio bitrates and duration?
How can I limit the file size without clipping?

Example for 10 second input with an output just under 3 MB output:
3 MB * 8000 / 10 seconds - 48kb audio bitrate - 1% muxing overhead = -b:v 2328k
Encode with two passes when targeting specific output file size:
ffmpeg -y -i input.mp4 -map 0:v:0 -filter:v "scale=640:360,fps=20" -c:v libvpx -b:v 2328k -pass 1 output.webm
ffmpeg -y -i input.mp4 -map 0:v:0 -filter:v "scale=640:360,fps=20" -c:v libvpx -b:v 2328k -map 0:a:0 -c:a libvorbis -b:a 48k -pass 2 output.webm
See:
Get duration with ffprobe
FFmpeg Wiki: VP8

Related

how to convert an 720p file to 360p using ffmpeg with the help of gpu

i want to convert a 720 p video into 360 p video with the help of GPU. i am using this command: "ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -resize 480x360 -i input -c:a copy -c:v h264_nvenc -b:v 249K output"
,but the output file is larger than input file.
i need to reduce the size of input file.
I managed to compress 720 P video with size 110MB to be 15 MB with below command:
ffmpeg -i input.mp4 -vf scale=-1:360 -c:v libx264 -crf 18 -preset veryslow -c:a copy output.mp4

FFMPEG: Combine "Create video from images" + scale to x + add audio + overlay logo

I´m working on a webcam-project. It is for generating timelapse videos of sunset/sundown.
I´m using a raspberrypi to generate them with gphoto2 + DSLR.
At the end of the day the images should get to an video, with audio and an overlay logo.
And it should be scaled to 1920 pixel.
I got a nice solution an it worked.
Producing the timelapse video an scale it:
ffmpeg -y -framerate 25 -start_number 0000001 -i /var/www/html/webcam/2020-01-05_bilder/%7d.jpg -vf scale=1920:-1 -pix_fmt yuv420p /var/www/html/webcam/2020-01-05-tag-output-1920.mp4
Taking the output of (1) and add an overlay-logo, add audio
ffmpeg -y -i '/var/www/html/webcam/2020-01-05-tag-output-1920.mp4'
-i '/var/www/html/webcam-scripts/graphics/logo.png'
-i '/var/www/html/webcam-scripts/sounds/chill_time_5.mp3'
-shortest -filter_complex '[1][0]scale2ref=h=ow/mdar:w=iw/6[#A logo][liebfrauen]; [#A logo]format=argb,colorchannelmixer=aa=0.95[#B logo transparent]; [liebfrauen][#B logo transparent] overlay=(main_w-w)-(main_w*0.05):(main_h-h)-(main_h*0.01)'
-c:v libx264 -crf 18 -preset slow -pix_fmt yuv420p -c:a aac -strict -2
'/var/www/html/webcam/2020-01-05-tag-1920.mp4
I tried to combine both actions, but I get an error:
ffmpeg -y -framerate 25 -start_number 0000001 -i '/var/www/html/webcam/2020-01-05_bilder/%7d.jpg' -vf scale=1920:-1 -pix_fmt yuv420p -i '/var/www/html/webcam-scripts/graphics/logo.png' -i '/var/www/html/webcam-scripts/sounds/chill_time_5.mp3' -shortest -filter_complex '[1][0]scale2ref=h=ow/mdar:w=iw/6[#A logo][liebfrauen]; [#A logo]format=argb,colorchannelmixer=aa=0.95[#B logo transparent]; [liebfrauen][#B logo transparent] overlay=(main_w-w)-(main_w*0.05):(main_h-h)-(main_h*0.01)' -c:v libx264 -crf 18 -preset slow -pix_fmt yuv420p -c:a aac -strict -2 '/var/www/html/webcam/2020-01-05-tag-1920.mp4'
Error: Filtergraph 'scale=720:-1' was specified through the -vf/-af/-filter option for output stream 0:0, which is fed from a complex filtergraph.
-vf/-af/-filter and -filter_complex cannot be used together for the same stream.
Isn`t it possible to combine these inputs and scale it? Or ... Where is my misunderstanding?
Don't mix -vf and -filter_complex. Do all filtering in one filtergraph.
ffmpeg -y -framerate 25 -i '/var/www/html/webcam/2020-01-05_bilder/%7d.jpg' -i '/var/www/html/webcam-scripts/graphics/logo.png' -i '/var/www/html/webcam-scripts/sounds/chill_time_5.mp3' -filter_complex '[0]scale=1920:-2[v0];[1][v0]scale2ref=h=ow/mdar:w=iw/6[#A logo][liebfrauen]; [#A logo]format=argb,colorchannelmixer=aa=0.95[#B logo transparent]; [liebfrauen][#B logo transparent] overlay=(main_w-w)-(main_w*0.05):(main_h-h)-(main_h*0.01),format=yuv420p' -c:v libx264 -crf 18 -preset slow -c:a aac -shortest '/var/www/html/webcam/2020-01-05-tag-1920.mp4'
No need for -strict -2. It does nothing for modern ffmpeg.
I replaced -pix_fmt yuv420p with format=yuv420p so it is more organized.
-start_number 0000001 is not needed because 1 is the default.

ffmpeg - Convert MP4 to WebM, poor results

I am trying to encode a video to webm for playing through a HTML5 video tag. I have these settings...
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:a 128k -b:v 1M -c:a libopus output.webm
The results aren't great, video has lost lot's of it's sharpness. Looking at the original file I can see the bitrate is 1694kb/s.
Are there any settings I can add or change to improve the output? Would maybe a 2 pass encode improve things?
Try with
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -b:a 128k -c:a libopus output.webm
Adjust the CRF value till the quality/size tradeoff is ok. Lower values produce bigger but better files.
Try to run two passes:
ffmpeg -i file.mp4 -b:v 0 -crf 30 -pass 1 -an -f webm -y /dev/null
ffmpeg -i file.mp4 -b:v 0 -crf 30 -pass 2 output.webm
From - https://trac.ffmpeg.org/wiki/Encode/VP9

FFmpeg concat and then add soundtrack results in a soundtrack that stutters

I am trying to create a video composed of clips of images and videos. For the clips of images, I use ffmpeg to create a video file and then I add a silent audio stream through these two steps:
ffmpeg.exe -loop 1 -i MyImage.png -codec:v libx264 -t 4.0 -profile:v high -preset slow -r 25 -b:v 500k -maxrate 500k -pix_fmt yuv420p -vf scale=1280:720 MyImageMovie.mp4
ffmpeg.exe -f lavfi -i anullsrc=r=48000 -i MyImageMovie.mp4 -shortest -c:v copy -c:a aac -strict experimental -y MyImageMovieWithSilentAudioStream.mp4
Then I combine my video clips and image clips with
ffmpeg.exe -f concat -i videoList.txt -c copy -y concatVideo.mp4
At this point, the video looks good, any video clips that have audio streams seemed well synced to the video.
Now I add a soundtrack:
ffmpeg.exe -i concatVideo.mp4 -i soundtrack.mp3 -ar 48000 -filter_complex "[1:a]apad [b] ; [0:a][b]amerge=inputs=2[a]" -map 0:v -map "[a]" -c:v copy -ac 2 -shortest -y FinalVideo.mp4
The problem is that the soundtrack on FinalVideo.mp4 stutters at some (not all) of the concatenation joints.
I suspect it has to do with the audio stream and the video stream of the Image clips not being perfectly aligned. The aac has .0231s resolution and the video has 0.04s resolution. When I ffprobe the MyImageMovieWithSilentAudioStream.mp4 the duration is 4.00s but the start is 0.0213.
If my concatenated video has several of these image clips, the error can start to accumulate.
What can I do to keep the video and audio in sync and add a soundtrack that doesn't stutter?
Also, this is a little interesting, I don't hear the stutter when the final video is played on Windows Media Player, but it is there if I play it on VLC or via the html native video element.
Try adding the soundtrack in the same step as the concat.
ffmpeg -f concat -i videoList.txt -i soundtrack.mp3 \
-filter_complex "[1:a]apad[b];[0:a][b]amerge=inputs=2[a]" \
-map 0:v -map "[a]"
-c:v copy -c:a aac -ac 2 -ar 48000 -shortest -y FinalVideo.mp4
As an aside, you can also combine the image and silent stream generation,
ffmpeg -loop 1 -i MyImage.png -f lavfi -i anullsrc=r=48000 \
-vf scale=1280:720 \
-c:v libx264 -profile:v high -preset slow -r 25 -b:v 500k -maxrate 500k -pix_fmt yuv420p \
-c:a aac -strict experimental -t 4 -y MyImageMovieWithSilentAudioStream.mp4

FFmpeg First 2 Seconds of Video Not Showing

This code works fine for some audio files (makes a slideshow of JPG pictures with a PNG watermark and MP3 audio, while maintaining aspect ratio) but for this audio file, the pictures are not showing for the first two seconds or so of the video:
ffmpeg -y -framerate 1/12 -i "media/%03d.jpg" -i "media/audio.mp3" -loop 1 -i "media/watermark.png" -filter_complex "[0:v]scale=iw*min(3840/iw\,2160/ih):ih*min(3840/iw\,2160/ih), pad=3840:2160:(3840-iw)/2:(2160-ih)/2[ss]; [ss][2:v] overlay=main_w-overlay_w-10:main_h-overlay_h-10:shortest=1[out]" -map "[out]" -map 1:a -c:v libx264 -r 24 -preset veryfast -tune stillimage -pix_fmt yuv420p -c:a copy -map_metadata -1 "media/video.mkv" -report
I tried converting the audio into different formats of MP3, tried changing bitrates, changed audio to stereo, and even tried converting it to a WAV. None of these things worked.
Here are the report results for when I run this command.
If it makes a difference, I'm using Ubuntu 14.04 and FFmpeg version N-77455-g4707497 (latest version).
This command should work, but I consider this bizarre behaviour as FFmpeg should be automatically padding frames as per output spec
ffmpeg -y -framerate 1/12 -i "media/%03d.jpg" -i "media/audio.mp3" -loop 1 -i "media/watermark.png" -filter_complex "[0:v]scale=iw*min(3840/iw\,2160/ih):ih*min(3840/iw\,2160/ih), pad=3840:2160:(3840-iw)/2:(2160-ih)/2,fps=24[ss]; [ss][2:v] overlay=main_w-overlay_w-10:main_h-overlay_h-10:shortest=1[out]" -map "[out]" -map 1:a -c:v libx264 -r 24 -preset veryfast -tune stillimage -pix_fmt yuv420p -c:a copy -map_metadata -1 "media/video.mkv"

Resources