PHP code example of pushinbr / pam-native-media-editor

1. Go to this page and download the library: Download pushinbr/pam-native-media-editor library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

pushinbr / pam-native-media-editor example snippets


use Pam\Native\MediaEditor\MediaClip;
use Pam\Native\MediaEditor\MediaCrop;
use Pam\Native\MediaEditor\MediaEditor;
use Pam\Native\MediaEditor\MediaExportOptions;
use Pam\Native\MediaEditor\MediaFilter;
use Pam\Native\MediaEditor\MediaTimeline;

$timeline = new MediaTimeline([
    new MediaClip(
        source: 'imports/clip.mp4',
        startMillis: 1_000,
        endMillis: 8_000,
        crop: new MediaCrop(0.1, 0.1, 0.8, 0.8),
        filter: MediaFilter::Vivid,
    ),
], soundtrack: 'imports/music.m4a', soundtrackVolume: 0.35);

(new MediaEditor())->export(
    $timeline,
    new MediaExportOptions('exports/final.mp4'),
    function ($result): void {
        // Persist or share $result->path after ExportState::Completed.
    },
);

use Pam\Native\MediaEditor\ImageOverlay;
use Pam\Native\MediaEditor\MediaAdjustments;
use Pam\Native\MediaEditor\MediaEditorFailure;
use Pam\Native\MediaEditor\MediaExportResult;
use Pam\Native\MediaEditor\MediaTimelineInfo;
use Pam\Native\MediaEditor\OverlayPlacement;
use Pam\Native\MediaEditor\TextOverlay;

$timeline = new MediaTimeline(
    [MediaClip::image('imports/cover.jpg', 5_000), new MediaClip('imports/clip.mp4', removeAudio: true)],
    soundtrack: 'imports/song.m4a',
    soundtrackVolume: 0.8,
    loopSoundtrack: true,
    adjustments: new MediaAdjustments(brightness: 0.1, saturation: -0.2, temperature: 0.3, fade: 0.2, grain: 0.3, vignette: 0.5),
    overlays: [
        new TextOverlay('Hello', new OverlayPlacement(x: 0.5, y: 0.4, scale: 1.2, rotationDegrees: 10, startMillis: 500, endMillis: 3_500), backgroundColor: '#FFFFFF', color: '#101713'),
        new ImageOverlay('https://media.example.com/sticker.gif', new OverlayPlacement(0.3, 0.7)),
    ],
    rangeStartMillis: 1_000,   // exported range on the concatenated clip timeline
    rangeEndMillis: 11_000,
);

$editor = new MediaEditor();
$editor->probe($timeline, function (?MediaTimelineInfo $info, ?string $error, ?MediaEditorFailure $failure): void {
    // $info->durationMillis, $info->clipDurationsMillis, $info->width/height, $info->hasAudio
});

$jobId = $editor->export(
    $timeline,
    new MediaExportOptions('exports/edit.mp4', width: null, height: null, videoBitRate: null, timeoutMillis: 120_000),
    function (MediaExportResult $result): void {
        // $result->completed(), ->path, ->bytes, ->durationMillis, ->width, ->height, ->hasAudio
        // or ->failure (MediaEditorFailure) and ->message
    },
    progress: function (int $percent): void {},
);

use Pam\Native\FileReference;
use Pam\Native\MediaEditor\{MediaClip, MediaEditor, MediaEditorFailure, MediaExportOptions, MediaExportResult, MediaTimeline, VideoCodec};

$timeline = new MediaTimeline(
    array_map(fn (array $s) => $s['video']
        ? new MediaClip($s['path'], removeAudio: $muteAudio)
        : MediaClip::image($s['path'], 5_000), $sources),
    soundtrack: $audioTrackPath !== '' ? $audioTrackPath : null,
    soundtrackVolume: $audioTrackVolume / 100,
    loopSoundtrack: true,
    adjustments: $adjustments,                       // null when every slider is neutral
    overlays: $layers,                               // TextOverlay / ImageOverlay (GIF stickers)
    rangeStartMillis: $trimStartMs,
    rangeEndMillis: $trimEndMs > $trimStartMs ? $trimEndMs : null,
);

(new MediaEditor())->export(
    $timeline,
    new MediaExportOptions(
        destination: 'video-editor/zechat-video-'.hrtime(true).'.mp4',
        videoCodec: VideoCodec::H264,
        width: null, height: null, videoBitRate: null,   // keep the source size, encoder bitrate
        timeoutMillis: 120_000,
    ),
    function (MediaExportResult $result): void {
        if ($result->completed()) {
            $this->media[$index] = new FileReference((string) $result->path, basename((string) $result->path), 'video/mp4', $result->bytes);
            return;
        }
        $this->error = match ($result->failure) {
            MediaEditorFailure::InvalidDuration => 'O vídeo selecionado não tem duração válida.',
            MediaEditorFailure::EmptyRange => 'A timeline selecionada não contém clipes exportáveis.',
            MediaEditorFailure::UnreadableSource => 'Não foi possível ler uma mídia da timeline.',
            MediaEditorFailure::TimedOut => 'A edição do vídeo excedeu o tempo limite.',
            default => 'Não foi possível editar o vídeo.',
        };
    },
    progress: fn (int $percent) => $this->exportProgress = $percent,
);