Skip to content

Instantly share code, notes, and snippets.

@romainneutron
Last active December 12, 2015 08:29
Show Gist options
  • Save romainneutron/4744947 to your computer and use it in GitHub Desktop.
Save romainneutron/4744947 to your computer and use it in GitHub Desktop.
PHP-FFMpeg API update RFC

PHP-FFMpeg has grown and what was a simple H264 encoder is now a bigger library.

what we have :

To sum up here is what we have :

  • FFMpeg\FFMpeg : the main component that opens a file, transcode it to a desired format and can optionnaly extract an image.
  • FFMpeg\FFProbe : a component that extracts Streams and Formats informations about a file.

What we need :

  • More tests : for the moment the library use mostly functionnal testing. It's a design issue, all processes are instancied from the component, it's not easily mockable.
  • More features : there are plenty of features waiting in github issues : cue points, subtitles, rotation and so on.
  • More customization : Adding a progress handler was a bit tricky and I don't like the addHandler method (mostly because of its semantic)

To achieve this, we need to split this components in more subclass, make them more testable, and optimize design to fit all our needs

Propositions :

We need to splt FFMpeg/FFMpeg in a service and an object :

FFMpeg\FFMpeg is the service that opens and creates FFMpeg\MediaInterface (FFMpeg\Video and FFMpeg\Audio) :

<?php
namespace FFMpeg;

use Psr\LoggerAwreInterface;

class FFMpeg implements LoggerAwareInterface
{
    /**
     * @param $pathfile
     *
     * @return MediaInterface
     */
    public function open($pathfile);

    /**
     * @return MediaInterface
     */
    public function create();
}
<?php
namespace FFMpeg;

use Symfony\Component\Process\ProcessBuilder;

class Video implements MediaInterface, LogerAwareInterface, EventEmitterInterface
{
    /** @var ProcessBuilder */
    private $processBuilder;

    public function addListener(ListenerInterface $listener);

    public function save(FormatInterface $format);

    /**
     * @return Effects
     */
    public function effects();

    public function crop(Position $position, Size $size);

    public function screenshot(Timecode $at);

    public function cut(Timecode $from, Timecode $to);

    public function paste(MediaInterface $media, Position $position, Size $size);
}

We can think about FFMpeg\Video implementing IteratorAggregate to provide an access to new FFMpeg\Streams object in the future.

<?php
namespace FFMpeg;

use Symfony\Component\Process\ProcessBuilder;

class Effects
{
    public function __construct(ProcessBuilder $builder);
    public function verticalFlip();
    public function horizontalFlip();
    public function blackAndWhite();
    public function negative();
    public function rotate($angle);
}

Those of you that are friends with Imagine source code would recognize the design I propose.

Listeners :

The first listener to implement is the ProgressListener :

<?php
ProgressListener implements ListenerInterface
{
    public function __construct($callable, $event = 'progress.*')
    {
         $this->callable = $callable;
         $this->event = $event;
    }

    public function register(EventEmitterInterface $emitter)
    {
        $callable = $this->callable;
        $emitter->on($this->event, function ($event, MediaInterface $media, $data) use ($callable) {
            // process raw data, get an overall percentage...
            call_user_func($callable, array($event, $media, $overall, $data));
        })
    }
}
@pulse00
Copy link

pulse00 commented Feb 12, 2013

@romainneutron we're only using the audio layer so far for simply transcoding from anything to mp3, but i'm familiar with the Imagine API, and adopting this interface to the PHP-FFMpeg library sounds like a good idea.

I guess implementing those changes will result in a lot of BC breaks, but as the library is tagged anyway, this shouldn't be a problem for people not wanting to refactor their existing apps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment