Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Support for new manipulators? #14

Open
deevus opened this issue Aug 9, 2019 · 2 comments
Open

Support for new manipulators? #14

deevus opened this issue Aug 9, 2019 · 2 comments
Labels
enhancement New feature or request

Comments

@deevus
Copy link

deevus commented Aug 9, 2019

I would like to implement a VideoManipulator class however the PerformConversions job does not support any manipulators other than ImageManipulator.

Maybe it would work something like this:

use Intervention\Image\Image;
use Optix\Media\Facades\Conversion;
use My\VideoManipulator;
use My\Video;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        // register your manipulators
        // ImageManipulator could be the default
        Conversion::registerManipulators([
            'image' => ImageManipulator::class,
            'video' => VideoManipulator::class
        ]);

        // register by key
        Conversion::register('image', 'thumb', function (Image $image) {
            return $image->fit(64, 64);
        });

        // register by class
        Conversion::register(VideoManipulator::class, 'preview', function (Video $video) {
            return $video
                ->mute() // mute audio
                ->clip(0, 2); // clip from time 0 for 2 seconds
        });

        // or perhaps infer the manipulator by the function parameter type
        // Image infers ImageManipulator
        Conversion::register('thumb', function (Image $image) {
            return $image->fit(64, 64);
        });

        // Video infers VideoManipulator
        Conversion::register('preview', function (Video $video) {
            return $video
                ->mute() // mute audio
                ->clip(0, 2); // clip from time 0 for 2 seconds
        });
    }
}

Thoughts?

@Jack97
Copy link
Contributor

Jack97 commented Aug 12, 2019

Hi @deevus

Really like this idea, not 100% sure on what the API would look like at first thought. Quite like the idea to add the manipulators via the ConversionRegistry and to have a manipulators key in the config file.

Perhaps the manipulator would be resolved depending on the type of media that gets passed to it.

For example:

'manipulators' => [
    ImageManipulator::class => [
        'extensions' => ['png', 'jpg'], // or...
        // 'mime_types' => ['image/*']
    ],
    VideoManipulator::class => [
        'extensions' => ['mp4']
    ]
]

Alternatively it could be slightly more flexible if the the resolved manipulator is specified by the user. For example:

// 1) All manipulator's should implement a FileManipulator interface.
// 2) The media item would be loaded into the manipulator expected by the callback parameter.
// 3) This class would be responsible for preparing the media item for manipulation, i.e 
// passing the image path to Intervention\Image and exposing a manipulation API.
// 4) It would also be responsible for returning a savable resource, such as a stream to
// the job that performs the manipulations.

Conversion::register('preview', function (VideoManipulator $manipulator) {
    return $manipulator->mute()->clip(0, 2);
});

I'll try and find some time to prototype this within the coming weeks, should all be a bit clearer then.

@Jack97 Jack97 added the enhancement New feature or request label Aug 12, 2019
@deevus
Copy link
Author

deevus commented Aug 13, 2019

This is good.

One thing to note is that the manipulations should be flexible enough to be able to handle external conversion, such as video encoding using AWS services like Elastic Transcoder or Media Convert.

A closure may be enough for some implementations, but there should also be hooks so that Media manipulation can be marked as done, or failed etc asyncronously.

This is obviously more complex than my simple example but it should be doable.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants