FFmpeg transparent PNG black outline issue - ffmpeg

I'm encoding a video with a transparent PNG using ffmpeg. I noticed there's a slight black outline surrounding the image. Is there any way to remove it?
Output image:
Transparent PNG sample:
My ffmpeg command
ffmpeg -hide_banner -y -ss 0.0 -t 8.5 -i C:\Users\Admin\Desktop\test_movies\6.mp4 -i C:\Users\Admin\Desktop\test_movies\text_and_emoji.png -filter_complex [0:v]setpts=PTS-STARTPTS,scale=640:640:force_original_aspect_ratio=decrease,pad=640:640:(ow-iw)/2:(oh-ih)/2:color=#18ffff[0v];[1:v]scale=556.24744:141.41884[1v];[0v][1v]overlay=(W-w)/2-(W/2-325.33328):(H-h)/2-(H/2-567.7075):enable='between(t,0.0,8.5)' -ac 2 -ar 44100 -vcodec libx264 -g 75 -r 20 -preset ultrafast -strict experimental C:\Users\Admin\Desktop\test_movies\test.mp4
Last edit 1:
I tried using without [1:v]scale=556.24744:141.41884[1v], the output still have the slight outline
Sample output:
Sample code:
ffmpeg -hide_banner -y -ss 0.0 -t 8.5 -i C:\Users\Admin\Desktop\test_movies\white.mp4 -i C:\Users\Admin\Desktop\test_movies\text_and_emoji.png -filter_complex [0:v]scale=640:640:force_original_aspect_ratio=decrease,pad=640:640:(ow-iw)/2:(oh-ih)/2:color=#18ffff[0v];[0v][1:v]overlay=(W-w)/2-(W/2-325.33328):(H-h)/2-(H/2-567.7075):enable='between(t,0.0,8.5)' -ac 2 -ar 44100 -vcodec libx264 -preset ultrafast -strict experimental C:\Users\Admin\Desktop\test_movies\test.mp4
Last edit 2:
I tried another one with added alpha=premultiplied with latest ffmpeg version. It somehow removed the outline, but the quality of the picture reduced alot till it seems like it's pixelated. Plus. there's another unknown white layer at the back of the image.
Output video
Sample code:
C:\Users\Admin\Downloads\ffmpeg-20180102-57d0c24-win64-static\bin\ffmpeg -y -ss 0.0 -t 8.5 -i C:\Users\Admin\Desktop\test_movies\white.mp4 -i C:\Users\Admin\Desktop\test_movies\text_and_emoji.png -filter_complex [0:v]scale=640:640:force_original_aspect_ratio=decrease,pad=640:640:(ow-iw)/2:(oh-ih)/2:color=#00ffff[0v];[1:v]scale=480:120[1v];[0v][1v]overlay=(W-w)/2-(W/2-325.33328):(H-h)/2-(H/2-567.7075):alpha=premultiplied:enable='between(t,0.0,8.5)' -ac 2 -ar 44100 -vcodec libx264 C:\Users\Admin\Desktop\test_movies\test.mp4
Latest edit 3:
As suggested by #Mulvya, I combined his code with alpha=premultiplied and it seems alot better now, with very slight black outline (almost not visible)
Output video:
Sample code:
C:\Users\Admin\Downloads\ffmpeg-20180102-57d0c24-win64-static\bin\ffmpeg -y -ss 0.0 -t 8.5 -i C:\Users\Admin\Desktop\test_movies\white.mp4 -i C:\Users\Admin\Desktop\test_movies\text_and_emoji.png -filter_complex [0:v]setpts=PTS-STARTPTS,scale=640:640:force_original_aspect_ratio=decrease,pad=640:640:(ow-iw)/2:(oh-ih)/2:color=#18ffff[0v];[1:v]premultiply=inplace=1,scale=480:120[1v];[0v][1v]overlay=(W-w)/2-(W/2-325.33328):(H-h)/2-(H/2-567.7075):alpha=premultiplied:enable='between(t,0.0,8.5)':format=rgb,format=yuv420p -ac 2 -ar 44100 -vcodec libx264 C:\Users\Admin\Desktop\test_movies\test.mp4

This is due to a bug in the overlay filter, since fixed. Alter your filtergraph to to this,
"[0:v]setpts=PTS-STARTPTS,scale=640:640:force_original_aspect_ratio=decrease,pad=640:640:(ow-iw)/2:(oh-ih)/2:color=#18ffff[0v];[1:v]premultiply=inplace=1,scale=556.24744:141.41884[1v];[0v][1v]overlay=(W-w)/2-(W/2-325.33328):(H-h)/2-(H/2-567.7075):enable='between(t,0.0,8.5)':format=rgb,format=yuv420p"
You'll need a FFmpeg version from after Dec 16 2017 for this.

Related

FFmpeg adding click to beginning of audio

I've got an odd issue that's been bugging me for a while. I'm converting another format to video using FFmpeg; the conversion takes place prior and is fed into FFmpeg to be finally converted to an mp4.
Oddly, I seem to be getting a little click at the start of the resulting video; it's not present in the original audio but shows up in the final video.
Here is the sample audio. You'll notice that it has no pop at the start.
Here is the raw video input.
Here is the video my command is generating.
Here is the command I'm using to reproduce the issue (the actual conversion takes place in a Python script feeding FFmpeg the video via stdin and the audio via a temp file)
cat debug_raw_video.bin| ffmpeg -hide_banner -loglevel info -y -s 256x192 -r 30 -f rawvideo -thread_queue_size 600 -pix_fmt rgb8 -i pipe:0 -f s16le -ar 11025 -ac 1 -guess_layout_max 0 -i ./debug_audio.wav -vcodec libx264 -pix_fmt yuv420p -movflags faststart -acodec aac -strict experimental -vf scale=512:384:flags=neighbor -threads 0 -preset medium -tune animation ./out.mp4
FFmpeg version:
ffmpeg version 2.8.15 Copyright (c) 2000-2018 the FFmpeg developers
Also have the same issue with this version:
ffmpeg version 3.3.4-static http://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2017 the FFmpeg developers
Why am I getting a little click/pop at the beginning? I've been trying to figure this out for quite a while.
It appears you're specifying that the input audio is raw, but it's not:
$ file debug_audio.wav
debug_audio.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, mono 11025 Hz
So I imagine the click you're hearing is the wav header being processed as audio. If I remove the related options, -f s16le and -ar 11025, ffmpeg correctly determines that the audio input is in wav format and produces a click-less output:
cat debug_raw_video.bin | ffmpeg -hide_banner -loglevel info -y -s 256x192 -r 30 -f rawvideo -thread_queue_size 600 -pix_fmt rgb8 -i pipe:0 -ac 1 -i ./debug_audio.wav -vcodec libx264 -pix_fmt yuv420p -movflags faststart -acodec aac -strict experimental -vf scale=512:384:flags=neighbor -threads 0 -preset medium -tune animation ./out.mp4

FFMPEG avoid_negative_ts makes video start not from keyframe

Let's say I want to cut part of the mp4 video and resize it from 1280x720 to 854x480.
My command looks like this:
ffmpeg -ss 45 -i source.mp4 -ss 10 -to 20 \
-acodec aac -ar 44100 -ac 2 -c:v libx264 \
-crf 26 -vf scale=854:480:force_original_aspect_ratio=decrease,pad=854:480:0:0,setsar=1/1,setdar=16/9 \
-video_track_timescale 29971 -pix_fmt yuv420p \
-map_metadata 0 -avoid_negative_ts 1 -y dest.mp4
The problem is, when I don't use option avoid_negative_ts, resulting video has some issues with time bases etc, therefore it cannot be later converted by other libs, for example Swift's AVFoundation.
But when I use this option - video does not start with keyframe.
By using ffprobe I see start_time=0.065997 or other times other than 0.
How can I use option avoid_negative_ts and have a video that starts with keyframe?

How to overlay a png to piped video source with audio mixed in via ffmpeg?

I'm successfully streaming silent video with music added from my Raspberry Pi (Raspbian) to YouTube via ffmpeg, with the help of this GitHub gist and this post:
raspivid -o - -t 0 -vf -hf -w 1280 -h 720 -fps 25 -b 4000000 | \
ffmpeg -i music.wav \
-f h264 -i - -vcodec copy -acodec aac -ab 128k -g 50 -strict experimental \
-f flv rtmp://a.rtmp.youtube.com/live2/STREAMKEY
The last step of my project to add a transparent, full width/height png overlay to the video (1280x720 size in my case). I've seen a few related answers such as this one and this one.
With the added complexity of piping in a camera feed, mixing in an audio source and outputting to a video stream, I haven't succeeded in adding the image overlay. Where/how would I add a transparent image overlay in the example above?
The ffmpeg part will be
ffmpeg -i music.wav \
-f h264 -i - -i overlay.png
-filter_complex "[1][2]overlay"
-vcodec libx264 -preset ultrafast -tune zerolatency -acodec aac -ab 128k -g 50 -strict experimental \
-f flv rtmp://a.rtmp.youtube.com/live2/STREAMKEY
Since you're altering the video contents, copy can't be used, and the video has to be re-encoded.

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"

animation between images using FFmpeg

Hi I am new in FFmpeg,
I have made video from slideshow of sequential images (img001.jpg, img002.jpg, img003.jpg....). Using following commands in Ubuntu 14.04
ffmpeg -framerate 1/5 -i img%03d.jpg -c:v libx264 -r 30 -pix_fmt yuv420p -vf scale=320:240 out.mp4
But now I want to put animation like fade-in, fade-out between each sequential images, I want to generate video,
can anybody help me how to make it, i have searched lots of things but could not get....
The best way to do this is create intermediate mpeg's for each image and then concatenate them all into a video. For example, say you have 5 images; you would run this for each one of the images to create the intermediate mpeg's with a fade in at the beginning and a fade out at the end.
ffmpeg -y -loop 1 -i image -vf "fade=t=in:st=0:d=0.5,fade=t=out:st=4.5:d=0.5" -c:v mpeg2video -t 5 -q:v 1 image-1.mpeg
where t is the duration, or time, of each image. Once you have all of these mpeg's, you use ffmpeg's concat command to combine them all into an mp4.
ffmpeg -y -i image-1.mpeg -i image-2.mpeg -i image-3.mpeg -i image-4.mpeg -i image-5.mpeg -filter_complex '[0:v][1:v][2:v][3:v][4:v] concat=n=5:v=1 [v]' -map '[v]' -c:v libx264 -s 1280x720 -aspect 16:9 -q:v 1 -pix_fmt yuv420p output.mp4
This gives you the desired video and is the simplest and highest quality solution with ffmpeg. Let me know if you have any questions about how the above command works.

Resources