How can i add a watermark on videos? [duplicate] - php

I am currently using these commands:
Top left corner
ffmpeg –i inputvideo.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=10:10 [out]" outputvideo.flv
Top right corner
ffmpeg –i inputvideo.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=main_w-overlay_w-10:10 [out]" outputvideo.flv
Bottom left corner
ffmpeg –i inputvideo.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=10:main_h-overlay_h-10 [out]" outputvideo.flv
Bottom right corner
ffmpeg –i inputvideo.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=(main_w-overlay_w-10)/2:(main_h-overlay_h-10)/2 [out]" outputvideo.flv
How to place watermark center of the video ?

Examples to add a watermark / logo image on video using the overlay filter.
Centered
ffmpeg -i input.mp4 -i logo.png -filter_complex "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2" -codec:a copy output.mp4
or with the shortened overlay options:
overlay=(W-w)/2:(H-h)/2
Top left
This is the easy one because the default, if you provide no options to overlay, is to place the image in the top left.
This example adds 5 pixels of padding so the image is not touching the edges:
overlay=5:5
Top right
With 5 pixels of padding:
overlay=main_w-overlay_w-5:5
or with the shortened options:
overlay=W-w-5:5
Bottom right
With 5 pixels of padding:
overlay=main_w-overlay_w-5:main_h-overlay_h-5
or with the shortened options:
overlay=W-w-5:H-h-5
Bottom left
With 5 pixels of padding:
overlay=5:main_h-overlay_h
or with the shortened options:
overlay=5:H-h-5
Transparency / opacity / alpha
Example to make watermark 50% transparent using the format and colorchannelmixer filters:
ffmpeg -i input.mp4 -i watermark.jpg -filter_complex "[1]format=rgba,colorchannelmixer=aa=0.5[logo];[0][logo]overlay=(W-w)/2:(H-h)/2:format=auto,format=yuv420p" -c:a copy output.mp4
Improved quality
Using the format=auto option in the overlay filter can make PNG watermarks look better:
ffmpeg -i input.mp4 -i watermark.png -filter_complex "overlay=5:H-h-5:format=auto,format=yuv420p" -c:a copy output.mp4
Note the addition of the format filter (yes, same name as the option, but a standalone filter) to reset it to YUV 4:2:0 which is needed for MP4 output. Remove ,format=yuv420p if you are not outputting MP4.
Scale watermark in relation to main video
Use the scale2ref filter:
Example to make logo 10% (1/10) the size of the main video:
ffmpeg -i input.mp4 -i watermark.png -filter_complex "[1][0]scale2ref=w=oh*mdar:h=ih*0.1[logo][video];[video][logo]overlay=5:H-h-5" -c:a copy output.mp4

Related

how to add watermark in multiple areas using ffmpeg?

i am using laravel framework and also using ffmpeg php library. Actually i have done almost 70% of work. But the problem i faced is to show watermark at multiple areas on video. I have done the watermark on top-left corner that is running very fine on that video. But i want to add watermark in top-left, bottom-left, bottom-right. I have used this code for top-left watermark (for video):-
$inputVideo = public_path('input/airplane_flight_airport_panorama_1080.mp4');
$outputVideo = public_path('uploads/output.mp4');
$watermark = public_path('input/watermark.jpg');
$wmarkvideo = "ffmpeg -i ".$inputVideo." -i ".$watermark." -filter_complex ". '"overlay=x=(main_w-overlay_w):y=(main_h-overlay_h)/(main_h-overlay_h)"'." ".$outputVideo;
exec($wmarkvideo );
Please help me how can i add watermark on top-left, bottom-left, bottom-right in these areas. Thanks in advance :)
This is the ffmpeg command you would use for multiple watermarks
ffmpeg -i inputVideo -i watermark-tr -i watermark-tl -i watermark-br -i watermark-bl
-filter_complex "[0][1]overlay=x=W-w:y=0[tr];
[tr][2]overlay=x=0:y=0[tl];
[tl][3]overlay=x=W-w:y=H-h[br];
[br][4]overlay=x=0:y=H-h" outputfile
tr = top-right; tl = top-left; br = bottom-right; bl = bottomleft
With center as well,
ffmpeg -i inputVideo -i watermark-tr -i watermark-tl -i watermark-br -i watermark-bl -i watermark-c
-filter_complex "[0][1]overlay=x=W-w:y=0[tr];
[tr][2]overlay=x=0:y=0[tl];
[tl][3]overlay=x=W-w:y=H-h[br];
[br][4]overlay=x=0:y=H-h[bl];
[bl][5]overlay=x=(W-w)/2:y=(H-h)/2" outputfile

get image from video without specifying height

I am using following code for extracting image from Video.
shell_exec('echo "Y" | ffmpeg -itsoffset -4 -i "'.base_path().'/assets/videos/'.$file_name.'.mp4" -vcodec mjpeg -vframes 1 -an -f rawvideo -s 1170x300 "'.base_path().'/assets/videos/thumbnail/'.$file_name.'.jpg"');
Here I have given static height and because of that image is stretching So I don't want to specify height so is there any way it adjust height automatically by maintaining quality of image.
I have tried following code as well but did not work
shell_exec('echo "Y" | ffmpeg -itsoffset -4 -i "'.base_path().'/assets/videos/'.$file_name.'.mp4" -vcodec mjpeg -vframes 1 -an -f rawvideo -s 1170x-1 "'.base_path().'/assets/videos/thumbnail/'.$file_name.'.jpg"');
Can anyone tell me solution for this?
First up, if echo "Y" | is intended to overwrite an existing thumbnail without prompting, there is a -y flag to ffmpeg which does this.
Now, assuming you want the image to be no larger than 1,170 pixels in either dimension, you can replace your -s parameter with a call to the scale video filter and appropriate arguments.
shell_exec(
'ffmpeg -y -itsoffset -4 -i "'.base_path().'/assets/videos/'.$file_name.'.mp4"'
. ' -vcodec mjpeg -vframes 1 -an -f rawvideo'
. ' -filter:v "scale=iw*min(min(1170/iw\,1170/ih)\,1):ih*min(min(1170/iw\,1170/ih)\,1)"'
. ' "'.base_path().'/assets/videos/thumbnail/'.$file_name.'.jpg"');
This doesn't scale up videos that are smaller than 1,170 pixels in both directions. If you'd prefer to scale up these thumbnails, replace scale=iw*min(min(1170/iw\,1170/ih)\,1):ih*min(min(1170/iw\,1170/ih)\,1) with scale=iw*min(1170/iw\,1170/ih):ih*min(1170/iw\,1170/ih).
If the image should always have a width of 1,170 pixels even if this makes it taller than 1,170 pixels high, instead use scale=1170:ih*1170/iw.
And finally, to reduce the width to 1,170 pixels only if it's wider, scale=min(iw\,1170):min(ih\,ih*1170/iw)

ffmpeg video thumbnail size

I'm generating thumbnails like so:
exec(ffmpeg -itsoffset -4 -i '.$path.' -vcodec mjpeg -vframes 1 -an -f rawvideo -s 300x300 '.$other_path);
Is it possible to not specify the exact size of output image and set it to 100%?
You can simply remove the -s 300x300 option, and it will note resize.

To water mark videos at bottom right corner using ffmpeg

I found some answer here in stack which is indeed using ffmpeg but it is giving me some error.
I ran it in command window and the error is quite like
"Unable to find a suitable output format for 'ΓÇôi'
ΓÇôi: Invalid argument".
my command is as follows
ffmpeg –i inputvideo.avi -vf "movie=watermarklogo.png [watermark]; [in][watermark] overlay=(main_w-overlay_w-10)/2:(main_h-overlay_h-10)/2 [out]" outputvideo.mp4
please suggest some ideas.
Basically overlay property defines where your watermark image will be posted -
main_w: video width
main_h: video height
overlay_w: overlay width
overlay_h: overlay height.
I guess this should work fine
$mark = "ffmpeg -i ".$inputvideo." -i logo.png -filter_complex ". '"overlay=x=(main_w-overlay_w):y=(main_h-overlay_h)/(main_h-overlay_h)"'." ".uniqid()."topright.mp4";
You can try these out. Should work out for you.
/*
* At top left watermark
*/
$mark = "ffmpeg -i ".$inputvideo." -i logo.png -filter_complex ". '"overlay=x=(main_w-overlay_w)/(main_w-overlay_w):y=(main_h-overlay_h)/(main_h-overlay_h)"'." ".uniqid()."topleft.mp4";
/*
* At top right watermark
*/
$mark = "ffmpeg -i ".$inputvideo." -i logo.png -filter_complex ". '"overlay=x=(main_w-overlay_w):y=(main_h-overlay_h)/(main_h-overlay_h)"'." ".uniqid()."topright.mp4";
I tried with this command, and it worked for me. hope it will work for you as well.
$mark = "ffmpeg -i inputvideo.mp4 -i watermark.png -filter_complex 'overlay=x=(main_w-overlay_w):y=(main_h-overlay_h)' outputvideo.mp4";
exec($mark);

Generating a waveform using ffmpeg

I am trying to generate a waveform image using ffmpeg.
I have successfully made a waveform image, however it doesn't look very nice...
I have been looking around to try and style the image to make it look nicer, however I have been unable to find any information on this or any tutorials on this.
I am using PHP and shell_exec to create the waveform.
I am aware that there are php library that can do this but due to file format this is a lengthy process.
The code I am using is as follows:
$command = 'convertvid\bin\ffmpeg -i Temp\\'.$file.' -y -lavfi showwavespic=split_channels=0:s='.$width.'x50 Temp\\'.$PNGFileName;
shell_exec($command);
Basically I would like to add a line through the middle as there are blank spots at the moment and would like to be able to set the background and wave colour.
Default waveform
ffmpeg -i input.wav -filter_complex showwavespic -frames:v 1 output.png
Notes
Notice the segment of silent audio in the middle (see "Fancy waveform" below if you want to see how to add a line).
The background is transparent.
Default colors are red (left channel) and green (right channel) for a stereo input. The color is mixed where the channels overlap.
You can change the channel colors with the colors option, such as "showwavespic=colors=blue|yellow". See a list of valid color names or use hexadecimal notation, such as #ffcc99.
See the showwavespic filter documentation for additional options.
If you want a video instead of an image use the showwaves filter.
Fancy waveform
ffmpeg -i input.mp4 -filter_complex \
"[0:a]aformat=channel_layouts=mono, \
compand=gain=-6, \
showwavespic=s=600x120:colors=#9cf42f[fg]; \
color=s=600x120:color=#44582c, \
drawgrid=width=iw/10:height=ih/5:color=#9cf42f#0.1[bg]; \
[bg][fg]overlay=format=auto,drawbox=x=(iw-w)/2:y=(ih-h)/2:w=iw:h=1:color=#9cf42f" \
-frames:v 1 output.png
Explanation of options
aformat downsamples the audio to mono. Otherwise, by default, a stereo input would result in a waveform with a different color for each channel (see Default waveform example above).
compand modifies the dynamic range of the audio to make the waveform look less flat. It makes a less accurate representation of the actual audio, but can be more visually appealing for some inputs.
showwavespic makes the actual waveform.
color source filter is used to make a colored background that is the same size as the waveform.
drawgrid adds a grid over the background. The grid does not represent anything, but is just for looks. The grid color is the same as the waveform color (#9cf42f), but opacity is set to 10% (#0.1).
overlay will place [bg] (what I named the filtergraph for the background) behind [fg] (the waveform).
Finally, drawbox will make the horizontal line so any silent areas are not blank.
Gradient example
Using gradients filter:
ffmpeg -i input.mp3 -filter_complex "gradients=s=1920x1080:c0=000000:c1=434343:x0=0:x1=0:y0=0:y1=1080,drawbox=x=(iw-w)/2:y=(ih-h)/2:w=iw:h=1:color=#0000ff[bg];[0:a]aformat=channel_layouts=mono,showwavespic=s=1920x1080:colors=#0068ff[fg];[bg][fg]overlay=format=auto" -vframes:v 1 output.png
Color background
ffmpeg -i input.opus -filter_complex "color=c=blue[color];aformat=channel_layouts=mono,showwavespic=s=1280x720:colors=white[wave];[color][wave]scale2ref[bg][fg];[bg][fg]overlay=format=auto" -frames:v 1 output.png
The scale2ref filter automatically makes the background the same size as the waveform.
Image background
Of course you can use an image or video instead for the background:
ffmpeg -i audio.flac -i background.jpg -filter_complex \
"[1:v]scale=600:-1,crop=iw:120[bg]; \
[0:a]showwavespic=s=600x120:colors=cyan|aqua[fg]; \
[bg][fg]overlay=format=auto" \
-q:v 3 showwavespic_bg.jpg
Getting waveform stats and data
Use the astats filter. Many stats are available: RMS, peak, min, max, difference, etc.
RMS level per audio frame
Example to get standard RMS level measured in dBFS per audio frame:
ffprobe -v error -f lavfi -i "amovie=input.wav,astats=metadata=1:reset=1" -show_entries frame_tags=lavfi.astats.Overall.RMS_level -of csv=p=0 > rms.log
Peak level per second
Add the asetnsamples filter.
ffprobe -v error -f lavfi -i "amovie=input.wav,asetnsamples=44100,astats=metadata=1:reset=1" -show_entries frame_tags=lavfi.astats.Overall.Peak_level -of csv=p=0
Same as above but with timestamps
ffprobe -v error -f lavfi -i "amovie=input.wav,asetnsamples=44100,astats=metadata=1:reset=1" -show_entries frame=pkt_pts_time:frame_tags=lavfi.astats.Overall.Peak_level -of csv=p=0
Output to file
Just append > output.log to the end of your command:
ffprobe -v error -f lavfi -i "amovie=input.wav,asetnsamples=44100,astats=metadata=1:reset=1" -show_entries frame_tags=lavfi.astats.Overall.RMS_level -of csv=p=0 > output.log
JSON
ffprobe -v error -f lavfi -i "amovie=input.wav,asetnsamples=44100,astats=metadata=1:reset=1" -show_entries frame_tags=lavfi.astats.Overall.RMS_level -of json > output.json

Categories