{"id":13622568,"url":"https://github.com/PHP-FFmpeg/PHP-FFmpeg","last_synced_at":"2025-04-15T09:32:55.184Z","repository":{"id":2997040,"uuid":"4013840","full_name":"PHP-FFMpeg/PHP-FFMpeg","owner":"PHP-FFMpeg","description":"An object oriented PHP driver for FFMpeg binary","archived":false,"fork":false,"pushed_at":"2024-04-25T13:56:09.000Z","size":12110,"stargazers_count":4833,"open_issues_count":316,"forks_count":886,"subscribers_count":169,"default_branch":"master","last_synced_at":"2024-10-29T22:12:19.435Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PHP-FFMpeg.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG-0.x.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-04-13T08:21:26.000Z","updated_at":"2024-10-26T01:14:16.000Z","dependencies_parsed_at":"2024-01-03T02:22:58.391Z","dependency_job_id":"4a8f24bd-b47f-4250-aef2-bc2ef4e69ee2","html_url":"https://github.com/PHP-FFMpeg/PHP-FFMpeg","commit_stats":{"total_commits":519,"total_committers":79,"mean_commits":6.569620253164557,"dds":0.5144508670520231,"last_synced_commit":"eace6f174ff6d206ba648483ebe59760f7f6a0e1"},"previous_names":[],"tags_count":47,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHP-FFMpeg%2FPHP-FFMpeg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHP-FFMpeg%2FPHP-FFMpeg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHP-FFMpeg%2FPHP-FFMpeg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PHP-FFMpeg%2FPHP-FFMpeg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PHP-FFMpeg","download_url":"https://codeload.github.com/PHP-FFMpeg/PHP-FFMpeg/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223472809,"owners_count":17150745,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T21:01:21.161Z","updated_at":"2024-11-08T10:30:30.011Z","avatar_url":"https://github.com/PHP-FFMpeg.png","language":"PHP","readme":"# PHP-FFMPEG\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/PHP-FFMpeg/PHP-FFMpeg.svg?style=flat-square)](https://packagist.org/packages/PHP-FFMpeg/PHP-FFMpeg)\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)\n![run-tests](https://github.com/PHP-FFMpeg/PHP-FFMpeg/workflows/run-tests/badge.svg)\n[![Total Downloads](https://img.shields.io/packagist/dt/PHP-FFMpeg/PHP-FFMpeg.svg?style=flat-square)](https://packagist.org/packages/PHP-FFMpeg/PHP-FFMpeg)\n\nAn Object-Oriented library to convert video/audio files with FFmpeg / AVConv.\n\n## Your attention please\n\n### How this library works:\n\nThis library requires a working [FFMpeg install](https://ffmpeg.org/download.html). You will need both FFMpeg and FFProbe binaries to use it.\nBe sure that these binaries can be located with system PATH to get the benefit of the binary detection,\notherwise you should have to explicitly give the binaries path on load.\n\n### Known issues:\n\n- Using rotate and resize will produce a corrupted output when using\n[libav](http://libav.org/) 0.8. The bug is fixed in version 9. This bug does not\nappear in latest ffmpeg version.\n\n## Installation\n\nThis library requires PHP 8.0 or higher. For older versions of PHP, check out the [0.x-branch](https://github.com/PHP-FFMpeg/PHP-FFMpeg/tree/0.x).\n\nThe recommended way to install PHP-FFMpeg is through [Composer](https://getcomposer.org).\n\n```bash\n$ composer require php-ffmpeg/php-ffmpeg\n```\n\n## Basic Usage\n\n```php\n\nrequire 'vendor/autoload.php';\n\n$ffmpeg = FFMpeg\\FFMpeg::create();\n$video = $ffmpeg-\u003eopen('video.mpg');\n$video\n    -\u003efilters()\n    -\u003eresize(new FFMpeg\\Coordinate\\Dimension(320, 240))\n    -\u003esynchronize();\n$video\n    -\u003eframe(FFMpeg\\Coordinate\\TimeCode::fromSeconds(10))\n    -\u003esave('frame.jpg');\n$video\n    -\u003esave(new FFMpeg\\Format\\Video\\X264(), 'export-x264.mp4')\n    -\u003esave(new FFMpeg\\Format\\Video\\WMV(), 'export-wmv.wmv')\n    -\u003esave(new FFMpeg\\Format\\Video\\WebM(), 'export-webm.webm');\n```\n\n## Documentation\n\nThis documentation is an introduction to discover the API. It's recommended\nto browse the source code as it is self-documented.\n\n### FFMpeg\n\n`FFMpeg\\FFMpeg` is the main object to use to manipulate medias. To build it,\nuse the static `FFMpeg\\FFMpeg::create`:\n\n```php\n$ffmpeg = FFMpeg\\FFMpeg::create();\n```\n\nFFMpeg will autodetect ffmpeg and ffprobe binaries. If you want to give binary\npaths explicitly, you can pass an array as configuration. A `Psr\\Logger\\LoggerInterface`\ncan also be passed to log binary executions.\n\n```php\n$ffmpeg = FFMpeg\\FFMpeg::create(array(\n    'ffmpeg.binaries'  =\u003e '/opt/local/ffmpeg/bin/ffmpeg',\n    'ffprobe.binaries' =\u003e '/opt/local/ffmpeg/bin/ffprobe',\n    'timeout'          =\u003e 3600, // The timeout for the underlying process\n    'ffmpeg.threads'   =\u003e 12,   // The number of threads that FFMpeg should use\n), $logger);\n```\n\nYou may pass a `temporary_directory` key to specify a path for temporary files.\n\n```php\n$ffmpeg = FFMpeg\\FFMpeg::create(array(\n    'temporary_directory' =\u003e '/var/ffmpeg-tmp'\n), $logger);\n```\n\n### Manipulate media\n\n`FFMpeg\\FFMpeg` creates media based on URIs. URIs could be either a pointer to a\nlocal filesystem resource, an HTTP resource or any resource supported by FFmpeg.\n\n**Note**: To list all supported resource type of your FFmpeg build, use the\n`-protocols` command:\n\n```\nffmpeg -protocols\n```\n\nTo open a resource, use the `FFMpeg\\FFMpeg::open` method.\n\n```php\n$ffmpeg-\u003eopen('video.mpeg');\n```\n\nTwo types of media can be resolved: `FFMpeg\\Media\\Audio` and `FFMpeg\\Media\\Video`.\nA third type, `FFMpeg\\Media\\Frame`, is available through videos.\n\n### Video\n\n`FFMpeg\\Media\\Video` can be transcoded, ie: change codec, isolate audio or\nvideo. Frames can be extracted.\n\n##### Transcoding\n\nYou can transcode videos using the `FFMpeg\\Media\\Video:save` method. You will\npass a `FFMpeg\\Format\\FormatInterface` for that.\n\nPlease note that audio and video bitrate are set on the format. You can disable the `-b:v` option by setting the kilo bitrate to 0.\n\n```php\n$format = new FFMpeg\\Format\\Video\\X264();\n$format-\u003eon('progress', function ($video, $format, $percentage) {\n    echo \"$percentage % transcoded\";\n});\n\n$format\n    -\u003esetKiloBitrate(1000)\n    -\u003esetAudioChannels(2)\n    -\u003esetAudioKiloBitrate(256);\n\n$video-\u003esave($format, 'video.avi');\n```\n\nTranscoding progress can be monitored in realtime, see Format documentation\nbelow for more information.\n\n##### Extracting image\n\nYou can extract a frame at any timecode using the `FFMpeg\\Media\\Video::frame`\nmethod.\n\nThis code returns a `FFMpeg\\Media\\Frame` instance corresponding to the second 42.\nYou can pass any `FFMpeg\\Coordinate\\TimeCode` as argument, see dedicated\ndocumentation below for more information.\n\n```php\n$frame = $video-\u003eframe(FFMpeg\\Coordinate\\TimeCode::fromSeconds(42));\n$frame-\u003esave('image.jpg');\n```\n\nIf you want to extract multiple images from the video, you can use the following filter:\n\n```php\n$video\n    -\u003efilters()\n    -\u003eextractMultipleFrames(FFMpeg\\Filters\\Video\\ExtractMultipleFramesFilter::FRAMERATE_EVERY_10SEC, '/path/to/destination/folder/')\n    -\u003esynchronize();\n\n$video\n    -\u003esave(new FFMpeg\\Format\\Video\\X264(), '/path/to/new/file');\n```\nBy default, this will save the frames as `jpg` images.\n\nYou are able to override this using `setFrameFileType` to save the frames in another format:\n```php\n$frameFileType = 'jpg'; // either 'jpg', 'jpeg' or 'png'\n$filter = new ExtractMultipleFramesFilter($frameRate, $destinationFolder);\n$filter-\u003esetFrameFileType($frameFileType);\n\n$video-\u003eaddFilter($filter);\n```\n\n##### Clip\n\nCuts the video at a desired point. Use input seeking method. It is faster option than use filter clip.\n\n```php\n$clip = $video-\u003eclip(FFMpeg\\Coordinate\\TimeCode::fromSeconds(30), FFMpeg\\Coordinate\\TimeCode::fromSeconds(15));\n$clip-\u003esave(new FFMpeg\\Format\\Video\\X264(), 'video.avi');\n```\n\nThe clip filter takes two parameters:\n\n- `$start`, an instance of `FFMpeg\\Coordinate\\TimeCode`, specifies the start point of the clip\n- `$duration`, optional, an instance of `FFMpeg\\Coordinate\\TimeCode`, specifies the duration of the clip\n\nOn clip you can apply same filters as on video. For example resizing filter.\n\n```php\n$clip = $video-\u003eclip(FFMpeg\\Coordinate\\TimeCode::fromSeconds(30), FFMpeg\\Coordinate\\TimeCode::fromSeconds(15));\n$clip-\u003efilters()-\u003eresize(new FFMpeg\\Coordinate\\Dimension(320, 240), FFMpeg\\Filters\\Video\\ResizeFilter::RESIZEMODE_INSET, true);\n$clip-\u003esave(new FFMpeg\\Format\\Video\\X264(), 'video.avi');\n```\n\n##### Generate a waveform\n\nYou can generate a waveform of an audio file using the `FFMpeg\\Media\\Audio::waveform`\nmethod.\n\nThis code returns a `FFMpeg\\Media\\Waveform` instance.\nYou can optionally pass dimensions as the first two arguments and an array of hex string colors for ffmpeg to use for the waveform, see dedicated\ndocumentation below for more information.\n\nThe output file MUST use the PNG extension.\n\n```php\n$waveform = $audio-\u003ewaveform(640, 120, array('#00FF00'));\n$waveform-\u003esave('waveform.png');\n```\n\nIf you want to get a waveform from a video, convert it in an audio file first.\n\n```php\n// Open your video file\n$video = $ffmpeg-\u003eopen( 'video.mp4' );\n\n// Set an audio format\n$audio_format = new FFMpeg\\Format\\Audio\\Mp3();\n\n// Extract the audio into a new file as mp3\n$video-\u003esave($audio_format, 'audio.mp3');\n\n// Set the audio file\n$audio = $ffmpeg-\u003eopen( 'audio.mp3' );\n\n// Create the waveform\n$waveform = $audio-\u003ewaveform();\n$waveform-\u003esave( 'waveform.png' );\n```\n\n##### Filters\n\nYou can apply filters on `FFMpeg\\Media\\Video` with the `FFMpeg\\Media\\Video::addFilter`\nmethod. Video accepts Audio and Video filters.\n\nYou can build your own filters and some are bundled in PHP-FFMpeg - they are\naccessible through the `FFMpeg\\Media\\Video::filters` method.\n\nFilters are chainable\n\n```php\n$video\n    -\u003efilters()\n    -\u003eresize($dimension, $mode, $useStandards)\n    -\u003eframerate($framerate, $gop)\n    -\u003esynchronize();\n```\n\n###### Rotate\n\nRotates a video to a given angle.\n\n```php\n$video-\u003efilters()-\u003erotate($angle);\n```\n\nThe `$angle` parameter must be one of the following constants :\n\n- `FFMpeg\\Filters\\Video\\RotateFilter::ROTATE_90`: 90° clockwise\n- `FFMpeg\\Filters\\Video\\RotateFilter::ROTATE_180`: 180°\n- `FFMpeg\\Filters\\Video\\RotateFilter::ROTATE_270`: 90° counterclockwise\n\n###### Resize\n\nResizes a video to a given size.\n\n```php\n$video-\u003efilters()-\u003eresize($dimension, $mode, $useStandards);\n```\n\nThe resize filter takes three parameters:\n\n- `$dimension`, an instance of `FFMpeg\\Coordinate\\Dimension`\n- `$mode`, one of the constants `FFMpeg\\Filters\\Video\\ResizeFilter::RESIZEMODE_*` constants\n- `$useStandards`, a boolean to force the use of the nearest aspect ratio standard.\n\nIf you want a video in a non-standard ratio, you can use the padding filter to resize your video in the desired size, and wrap it into black bars.\n\n```php\n$video-\u003efilters()-\u003epad($dimension);\n```\n\nThe pad filter takes one parameter:\n\n- `$dimension`, an instance of `FFMpeg\\Coordinate\\Dimension`\n\nDon't forget to save it afterwards.\n\n```php\n$video-\u003esave(new FFMpeg\\Format\\Video\\X264(), $new_file);\n```\n\n###### Watermark\n\nWatermark a video with a given image.\n\n```php\n$video\n    -\u003efilters()\n    -\u003ewatermark($watermarkPath, array(\n        'position' =\u003e 'relative',\n        'bottom' =\u003e 50,\n        'right' =\u003e 50,\n    ));\n```\n\nThe watermark filter takes two parameters:\n\n`$watermarkPath`, the path to your watermark file.\n`$coordinates`, an array defining how you want your watermark positioned. You can use relative positioning as demonstrated above or absolute as such:\n\n```php\n$video\n    -\u003efilters()\n    -\u003ewatermark($watermarkPath, array(\n        'position' =\u003e 'absolute',\n        'x' =\u003e 1180,\n        'y' =\u003e 620,\n    ));\n```\n\n###### Framerate\n\nChanges the frame rate of the video.\n\n```php\n$video-\u003efilters()-\u003eframerate($framerate, $gop);\n```\n\nThe framerate filter takes two parameters:\n\n- `$framerate`, an instance of `FFMpeg\\Coordinate\\FrameRate`\n- `$gop`, a [GOP](https://wikipedia.org/wiki/Group_of_pictures) value (integer)\n\n###### Synchronize\n\nSynchronizes audio and video.\n\nSome containers may use a delay that results in desynchronized outputs. This\nfilter solves this issue.\n\n```php\n$video-\u003efilters()-\u003esynchronize();\n```\n\n###### Clip\n\nCuts the video at a desired point.\n\n```php\n$video-\u003efilters()-\u003eclip(FFMpeg\\Coordinate\\TimeCode::fromSeconds(30), FFMpeg\\Coordinate\\TimeCode::fromSeconds(15));\n```\n\nThe clip filter takes two parameters:\n\n- `$start`, an instance of `FFMpeg\\Coordinate\\TimeCode`, specifies the start point of the clip\n- `$duration`, optional, an instance of `FFMpeg\\Coordinate\\TimeCode`, specifies the duration of the clip\n\n###### Crop\n\nCrops the video based on a width and height(a `Point`)\n\n```php\n$video-\u003efilters()-\u003ecrop(new FFMpeg\\Coordinate\\Point(\"t*100\", 0, true), new FFMpeg\\Coordinate\\Dimension(200, 600));\n```\n\nIt takes two parameters:\n- `$point`, an instance of `FFMpeg\\Coordinate\\Point`, specifies the point to crop\n- `$dimension`, an instance of `FFMpeg\\Coordinate\\Dimension`, specifies the dimension of the output video\n\n### Audio\n\n`FFMpeg\\Media\\Audio` can be transcoded too, ie: change codec, isolate audio or\nvideo. Frames can be extracted.\n\n##### Transcoding\n\nYou can transcode audios using the `FFMpeg\\Media\\Audio:save` method. You will\npass a `FFMpeg\\Format\\FormatInterface` for that.\n\nPlease note that audio kilobitrate is set on the audio format.\n\n```php\n$ffmpeg = FFMpeg\\FFMpeg::create();\n$audio = $ffmpeg-\u003eopen('track.mp3');\n\n$format = new FFMpeg\\Format\\Audio\\Flac();\n$format-\u003eon('progress', function ($audio, $format, $percentage) {\n    echo \"$percentage % transcoded\";\n});\n\n$format\n    -\u003esetAudioChannels(2)\n    -\u003esetAudioKiloBitrate(256);\n\n$audio-\u003esave($format, 'track.flac');\n```\n\nTranscoding progress can be monitored in realtime, see Format documentation\nbelow for more information.\n\n##### Filters\n\nYou can apply filters on `FFMpeg\\Media\\Audio` with the `FFMpeg\\Media\\Audio::addFilter`\nmethod. It only accepts audio filters.\n\nYou can build your own filters and some are bundled in PHP-FFMpeg - they are\naccessible through the `FFMpeg\\Media\\Audio::filters` method.\n\n##### Clipping\nCuts the audio at a desired point.\n\n```php\n$audio-\u003efilters()-\u003eclip(FFMpeg\\Coordinate\\TimeCode::fromSeconds(30), FFMpeg\\Coordinate\\TimeCode::fromSeconds(15));\n```\n\n\n###### Metadata\n\nAdd metadata to audio files. Just pass an array of key=value pairs of all\nmetadata you would like to add. If no arguments are passed into the filter\nall metadata will be removed from input file. Currently supported data is\ntitle, artist, album, artist, composer, track, year, description, artwork\n\n```php\n$audio-\u003efilters()-\u003eaddMetadata([\"title\" =\u003e \"Some Title\", \"track\" =\u003e 1]);\n\n//remove all metadata and video streams from audio file\n$audio-\u003efilters()-\u003eaddMetadata();\n```\n\nAdd artwork to the audio file\n```php\n$audio-\u003efilters()-\u003eaddMetadata([\"artwork\" =\u003e \"/path/to/image/file.jpg\"]);\n```\nNOTE: at present ffmpeg (version 3.2.2) only supports artwork output for .mp3\nfiles\n\n###### Resample\n\nResamples an audio file.\n\n```php\n$audio-\u003efilters()-\u003eresample($rate);\n```\n\nThe resample filter takes two parameters :\n\n- `$rate`, a valid audio sample rate value (integer)\n\n#### Frame\n\nA frame is an image at a timecode of a video; see documentation above about\nframe extraction.\n\nYou can save frames using the `FFMpeg\\Media\\Frame::save` method.\n\n```php\n$frame-\u003esave('target.jpg');\n```\n\nThis method has a second optional boolean parameter. Set it to true to get\naccurate images; it takes more time to execute.\n\n#### Gif\n\nA gif is an animated image extracted from a sequence of the video.\n\nYou can save gif files using the `FFMpeg\\Media\\Gif::save` method.\n\n```php\n$video = $ffmpeg-\u003eopen( '/path/to/video' );\n$video\n    -\u003egif(FFMpeg\\Coordinate\\TimeCode::fromSeconds(2), new FFMpeg\\Coordinate\\Dimension(640, 480), 3)\n    -\u003esave($new_file);\n```\n\nThis method has a third optional boolean parameter, which is the duration of the animation.\nIf you don't set it, you will get a fixed gif image.\n\n#### Concatenation\n\nThis feature allows you to generate one audio or video file, based on multiple sources.\n\nThere are two ways to concatenate videos, depending on the codecs of the sources.\nIf your sources have all been encoded with the same codec, you will want to use the `FFMpeg\\Media\\Concatenate::saveFromSameCodecs` which has way better performances.\nIf your sources have been encoded with different codecs, you will want to use the `FFMpeg\\Media\\Concatenate::saveFromDifferentCodecs`.\n\nThe first function will use the initial codec as the one for the generated file.\nWith the second function, you will be able to choose which codec you want for the generated file.\n\nYou also need to pay attention to the fact that, when using the saveFromDifferentCodecs method,\nyour files MUST have video and audio streams.\n\nIn both cases, you will have to provide an array of files.\n\nTo concatenate videos encoded with the same codec, do as follow:\n\n```php\n// In order to instantiate the video object, you HAVE TO pass a path to a valid video file.\n// We recommend that you put there the path of any of the video you want to use in this concatenation.\n$video = $ffmpeg-\u003eopen( '/path/to/video' );\n$video\n    -\u003econcat(array('/path/to/video1', '/path/to/video2'))\n    -\u003esaveFromSameCodecs('/path/to/new_file', TRUE);\n```\n\nThe boolean parameter of the save function allows you to use the copy parameter which accelerates drastically the generation of the encoded file.\n\nTo concatenate videos encoded with the different codec, do as follow:\n\n```php\n// In order to instantiate the video object, you HAVE TO pass a path to a valid video file.\n// We recommend that you put there the path of any of the video you want to use in this concatenation.\n$video = $ffmpeg-\u003eopen( '/path/to/video' );\n\n$format = new FFMpeg\\Format\\Video\\X264();\n$format-\u003esetAudioCodec(\"libmp3lame\");\n\n$video\n    -\u003econcat(array('/path/to/video1', '/path/to/video2'))\n    -\u003esaveFromDifferentCodecs($format, '/path/to/new_file');\n```\n\nMore 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).\n\n### AdvancedMedia\nAdvancedMedia may have multiple inputs and multiple outputs.\n\nThis class has been developed primarily to use with `-filter_complex`.\n\nSo, its `filters()` method accepts only filters that can be used inside `-filter_complex` command.\nAdvancedMedia already contains some built-in filters.\n\n#### Base usage\nFor example:\n\n```php\n$advancedMedia = $ffmpeg-\u003eopenAdvanced(array('video_1.mp4', 'video_2.mp4'));\n$advancedMedia-\u003efilters()\n    -\u003ecustom('[0:v][1:v]', 'hstack', '[v]');\n$advancedMedia\n    -\u003emap(array('0:a', '[v]'), new X264('aac', 'libx264'), 'output.mp4')\n    -\u003esave();\n```\n\nThis code takes 2 input videos, stacks they horizontally in 1 output video and adds to this new video the audio from the first video.\n(It is impossible with simple filtergraph that has only 1 input and only 1 output).\n\n\n#### Complicated example\nA more difficult example of possibilities of the AdvancedMedia. Consider all input videos already have the same resolution and duration. (\"xstack\" filter has been added in the 4.1 version of the ffmpeg).\n\n```php\n$inputs = array(\n    'video_1.mp4',\n    'video_2.mp4',\n    'video_3.mp4',\n    'video_4.mp4',\n);\n\n$advancedMedia = $ffmpeg-\u003eopenAdvanced($inputs);\n$advancedMedia-\u003efilters()\n    -\u003ecustom('[0:v]', 'negate', '[v0negate]')\n    -\u003ecustom('[1:v]', 'edgedetect', '[v1edgedetect]')\n    -\u003ecustom('[2:v]', 'hflip', '[v2hflip]')\n    -\u003ecustom('[3:v]', 'vflip', '[v3vflip]')\n    -\u003exStack('[v0negate][v1edgedetect][v2hflip][v3vflip]', XStackFilter::LAYOUT_2X2, 4, '[resultv]');\n$advancedMedia\n    -\u003emap(array('0:a'), new Mp3(), 'video_1.mp3')\n    -\u003emap(array('1:a'), new Flac(), 'video_2.flac')\n    -\u003emap(array('2:a'), new Wav(), 'video_3.wav')\n    -\u003emap(array('3:a'), new Aac(), 'video_4.aac')\n    -\u003emap(array('[resultv]'), new X264('aac', 'libx264'), 'output.mp4')\n    -\u003esave();\n```\n\nThis 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.\nThen saves audios from the original videos into the 4 different formats and saves the generated collage video into the separate file.\n\nAs 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.\n\n#### Just give me a map!\nYou do not have to use `-filter_complex`. You can use only `-map` options. For example, just extract the audio from the video:\n\n```php\n$advancedMedia = $ffmpeg-\u003eopenAdvanced(array('video.mp4'));\n$advancedMedia\n    -\u003emap(array('0:a'), new Mp3(), 'output.mp3')\n    -\u003esave();\n```\n\n#### Customisation\nIf you need you can extra customize the result ffmpeg command of the AdvancedMedia:\n\n```php\n$advancedMedia = $ffmpeg-\u003eopenAdvanced($inputs);\n$advancedMedia\n    -\u003esetInitialParameters(array('the', 'params', 'that', 'will', 'be', 'added', 'before', '-i', 'part', 'of', 'the', 'command'))\n    -\u003esetAdditionalParameters(array('the', 'params', 'that', 'will', 'be', 'added', 'at', 'the', 'end', 'of', 'the', 'command'));\n```\n\n#### Formats\n\nA format implements `FFMpeg\\Format\\FormatInterface`. To save to a video file,\nuse `FFMpeg\\Format\\VideoInterface`, and `FFMpeg\\Format\\AudioInterface` for\naudio files.\n\nA format can also extend `FFMpeg\\Format\\ProgressableInterface` to get realtime\ninformation about the transcoding.\n\nPredefined formats already provide progress information as events.\n\n```php\n$format = new FFMpeg\\Format\\Video\\X264();\n$format-\u003eon('progress', function ($video, $format, $percentage) {\n    echo \"$percentage % transcoded\";\n});\n\n$video-\u003esave($format, 'video.avi');\n```\n\nThe callback provided for the event can be any callable.\n\n##### Add additional parameters\n\nYou can add additional parameters to your encoding requests based on your video format.\n\nThe argument of the setAdditionalParameters method is an array.\n\n```php\n$format = new FFMpeg\\Format\\Video\\X264();\n$format-\u003esetAdditionalParameters(array('foo', 'bar'));\n$video-\u003esave($format, 'video.avi');\n```\n\n##### Add initial parameters\n\nYou can also add initial parameters to your encoding requests based on your video format. This can be expecially handy in overriding a default input codec in FFMpeg.\n\nThe argument of the setInitialParameters method is an array.\n\n```php\n$format = new FFMpeg\\Format\\Video\\X264();\n$format-\u003esetInitialParameters(array('-acodec', 'libopus'));\n$video-\u003esave($format, 'video.avi');\n```\n\n##### Create your own format\n\nThe easiest way to create a format is to extend the abstract\n`FFMpeg\\Format\\Video\\DefaultVideo` and `FFMpeg\\Format\\Audio\\DefaultAudio`.\nand implement the following methods.\n\n```php\nclass CustomWMVFormat extends FFMpeg\\Format\\Video\\DefaultVideo\n{\n    public function __construct($audioCodec = 'wmav2', $videoCodec = 'wmv2')\n    {\n        $this\n            -\u003esetAudioCodec($audioCodec)\n            -\u003esetVideoCodec($videoCodec);\n    }\n\n    public function supportBFrames()\n    {\n        return false;\n    }\n\n    public function getAvailableAudioCodecs()\n    {\n        return array('wmav2');\n    }\n\n    public function getAvailableVideoCodecs()\n    {\n        return array('wmv2');\n    }\n}\n```\n\n#### Coordinates\n\nFFMpeg uses many units for time and space coordinates.\n\n- `FFMpeg\\Coordinate\\AspectRatio` represents an aspect ratio.\n- `FFMpeg\\Coordinate\\Dimension` represent a dimension.\n- `FFMpeg\\Coordinate\\FrameRate` represent a framerate.\n- `FFMpeg\\Coordinate\\Point` represent a point. (Supports dynamic points since v0.10.0)\n- `FFMpeg\\Coordinate\\TimeCode` represent a timecode.\n\n### FFProbe\n\n`FFMpeg\\FFProbe` is used internally by `FFMpeg\\FFMpeg` to probe medias. You can\nalso use it to extract media metadata.\n\n```php\n$ffprobe = FFMpeg\\FFProbe::create();\n$ffprobe\n    -\u003estreams('/path/to/video/mp4') // extracts streams informations\n    -\u003evideos()                      // filters video streams\n    -\u003efirst()                       // returns the first video stream\n    -\u003eget('codec_name');            // returns the codec_name property\n```\n\n```php\n$ffprobe = FFMpeg\\FFProbe::create();\n$ffprobe\n    -\u003eformat('/path/to/video/mp4') // extracts file informations\n    -\u003eget('duration');             // returns the duration property\n```\n\n### Validating media files\n\n(since 0.10.0)\nYou can validate media files using PHP-FFMpeg's FFProbe wrapper.\n\n```php\n$ffprobe = FFMpeg\\FFProbe::create();\n$ffprobe-\u003eisValid('/path/to/file/to/check'); // returns bool\n```\n\n## License\n\nThis project is licensed under the [MIT license](http://opensource.org/licenses/MIT).\n\nMusic: \"Favorite Secrets\" by Waylon Thornton\nFrom the Free Music Archive\n[CC BY NC SA](http://creativecommons.org/licenses/by-nc-sa/3.0/us/)\n\nMusic: \"Siesta\" by Jahzzar\nFrom the Free Music Archive\n[CC BY SA](https://creativecommons.org/licenses/by-sa/3.0/)\n","funding_links":[],"categories":["Table of Contents"],"sub_categories":["Files"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPHP-FFmpeg%2FPHP-FFmpeg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FPHP-FFmpeg%2FPHP-FFmpeg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FPHP-FFmpeg%2FPHP-FFmpeg/lists"}