Added the ComplexMedia type and the possibility to use -filter_complex and -map features. Added some built-in complex filters. Added the unit and functional tests of the new features. README.md has been updated.

This commit is contained in:
CaliforniaMountainSnake 2020-02-18 13:49:32 +03:00
commit f20ad8a82e
17 changed files with 1583 additions and 7 deletions

View file

@ -520,6 +520,82 @@ $video
More details about concatenation in FFMPEG can be found [here](https://trac.ffmpeg.org/wiki/Concatenate), [here](https://ffmpeg.org/ffmpeg-formats.html#concat-1) and [here](https://ffmpeg.org/ffmpeg.html#Stream-copy).
### ComplexMedia
ComplexMedia may have multiple inputs and multiple outputs.
This class has been developed primarily to use with `-filter_complex`.
So, its `filters()` method accepts only filters that can be used inside `-filter_complex` command.
ComplexMedia already contains some built-in filters.
#### Base usage
For example:
```php
$complexMedia = $ffmpeg->openComplex(array ('video_1.mp4', 'video_2.mp4'));
$complexMedia->filters()
->custom('[0:v][1:v]', 'hstack', '[v]');
$complexMedia
->map(array('0:a', '[v]'), new X264('aac', 'libx264'), 'output.mp4')
->save();
```
This code takes 2 input videos, stacks they horizontally in 1 output video and adds to this new video the audio from the first video.
(It is impossible with simple filtergraph that has only 1 input and only 1 output).
#### Complicated example
A more difficult example of possibilities of the ComplexMedia. Consider all input videos already have the same resolution and duration. ("xstack" filter has been added in the 4.1 version of the ffmpeg).
```php
$inputs = array(
'video_1.mp4',
'video_2.mp4',
'video_3.mp4',
'video_4.mp4',
);
$complexMedia = $ffmpeg->openComplex($inputs);
$complexMedia->filters()
->custom('[0:v]', 'negate', '[v0negate]')
->custom('[1:v]', 'edgedetect', '[v1edgedetect]')
->custom('[2:v]', 'hflip', '[v2hflip]')
->custom('[3:v]', 'vflip', '[v3vflip]')
->xStack('[v0negate][v1edgedetect][v2hflip][v3vflip]', XStackFilter::LAYOUT_2X2, 4, '[resultv]');
$complexMedia
->map(array('0:a'), new Mp3(), 'video_1.mp3')
->map(array('1:a'), new Flac(), 'video_2.flac')
->map(array('2:a'), new Wav(), 'video_3.wav')
->map(array('3:a'), new Aac(), 'video_4.aac')
->map(array('[resultv]'), new X264('aac', 'libx264'), 'output.mp4')
->save();
```
This code takes 4 input videos, then the negates the first video, stores result in `[v0negate]` stream, detects edges in the second video, stores result in `[v1edgedetect]` stream, horizontally flips the third video, stores result in `[v2hflip]` stream, vertically flips the fourth video, stores result in `[v3vflip]` stream, then takes this 4 generated streams ans combine them in one 2x2 collage video.
Then saves audios from the original videos into the 4 different formats and saves the generated collage video into the separate file.
As you can see, you can take multiple input sources, perform the complicated processing for them and produce multiple output files in the same time, in the one ffmpeg command.
#### Just give me map!
You do not have to use `-filter_complex`. For example, just extract the audio from the video:
```php
$complexMedia = $ffmpeg->openComplex(array ('video.mp4'));
$complexMedia
->map(array('0:a'), new Mp3(), 'output.mp3')
->save();
```
#### Customisation
If you need you can extra customize the result ffmpeg command of the ComplexMedia:
```php
$complexMedia = $ffmpeg->openComplex($inputs);
$complexMedia
->setInitialParameters(array('the', 'params', 'that', 'will', 'be', 'added', 'before', '-i', 'part', 'of', 'the', 'command'))
->setAdditionalParameters(array('the', 'params', 'that', 'will', 'be', 'added', 'at', 'the', 'end', 'of', 'the', 'command'));
```
#### Formats
A format implements `FFMpeg\Format\FormatInterface`. To save to a video file,