Question: What are the different filters available?
- alphaextract: Extract the alpha component from the input as a grayscale video.
- alphamerge: Add or replace the alpha component of the primary input with the grayscale value of a second input
movie=in_alpha.mkv [alpha]; [in][alpha] alphamerge [out]
- amplify: Amplify differences between current pixel and pixels of adjacent frames in same pixel location.
- atadenoise: Adaptive Temporal Averaging Denoiser to the video input.
- avgblur: Apply average blur filter.
- bbox: Compute the bounding box for the non-black pixels in the input frame luminance plane.
- bitplanenoise: Show and measure bit plane noise.
- blackdetect: Detect video intervals that are (almost) completely black.
blackdetect=d=2:pix_th=0.00
Question: Give few examples?
Apply transition from bottom layer to top layer in first 10 seconds
blend=all_expr='A*(if(gte(T,10),1,T/10))+B*(1-(if(gte(T,10),1,T/10)))'
Apply uncover left effect:
blend=all_expr='if(gte(N*SW+X,W),A,B)'
Apply uncover down effect:
blend=all_expr='if(gte(Y-N*SH,0),A,B)'
Display differences between the current and the previous frame:
tblend=all_mode=grainextract
Question: How to add video filter (transition) on videos with PHP-FFMPEG?
- You must have installed PHP-FFMPEG
php composer.phar require php-ffmpeg/php-ffmpeg
If not, you can check https://www.web-technology-experts-notes.in/2017/10/how-to-install-ffmpeg-in-wamp-server-in-windows7.html
Open File Path: \vendor\php-ffmpeg\php-ffmpeg\src\FFMpeg\Media\Concat.php
Add following function in Concat.php
public function saveFromDifferentCodecsTransition(FormatInterface $format, $outputPathfile,$transition=array())
{
/**
* @see https://ffmpeg.org/ffmpeg-formats.html#concat
* @see https://trac.ffmpeg.org/wiki/Concatenate
*/
// Check the validity of the parameter
if(!is_array($this->sources) || (count($this->sources) == 0)) {
throw new InvalidArgumentException('The list of videos is not a valid array.');
}
// Create the commands variable
$commands = array();
// Prepare the parameters
$nbSources = 0;
$files = array();
// For each source, check if this is a legit file
// and prepare the parameters
foreach ($this->sources as $videoPath) {
$files[] = '-i';
$files[] = $videoPath;
$nbSources++;
}
$commands = array_merge($commands, $files);
// Set the parameters of the request
$commands[] = '-filter_complex';
$complex_filter = '';
//$transition =array('transition_effect'=>'fade_out','transition_length'=>1.2);
//No transistion
if(empty($transition) || @$transition['transition_effect']=='none' || $nbSources==1){
for($i=0; $i<$nbSources; $i++) {
$complex_filter .= '['.$i.':v:0] ['.$i.':a:0] ';
}
}else{ //Transition with Fade in/Fade out
if($transition['transition_effect']=='fade_in'){
for($i=0; $i<$nbSources; $i++) {
if($i == 0){
$complex_filter .='['.$i.':v]setpts=PTS-STARTPTS[v'.$i.'];';
}else{
$complex_filter .='['.$i.':v]fade=type=in:duration='.$transition['transition_length'].',setpts=PTS-STARTPTS[v'.$i.'];';
}
}
}else if($transition['transition_effect']=='fade_out'){
for($i=0; $i<$nbSources; $i++) {
if($i == ($nbSources-1)){
$complex_filter .='['.$i.':v]setpts=PTS-STARTPTS[v'.$i.'];';
}else{
$startTime=0;
/* Get duration of video*/
try{
$sourceFile = $this->sources[$i];
$ffprobe = \FFMpeg\FFProbe::create();
$duration=
$ffprobe->streams($sourceFile)
->videos()
->first()
->get('duration');
$startTime=$duration-$transition['transition_length'];
}catch(Exception $e){
$transition['transition_length']=0;
}
/* Get duration of video*/
$complex_filter .='['.$i.':v]fade=type=out:start_time='.$startTime.',setpts=PTS-STARTPTS[v'.$i.'];';
}
}
}
for($i=0; $i<$nbSources; $i++) {
$complex_filter .= '[v'.$i.']['.$i.':a]';
}
}
$complex_filter .= 'concat=n='.$nbSources.':v=1:a=1 [v] [a]';
$commands[] = $complex_filter;
$commands[] = '-map';
$commands[] = '[v]';
$commands[] = '-map';
$commands[] = '[a]';
// Prepare the filters
$filters = clone $this->filters;
$filters->add(new SimpleFilter($format->getExtraParams(), 10));
if ($this->driver->getConfiguration()->has('ffmpeg.threads')) {
$filters->add(new SimpleFilter(array('-threads', $this->driver->getConfiguration()->get('ffmpeg.threads'))));
}
if ($format instanceof VideoInterface) {
if (null !== $format->getVideoCodec()) {
$filters->add(new SimpleFilter(array('-vcodec', $format->getVideoCodec())));
}
}
if ($format instanceof AudioInterface) {
if (null !== $format->getAudioCodec()) {
$filters->add(new SimpleFilter(array('-acodec', $format->getAudioCodec())));
}
}
// Add the filters
foreach ($this->filters as $filter) {
$commands = array_merge($commands, $filter->apply($this));
}
if ($format instanceof AudioInterface) {
if (null !== $format->getAudioKiloBitrate()) {
$commands[] = '-b:a';
$commands[] = $format->getAudioKiloBitrate() . 'k';
}
if (null !== $format->getAudioChannels()) {
$commands[] = '-ac';
$commands[] = $format->getAudioChannels();
}
}
// If the user passed some additional parameters
if ($format instanceof VideoInterface) {
if (null !== $format->getAdditionalParameters()) {
foreach ($format->getAdditionalParameters() as $additionalParameter) {
$commands[] = $additionalParameter;
}
}
}
// Set the output file in the command
$commands[] = $outputPathfile;
$failure = null;
try {
$this->driver->command($commands);
} catch (ExecutionFailureException $e) {
throw new RuntimeException('Encoding failed', $e->getCode(), $e);
}
return $this;
}
Question: How to call above function (used for scale in/scale out) with number of seconds?
require_once 'ffmpeglib/vendor/autoload.php';
$ffmpeg = FFMpeg\FFMpeg::create();
$format = new FFMpeg\Format\Video\X264();
$format->setAudioCodec("aac");
$newFileName='output_video.mp4';
$captionStaticFilePath=$_SERVER['DOCUMENT_ROOT'].'/myvideos/';
$videoFiles=array($captionStaticFilePath.'myvideo.mp4',$captionStaticFilePath.'myvideo1.mp4',$captionStaticFilePath.'myvideo2.mp4');
/////////////// Debug ////////////////////////////
$ffmpeg->getFFMpegDriver()->listen(new \Alchemy\BinaryDriver\Listeners\DebugListener());
$ffmpeg->getFFMpegDriver()->on('debug', function ($message) {
echo $message."
";
});
/////////////// Debug ////////////////////////////
$transition=array(
'transition_effect'=>'fade_in', //fade_in,fade_out, black
'transition_length'=>4 //number of seconds
);
try{
$video = $ffmpeg->open($videoFiles[0])
->concat($videoFiles)
->saveFromDifferentCodecsTransition(new FFMpeg\Format\Video\X264,$captionStaticFilePath.$newFileName,$transition);
}catch(Exception $e){
echo $e->getMessage();
}