Dieses Paket bietet eine Integration mit FFmpeg für Laravel 10. Das Dateisystem von Laravel übernimmt die Speicherung der Dateien.
Wir sind stolz darauf, die Community zu unterstützen, indem wir Laravel-Pakete entwickeln und diese kostenlos verschenken. Wenn Sie mit diesem Paket Zeit sparen oder sich beruflich darauf verlassen, denken Sie bitte darüber nach, die Wartung und Entwicklung zu sponsern und schauen Sie sich unser neuestes Premium-Paket an: Inertia Table. Es braucht Zeit, den Überblick über Probleme und Pull-Requests zu behalten, aber wir helfen Ihnen gerne weiter!
Super einfacher Wrapper für PHP-FFMpeg, einschließlich Unterstützung für Filter und andere erweiterte Funktionen.
Integration mit dem Dateisystem, dem Konfigurationssystem und der Protokollierungsverwaltung von Laravel.
Kompatibel mit Laravel 10, Unterstützung für Package Discovery.
Integrierte Unterstützung für HLS.
Integrierte Unterstützung für verschlüsseltes HLS (AES-128) und rotierende Schlüssel (optional).
Integrierte Unterstützung für Verkettung, mehrere Ein-/Ausgaben, Bildsequenzen (Zeitraffer), komplexe Filter (und Zuordnung), Frame-/Thumbnail-Exporte.
Integrierte Unterstützung für Wasserzeichen (Positionierung und Manipulation).
Integrierte Unterstützung für die Erstellung eines Mosaiks/Sprites/einer Kachel aus einem Video.
Integrierte Unterstützung für die Generierung von VTT-Vorschau-Thumbnail- Dateien.
Erfordert PHP 8.1 oder höher.
Getestet mit FFmpeg 4.4 und 5.0.
Stellen Sie sicher, dass Sie die neueste Version von FFmpeg installiert haben:
ffmpeg-Version
Sie können das Paket über Composer installieren:
Komponist benötigt pbmedia/laravel-ffmpeg
Fügen Sie den Dienstanbieter und die Fassade zu Ihrer app.php
-Konfigurationsdatei hinzu, wenn Sie Package Discovery nicht verwenden.
// config/app.php'providers' => [ ...ProtoneMediaLaravelFFMpegSupportServiceProvider::class, ... ];'aliases' => [ ...'FFMpeg' => ProtoneMediaLaravelFFMpegSupportFFMpeg::class ... ];
Veröffentlichen Sie die Konfigurationsdatei mit dem Artisan-CLI-Tool:
PHP-Artist-Anbieter:publish --provider="ProtoneMediaLaravelFFMpegSupportServiceProvider"
Der Konfigurationsschlüssel set_command_and_error_output_on_exception
ist jetzt standardmäßig auf true
eingestellt, wodurch Ausnahmen informativer werden. Weitere Informationen finden Sie im Abschnitt Ausnahmen behandeln.
Der Konfigurationsschlüssel enable_logging
wurde durch log_channel
ersetzt, um den Protokollkanal auszuwählen, der beim Schreiben von Nachrichten in die Protokolle verwendet wird. Wenn Sie die Protokollierung dennoch vollständig deaktivieren möchten, können Sie den neuen Konfigurationsschlüssel auf false
setzen.
Die Segmentlänge und das Keyframe-Intervall von HLS-Exporten sollten 2
oder mehr betragen; less wird nicht mehr unterstützt.
Da Laravel 9 von Flysystem 1.x auf 3.x migriert wurde, ist diese Version nicht mit Laravel 8 oder früher kompatibel.
Wenn Sie die Wasserzeichen-Manipulationsfunktion verwenden, stellen Sie sicher, dass Sie spatie/image
auf v2 aktualisieren.
Der Namespace wurde in ProtoneMediaLaravelFFMpeg
geändert, die Fassade wurde in ProtoneMediaLaravelFFMpegSupportFFMpeg
umbenannt und der Dienstanbieter wurde in ProtoneMediaLaravelFFMpegSupportServiceProvider
umbenannt.
Verkettete Exporte werden weiterhin unterstützt, Sie müssen jedoch für jeden Export erneut Filter anwenden.
HLS-Wiedergabelisten enthalten jetzt Daten zu Bitrate, Framerate und Auflösung. Die Segmente verwenden außerdem ein neues Benennungsmuster (weiterlesen). Bitte überprüfen Sie, ob Ihre Exporte in Ihrem Player noch funktionieren.
Der HLS-Export wird jetzt als ein Job ausgeführt, anstatt jedes Format/jeden Stream separat zu exportieren. Dabei werden map
und filter_complex
Funktionen von FFMpeg verwendet. Es kann ausreichend sein, alle Aufrufe von addFilter
durch addLegacyFilter
zu ersetzen, einige Filter sollten jedoch manuell migriert werden. Bitte lesen Sie die Dokumentation zu HLS, um mehr über das Hinzufügen von Filtern zu erfahren.
Konvertieren Sie eine Audio- oder Videodatei:
FFMpeg::fromDisk('songs') ->open('yesterday.mp3') ->export() ->toDisk('converted_songs') ->inFormat(neues FFMpegFormatAudioAac) ->save('yesterday.aac');
Anstelle der fromDisk()
-Methode können Sie auch die fromFilesystem()
Methode verwenden, wobei $filesystem
eine Instanz von IlluminateContractsFilesystemFilesystem
ist.
$media = FFMpeg::fromFilesystem($filesystem)->open('yesterday.mp3');
Sie können den Transkodierungsfortschritt überwachen. Verwenden Sie die onProgress
-Methode, um einen Rückruf bereitzustellen, der Ihnen den abgeschlossenen Prozentsatz liefert. In früheren Versionen dieses Pakets mussten Sie den Rückruf an das Formatobjekt übergeben.
FFMpeg::open('steve_howe.mp4') ->export() ->onProgress(function ($percentage) {echo "{$percentage}% transcoded"; });
Der Rückruf kann auch $remaining
(in Sekunden) und $rate
offenlegen:
FFMpeg::open('steve_howe.mp4') ->export() ->onProgress(function ($percentage, $remaining, $rate) {echo "{$remaining} verbleibende Sekunden bei Rate: {$rate}"; });
Sie können hochgeladene Dateien direkt aus der Request
-Instanz öffnen. Für den Fall, dass die Anfrage abbricht, ist es wahrscheinlich besser, zuerst die hochgeladene Datei zu speichern. Wenn Sie möchten, können Sie jedoch eine UploadedFile
-Instanz öffnen:
Klasse UploadVideoController {öffentliche Funktion __invoke(Request $request) { FFMpeg::open($request->file('video')); } }
Sie können Dateien aus dem Web öffnen, indem Sie die openUrl
-Methode verwenden. Sie können benutzerdefinierte HTTP-Header mit dem optionalen zweiten Parameter angeben:
FFMpeg::openUrl('https://videocoursebuilder.com/lesson-1.mp4'); FFMpeg::openUrl('https://videocoursebuilder.com/lesson-2.mp4', ['Authorization' => 'Basic YWRtaW46MTIzNA==', ]);
Wenn die Codierung fehlschlägt, wird eine ProtoneMediaLaravelFFMpegExportersEncodingException
ausgelöst, die die zugrunde liegende FFMpegExceptionRuntimeException
-Klasse erweitert. Diese Klasse verfügt über zwei Methoden, die Ihnen bei der Identifizierung des Problems helfen können. Mit der getCommand
-Methode können Sie den ausgeführten Befehl mit allen Parametern abrufen. Mit der getErrorOutput
-Methode erhalten Sie ein vollständiges Ausgabeprotokoll.
In früheren Versionen dieses Pakets lautete die Meldung der Ausnahme immer Encoding failed . Sie können ein Downgrade auf diese Meldung durchführen, indem Sie den Konfigurationsschlüssel set_command_and_error_output_on_exception
auf false
aktualisieren.
versuchen { FFMpeg::open('yesterday.mp3') ->export() ->inFormat(neues Aac) ->save('yesterday.aac'); } Catch (EncodingException $Exception) {$command = $Exception->getCommand();$errorLog = $Exception->getErrorOutput(); }
Sie können Filter über einen Closure
oder mithilfe der Filterobjekte von PHP-FFMpeg hinzufügen:
benutze FFMpegFiltersVideoVideoFilters; FFMpeg::fromDisk('videos') ->open('steve_howe.mp4') ->addFilter(function (VideoFilters $filters) {$filters->resize(new FFMpegCoordinateDimension(640, 480)); }) ->export() ->toDisk('converted_videos') ->inFormat(neues FFMpegFormatVideoX264) ->save('small_steve.mkv');// or$start = FFMpegCoordinateTimeCode::fromSeconds(5)$clipFilter = new FFMpegFiltersVideoClipFilter($start); FFMpeg::fromDisk('videos') ->open('steve_howe.mp4') ->addFilter($clipFilter) ->export() ->toDisk('converted_videos') ->inFormat(neues FFMpegFormatVideoX264) ->save('short_steve.mkv');
Sie können die Methode addFilter
auch nach der export
aufrufen:
benutze FFMpegFiltersVideoVideoFilters; FFMpeg::fromDisk('videos') ->open('steve_howe.mp4') ->export() ->toDisk('converted_videos') ->inFormat(neues FFMpegFormatVideoX264) ->addFilter(function (VideoFilters $filters) {$filters->resize(new FFMpegCoordinateDimension(640, 480)); }) ->save('small_steve.mkv');
Da die Größenänderung ein häufiger Vorgang ist, haben wir eine spezielle Methode dafür hinzugefügt:
FFMpeg::open('steve_howe.mp4') ->export() ->inFormat(neues FFMpegFormatVideoX264) ->Größe ändern(640, 480) ->save('steve_howe_resized.mp4');
Das erste Argument ist die Breite und das zweite Argument die Höhe. Das optionale dritte Argument ist der Modus. Sie können zwischen fit
(Standard), inset
, width
oder height
wählen. Das optionale vierte Argument ist ein boolescher Wert, der angibt, ob die Verwendung von Standardverhältnissen erzwungen werden soll oder nicht. Informationen zu diesen Modi finden Sie in der Klasse FFMpegFiltersVideoResizeFilter
.
Manchmal möchten Sie die integrierten Filter nicht verwenden. Sie können Ihren eigenen Filter anwenden, indem Sie eine Reihe von Optionen bereitstellen. Dies kann ein Array oder mehrere Strings als Argumente sein:
FFMpeg::fromDisk('videos') ->open('steve_howe.mp4') ->addFilter(['-itsoffset', 1]);// orFFMpeg::fromDisk('videos') ->open('steve_howe.mp4') ->addFilter('-itsoffset', 1);
Mit der Methode addWatermark
können Sie ganz einfach ein Wasserzeichen hinzufügen. Mit der WatermarkFactory
können Sie Ihre Wasserzeichendatei von einer bestimmten Festplatte öffnen, genau wie das Öffnen einer Audio- oder Videodatei. Wenn Sie die fromDisk
-Methode verwerfen, wird die in der Konfigurationsdatei filesystems.php
angegebene Standardfestplatte verwendet.
Nachdem Sie Ihre Wasserzeichendatei geöffnet haben, können Sie sie mit den Methoden top
, right
, bottom
und left
positionieren. Der erste Parameter dieser Methoden ist der Offset, der optional ist und negativ sein kann.
verwenden Sie ProtoneMediaLaravelFFMpegFiltersWatermarkFactory; FFMpeg::fromDisk('videos') ->open('steve_howe.mp4') ->addWatermark(function(WatermarkFactory $watermark) {$watermark->fromDisk('local') ->open('logo.png') ->richtig(25) ->unten(25); });
Anstelle der Positionsmethoden können Sie auch die Methoden horizontalAlignment
und verticalAlignment
verwenden.
Für die horizontale Ausrichtung können Sie die Konstanten WatermarkFactory::LEFT
, WatermarkFactory::CENTER
und WatermarkFactory::RIGHT
verwenden. Für die vertikale Ausrichtung können Sie die Konstanten WatermarkFactory::TOP
, WatermarkFactory::CENTER
und WatermarkFactory::BOTTOM
verwenden. Beide Methoden benötigen einen optionalen zweiten Parameter, nämlich den Offset.
FFMpeg::open('steve_howe.mp4') ->addWatermark(function(WatermarkFactory $watermark) {$watermark->open('logo.png') ->horizontalAlignment(WatermarkFactory::LEFT, 25) ->verticalAlignment(WatermarkFactory::TOP, 25); });
Die WatermarkFactory
unterstützt auch das Öffnen von Dateien aus dem Web mit der openUrl
-Methode. Es unterstützt auch benutzerdefinierte HTTP-Header.
FFMpeg::open('steve_howe.mp4') ->addWatermark(function(WatermarkFactory $watermark) {$watermark->openUrl('https://videocoursebuilder.com/logo.png');// oder$watermark->openUrl('https://videocoursebuilder.com/ logo.png', ['Authorization' => 'Basic YWRtaW46MTIzNA==', ]); });
Wenn Sie mehr Kontrolle über die GET-Anfrage wünschen, können Sie einen optionalen dritten Parameter übergeben, der Ihnen die Curl-Ressource zur Verfügung stellt.
$watermark->openUrl('https://videocoursebuilder.com/logo.png', ['Authorization' => 'Basic YWRtaW46MTIzNA==', ], function($curl) {curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); });
Dieses Paket kann Wasserzeichen mithilfe des Image-Pakets von Spatie bearbeiten. Installieren Sie zunächst das Paket mit Composer:
Komponist benötigt Spatie/Image
Jetzt können Sie eine weitere Manipulationsmethode auf der WatermarkFactory
-Instanz verketten:
FFMpeg::open('steve_howe.mp4') ->addWatermark(function(WatermarkFactory $watermark) {$watermark->open('logo.png') ->richtig(25) ->unten(25) ->Breite(100) ->Höhe(100) ->Graustufen(); });
Sehen Sie sich die Dokumentation für alle verfügbaren Methoden an.
Dieses Paket enthält eine ProtoneMediaLaravelFFMpegFFMpegCopyFormat
-Klasse, mit der Sie eine Datei exportieren können, ohne die Streams zu transkodieren. Möglicherweise möchten Sie dies verwenden, um einen anderen Container zu verwenden:
verwenden Sie ProtoneMediaLaravelFFMpegFFMpegCopyFormat; FFMpeg::open('video.mp4') ->export() ->inFormat(neues CopyFormat) ->save('video.mkv');
// Die Methode „fromDisk()“ ist nicht erforderlich, die Datei wird jetzt// von der Standardfestplatte geöffnet, wie in// der Konfigurationsdatei angegeben.FFMpeg::open('my_movie.mov')// Export nach FTP, konvertiert in WMV->export() ->toDisk('ftp') ->inFormat(neues FFMpegFormatVideoWMV) ->save('my_movie.wmv')// Export nach Amazon S3, konvertiert in X264->export() ->toDisk('s3') ->inFormat(neues FFMpegFormatVideoX264) ->save('my_movie.mkv');// Sie könnten sogar die Methode 'toDisk()' verwerfen,// jetzt wird die konvertierte Datei auf// derselben Festplatte wie die Quelle gespeichert!->export() ->inFormat(neues FFMpegFormatVideoWebM) ->save('my_movie.webm')// optional können Sie die Sichtbarkeit// der exportierten Datei festlegen->export() ->inFormat(neues FFMpegFormatVideoWebM) ->withVisibility('public') ->save('my_movie.webm')
FFMpeg::fromDisk('videos') ->open('steve_howe.mp4') ->getFrameFromSeconds(10) ->export() ->toDisk('thumnails') ->save('FrameAt10sec.png');// Anstelle der Methode 'getFrameFromSeconds()' können Sie // auch die Methoden 'getFrameFromString()' oder // 'getFrameFromTimecode()' verwenden:$media = FFMpeg ::open('steve_howe.mp4');$frame = $media->getFrameFromString('00:00:13.37');// or$timecode = new FFMpegCoordinateTimeCode(...);$frame = $media->getFrameFromTimecode($timecode);
Sie können auch den Rohinhalt des Frames abrufen, anstatt ihn im Dateisystem zu speichern:
$contents = FFMpeg::open('video.mp4') ->getFrameFromSeconds(2) ->export() ->getFrameContents();
Es gibt einen TileFilter
, der die Tile-Funktion unterstützt. Um den Export mehrerer Frames schneller und einfacher zu gestalten, haben wir diese Funktion genutzt, um einige Hilfsmethoden hinzuzufügen. Sie können beispielsweise die Methode exportFramesByInterval
verwenden, um Frames in einem festen Intervall zu exportieren. Alternativ können Sie die Anzahl der Frames, die Sie exportieren möchten, an die Methode exportFramesByAmount
übergeben, die dann das Intervall basierend auf der Dauer des Videos berechnet.
FFMpeg::open('video.mp4') ->exportFramesByInterval(2) ->save('thumb_%05d.jpg');
Beide Methoden akzeptieren ein optionales zweites und drittes Argument zur Angabe der Breite und Höhe der Rahmen. Anstatt sowohl die Breite als auch die Höhe zu übergeben, können Sie auch nur eine davon übergeben. FFmpeg respektiert das Seitenverhältnis der Quelle.
FFMpeg::open('video.mp4') ->exportFramesByAmount(10, 320, 180) ->save('thumb_%05d.png');
Beide Methoden akzeptieren ein optionales viertes Argument, um die Qualität des Bildes anzugeben, wenn Sie in ein verlustbehaftetes Format wie JPEG exportieren. Der Bereich für JPEG liegt zwischen 2-31
, wobei 2
die beste Qualität und 31
die schlechteste ist.
FFMpeg::open('video.mp4') ->exportFramesByInterval(2, 640, 360, 5) ->save('thumb_%05d.jpg');
Sie können Kacheln aus einem Video erstellen. Sie können die Methode exportTile
aufrufen, um anzugeben, wie Ihre Kacheln generiert werden sollen. Im folgenden Beispiel besteht jedes generierte Bild aus einem 3x5-Raster (enthält also 15 Frames) und jeder Frame ist 160x90 Pixel groß. Aus dem Video wird alle 5 Sekunden ein Bild erstellt. Anstatt sowohl die Breite als auch die Höhe zu übergeben, können Sie auch nur eine davon übergeben. FFmpeg respektiert das Seitenverhältnis der Quelle.
verwenden Sie ProtoneMediaLaravelFFMpegFiltersTileFactory; FFMpeg::open('steve_howe.mp4') ->exportTile(function (TileFactory $factory) {$factory->interval(5) ->Skala(160, 90) ->gitter(3, 5); }) ->save('tile_%05d.jpg');
Anstatt sowohl die Breite als auch die Höhe zu übergeben, können Sie auch nur eine davon übergeben, z. B. scale(160)
oder scale(null, 90)
. Das Seitenverhältnis wird respektiert. Die TileFactory
verfügt auch über die Methoden margin
, padding
, width
und height
. Es gibt auch eine quality
, um die Qualität beim Exportieren in ein verlustbehaftetes Format wie JPEG festzulegen. Der Bereich für JPEG liegt zwischen 2-31
, wobei 2
die beste Qualität und 31
die schlechteste ist.
Dieses Paket kann auch eine WebVTT-Datei generieren, um Vorschau-Miniaturansichten zu Ihrem Videoplayer hinzuzufügen. Dies wird vom JW-Player standardmäßig unterstützt und es sind auch von der Community betriebene Plugins für Video.js verfügbar. Sie können die Methode generateVTT
in der TileFactory
mit dem gewünschten Dateinamen aufrufen:
FFMpeg::open('steve_howe.mp4') ->exportTile(function (TileFactory $factory) {$factory->interval(10) ->Skala(320, 180) ->Gitter(5, 5) ->generateVTT('thumbnails.vtt'); }) ->save('tile_%05d.jpg');
Das Verketten mehrerer Konvertierungen funktioniert, da die save
von MediaExporter
eine neue Instanz von MediaOpener
zurückgibt. Damit können Sie Elemente durchlaufen, um beispielsweise mehrere Frames aus einem Video zu exportieren:
$mediaOpener = FFMpeg::open('video.mp4');foreach ([5, 15, 25] as $key => $seconds) {$mediaOpener = $mediaOpener->getFrameFromSeconds($seconds) ->export() ->save("thumb_{$key}.png"); }
Der MediaOpener
verfügt auch über eine each
-Methode. Das obige Beispiel könnte wie folgt umgestaltet werden:
FFMpeg::open('video.mp4')->each([5, 15, 25], function ($ffmpeg, $seconds, $key) {$ffmpeg->getFrameFromSeconds($seconds)->export()- >save("thumb_{$key}.png"); });
Sie können einen Zeitraffer aus einer Bildfolge erstellen, indem Sie die Methode asTimelapseWithFramerate
im Exporter verwenden
FFMpeg::open('feature_%04d.png') ->export() ->asTimelapseWithFramerate(1) ->inFormat(neues X264) ->save('timelapse.mp4');
Sie können mehrere Eingaben öffnen, sogar von verschiedenen Datenträgern. Dabei werden map
und filter_complex
Funktionen von FFMpeg verwendet. Sie können mehrere Dateien öffnen, indem Sie die Methode open
verketten oder ein Array verwenden. Sie können Eingaben von verschiedenen Festplatten mischen.
FFMpeg::open('video1.mp4')->open('video2.mp4'); FFMpeg::open(['video1.mp4', 'video2.mp4']); FFMpeg::fromDisk('uploads') ->open('video1.mp4') ->fromDisk('archive') ->open('video2.mp4');
Wenn Sie mehrere Eingaben öffnen, müssen Sie Zuordnungen hinzufügen, damit FFMpeg weiß, wie sie weitergeleitet werden. Dieses Paket stellt eine addFormatOutputMapping
-Methode bereit, die drei Parameter benötigt: das Format, die Ausgabe und die Ausgabebezeichnungen des Teils -filter_complex
.
Die Ausgabe (2. Argument) sollte eine Instanz von ProtoneMediaLaravelFFMpegFilesystemMedia
sein. Sie können mit der Methode make
eine Instanziierung durchführen, indem Sie sie mit dem Namen der Festplatte und dem Pfad aufrufen (siehe Beispiel).
Schauen Sie sich dieses Beispiel an, das separate Video- und Audioeingänge einem Ausgang zuordnet.
FFMpeg::fromDisk('local') ->open(['video.mp4', 'audio.m4a']) ->export() ->addFormatOutputMapping(new X264, Media::make('local', 'new_video.mp4'), ['0:v', '1:a']) ->save();
Dies ist ein Beispiel aus der zugrunde liegenden Bibliothek:
// Dieser Code nimmt 2 Eingabevideos, stapelt sie horizontal in 1 Ausgabevideo und// fügt diesem neuen Video den Ton des ersten Videos hinzu. (Das ist unmöglich// mit einem einfachen Filterdiagramm, das nur 1 Eingabe und nur 1 Ausgabe hat).FFMpeg::fromDisk('local') ->open(['video.mp4', 'video2.mp4']) ->export() ->addFilter('[0:v][1:v]', 'hstack', '[v]') // $in, $parameters, $out->addFormatOutputMapping(new X264, Media::make(' local', 'stacked_video.mp4'), ['0:a', '[v]']) ->save();
Genau wie einzelne Eingaben können Sie auch einen Rückruf an die Methode addFilter
übergeben. Dadurch erhalten Sie eine Instanz von FFMpegFiltersAdvancedMediaComplexFilters
:
verwenden Sie FFMpegFiltersAdvancedMediaComplexFilters; FFMpeg::open(['video.mp4', 'video2.mp4']) ->export() ->addFilter(function(ComplexFilters $filters) {// $filters->watermark(...);});
Das Öffnen von Dateien aus dem Internet funktioniert ähnlich. Sie können ein Array von URLs an die openUrl
-Methode übergeben, optional mit benutzerdefinierten HTTP-Headern.
FFMpeg::openUrl(['https://videocoursebuilder.com/lesson-3.mp4','https://videocoursebuilder.com/lesson-4.mp4', ]); FFMpeg::openUrl(['https://videocoursebuilder.com/lesson-3.mp4','https://videocoursebuilder.com/lesson-4.mp4', ], ['Authorization' => 'Basic YWRtaW46MTIzNA==', ]);
Wenn Sie für jede URL einen anderen Satz HTTP-Header verwenden möchten, können Sie die openUrl
-Methode verketten:
FFMpeg::openUrl('https://videocoursebuilder.com/lesson-5.mp4', ['Authorization' => 'Basic YWRtaW46MTIzNA==', ])->openUrl('https://videocoursebuilder.com/lesson-6.mp4', ['Authorization' => 'Basic bmltZGE6NDMyMQ==', ]);
FFMpeg::fromDisk('local') ->open(['video.mp4', 'video2.mp4']) ->export() ->concatWithoutTranscoding() ->save('concat.mp4');
FFMpeg::fromDisk('local') ->open(['video.mp4', 'video2.mp4']) ->export() ->inFormat(neues X264) ->concatWithTranscoding($hasVideo = true, $hasAudio = true) ->save('concat.mp4');
Mit der Media
-Klasse können Sie die Dauer einer Datei bestimmen:
$media = FFMpeg::open('wwdc_2006.mp4');$durationInSeconds = $media->getDurationInSeconds(); // gibt ein int$durationInMiliseconds = $media->getDurationInMiliseconds(); // gibt einen Float zurück
Beim Öffnen oder Speichern von Dateien von oder auf einer Remote-Festplatte werden temporäre Dateien auf Ihrem Server erstellt. Nachdem Sie diese Dateien exportiert oder verarbeitet haben, können Sie sie bereinigen, indem Sie die Methode cleanupTemporaryFiles()
aufrufen:
FFMpeg::cleanupTemporaryFiles();
Standardmäßig wird das Stammverzeichnis der temporären Verzeichnisse von der PHP-Methode sys_get_temp_dir()
ausgewertet. Sie können es jedoch ändern, indem Sie den Konfigurationsschlüssel temporary_files_root
auf einen benutzerdefinierten Pfad festlegen.
Sie können eine M3U8-Wiedergabeliste für HLS erstellen.
$lowBitrate = (neues X264)->setKiloBitrate(250);$midBitrate = (neues X264)->setKiloBitrate(500);$highBitrate = (neues X264)->setKiloBitrate(1000); FFMpeg::fromDisk('videos') ->open('steve_howe.mp4') ->exportForHLS() ->setSegmentLength(10) // optional->setKeyFrameInterval(48) // optional->addFormat($lowBitrate) ->addFormat($midBitrate) ->addFormat($highBitrate) ->save('adaptive_steve.m3u8');
Die addFormat
-Methode des HLS-Exporters akzeptiert einen optionalen zweiten Parameter, der eine Rückrufmethode sein kann. Dadurch können Sie je Format unterschiedliche Filter hinzufügen. Schauen Sie sich zunächst den Abschnitt „Mehrere Eingaben“ an, um zu verstehen, wie komplexe Filter gehandhabt werden.
Sie können die Methode addFilter
verwenden, um einen komplexen Filter hinzuzufügen (siehe Beispiel für $lowBitrate
). Da der scale
häufig verwendet wird, gibt es eine Hilfsmethode (siehe Beispiel $midBitrate
). Sie können auch einen Callable verwenden, um Zugriff auf die ComplexFilters
-Instanz zu erhalten. Das Paket stellt die Argumente $in
und $out
bereit, sodass Sie sich darüber keine Gedanken machen müssen (siehe Beispiel für $highBitrate
).
Der HLS-Export wird mithilfe der map
und filter_complex
Funktionen von FFMpeg erstellt. Dies ist eine bahnbrechende Änderung gegenüber früheren Versionen (1.x – 6.x), die für jedes Format einen einzelnen Export durchführten. Wenn Sie ein Upgrade durchführen, ersetzen Sie die addFilter
-Aufrufe durch addLegacyFilter
-Aufrufe und überprüfen Sie das Ergebnis (siehe Beispiel für $superBitrate
). Nicht alle Filter funktionieren auf diese Weise und einige müssen manuell aktualisiert werden.
$lowBitrate = (new X264)->setKiloBitrate(250);$midBitrate = (new X264)->setKiloBitrate(500);$highBitrate = (new X264)->setKiloBitrate(1000);$superBitrate = (new >setKiloBitrate(1500); FFMpeg::open('steve_howe.mp4') ->exportForHLS() ->addFormat($lowBitrate, function($media) {$media->addFilter('scale=640:480'); }) ->addFormat($midBitrate, function($media) {$media->scale(960, 720); }) ->addFormat($highBitrate, function ($media) {$media->addFilter(function ($filters, $in, $out) {$filters->custom($in, 'scale=1920:1200', $out ); // $in, $parameters, $out}); }) ->addFormat($superBitrate, function($media) {$media->addLegacyFilter(function ($filters) {$filters->resize(new FFMpegCoordinateDimension(2560, 1920)); }); }) ->save('adaptive_steve.m3u8');
Sie können ein benutzerdefiniertes Muster verwenden, um die Segmente und Wiedergabelisten zu benennen. Der useSegmentFilenameGenerator
gibt Ihnen 5 Argumente. Das erste, zweite und dritte Argument liefern Informationen über den Basisnamen des Exports, das Format der aktuellen Iteration und den Schlüssel der aktuellen Iteration. Das vierte Argument ist ein Rückruf, den Sie mit Ihrem Segmentmuster aufrufen sollten. Das fünfte Argument ist ein Rückruf, den Sie mit Ihrem Playlist- Muster aufrufen sollten. Beachten Sie, dass dies nicht der Name der primären Playlist ist, sondern der Name der Playlist jedes Formats.
FFMpeg::fromDisk('videos') ->open('steve_howe.mp4') ->exportForHLS() ->useSegmentFilenameGenerator(function ($name, $format, $key, callable $segments, callable $playlist) {$segments("{$name}-{$format->getKiloBitrate()}-{$key}-%03d .ts");$playlist("{$name}-{$format->getKiloBitrate()}-{$key}.m3u8"); });
Sie können jedes HLS-Segment mit der AES-128-Verschlüsselung verschlüsseln. Rufen Sie dazu die withEncryptionKey
-Methode im HLS-Exporter mit einem Schlüssel auf. Wir stellen eine generateEncryptionKey
-Hilfsmethode für die HLSExporter
-Klasse bereit, um einen Schlüssel zu generieren. Stellen Sie sicher, dass Sie den Schlüssel gut aufbewahren, da das exportierte Ergebnis ohne den Schlüssel wertlos ist. Standardmäßig lautet der Dateiname des Schlüssels secret.key
. Sie können ihn jedoch mit dem optionalen zweiten Parameter der Methode withEncryptionKey
ändern.
use ProtoneMediaLaravelFFMpegExportersHLSExporter;$encryptionKey = HLSExporter::generateEncryptionKey(); FFMpeg::open('steve_howe.mp4') ->exportForHLS() ->withEncryptionKey($encryptionKey) ->addFormat($lowBitrate) ->addFormat($midBitrate) ->addFormat($highBitrate) ->save('adaptive_steve.m3u8');
Um Ihren HLS-Export noch weiter zu sichern, können Sie den Schlüssel für jedes exportierte Segment rotieren. Dadurch werden mehrere Schlüssel generiert, die Sie speichern müssen. Verwenden Sie die Methode withRotatingEncryptionKey
, um diese Funktion zu aktivieren und einen Rückruf bereitzustellen, der die Speicherung der Schlüssel implementiert.
FFMpeg::open('steve_howe.mp4') ->exportForHLS() ->withRotatingEncryptionKey(function ($filename, $contents) {$videoId = 1;// diesen Rückruf verwenden, um die Verschlüsselungsschlüssel zu speichernStorage::disk('secrets')->put($videoId . '/' . $filename, $contents);// oder...DB::table('hls_secrets')->insert(['video_id' => $videoId,'filename' => $filename,'contents' => $contents, ]); }) ->addFormat($lowBitrate) ->addFormat($midBitrate) ->addFormat($highBitrate) ->save('adaptive_steve.m3u8');
Die Methode withRotatingEncryptionKey
verfügt über ein optionales zweites Argument, um die Anzahl der Segmente festzulegen, die denselben Schlüssel verwenden. Der Standardwert ist 1
.
FFMpeg::open('steve_howe.mp4') ->exportForHLS() ->withRotatingEncryptionKey($callable, 10);
Einige Dateisysteme, insbesondere auf günstigen und langsamen VPSs, sind nicht schnell genug, um den rotierenden Schlüssel zu verarbeiten. Dies kann zu Codierungsausnahmen führen, z. B. No key URI specified in key info file
. Eine mögliche Lösung besteht darin, einen anderen Speicher für die Schlüssel zu verwenden, den Sie mithilfe des Konfigurationsschlüssels temporary_files_encrypted_hls
angeben können. Auf UNIX-basierten Systemen können Sie ein tmpfs
Dateisystem verwenden, um die Lese-/Schreibgeschwindigkeit zu erhöhen:
// config/laravel-ffmpeg.phpreturn ['temporary_files_encrypted_hls' => '/dev/shm'];
Um die Arbeit mit verschlüsseltem HLS noch besser zu machen, haben wir eine DynamicHLSPlaylist
-Klasse hinzugefügt, die Wiedergabelisten im laufenden Betrieb und speziell für Ihre Anwendung ändert. Auf diese Weise können Sie Ihre Authentifizierungs- und Autorisierungslogik hinzufügen. Da wir einen einfachen Laravel-Controller verwenden, können Sie Funktionen wie Gates und Middleware nutzen.
In diesem Beispiel haben wir den HLS-Export auf der public
Festplatte gespeichert und die Verschlüsselungsschlüssel auf der secrets
, die nicht öffentlich verfügbar ist. Da der Browser nicht auf die Verschlüsselungsschlüssel zugreifen kann, wird das Video nicht abgespielt. Jede Wiedergabeliste verfügt über Pfade zu den Verschlüsselungsschlüsseln, und wir müssen diese Pfade ändern, um auf einen zugänglichen Endpunkt zu verweisen.
Diese Implementierung besteht aus zwei Routen. Eines, das mit einem Verschlüsselungsschlüssel antwortet, und eines, das mit einer modifizierten Wiedergabeliste antwortet. Die erste Route ( video.key
) ist relativ einfach und hier sollten Sie Ihre zusätzliche Logik hinzufügen.
Die zweite Route ( video.playlist
) verwendet die DynamicHLSPlaylist
-Klasse. Rufen Sie die Methode dynamicHLSPlaylist
auf der FFMpeg
Fassade auf. Ähnlich wie beim Öffnen von Mediendateien können Sie eine Wiedergabeliste mithilfe der Methoden fromDisk
und open
öffnen. Dann müssen Sie drei Rückrufe bereitstellen. Jeder von ihnen gibt Ihnen einen relativen Pfad und erwartet im Gegenzug einen vollständigen Pfad. Da die DynamicHLSPlaylist
Klasse die IlluminateContractsSupportResponsable
-Schnittstelle implementiert, können Sie die Instanz zurückgeben.
Der erste Rückruf (KeyUrlResolver) gibt Ihnen den relativen Pfad zu einem Verschlüsselungsschlüssel. Der zweite Rückruf (MediaUrlResolver) gibt Ihnen den relativen Pfad zu einem Mediensegment (.ts-Dateien). Der dritte Rückruf (PlaylistUrlResolver) gibt Ihnen den relativen Pfad zu einer Wiedergabeliste.
Anstatt nun Storage::disk('public')->url('adaptive_steve.m3u8')
zu verwenden, um die vollständige URL zu Ihrer primären Wiedergabeliste abzurufen, können Sie route('video.playlist', ['playlist' => 'adaptive_steve.m3u8'])
verwenden route('video.playlist', ['playlist' => 'adaptive_steve.m3u8'])
. Die DynamicHLSPlaylist
-Klasse kümmert sich um alle Pfade und URLs.
Route::get('/video/secret/{key}', function ($key) {return Storage::disk('secrets')->download($key); })->name('video.key'); Route::get('/video/{playlist}', function ($playlist) {return FFMpeg::dynamicHLSPlaylist() ->fromDisk('public') ->öffnen($playlist) ->setKeyUrlResolver(function ($key) {return route('video.key', ['key' => $key]); }) ->setMediaUrlResolver(function ($mediaFilename) {return Storage::disk('public')->url($mediaFilename); }) ->setPlaylistUrlResolver(function ($playlistFilename) {return route('video.playlist', ['playlist' => $playlistFilename]); }); })->name('video.playlist');
Hier finden Sie eine Live Coding Session zum Thema HLS-Verschlüsselung:
https://www.youtube.com/watch?v=WlbzWoAcez4
Sie können die Rohprozessausgabe erhalten, indem Sie die Methode getProcessOutput
aufrufen. Obwohl der Anwendungsfall begrenzt ist, können Sie damit eine Datei analysieren (z. B. mit dem volumedetect
Filter). Es gibt eine ProtoneMediaLaravelFFMpegSupportProcessOutput
-Klasse zurück, die über drei Methoden verfügt: all
, errors
und output
. Jede Methode gibt ein Array mit den entsprechenden Zeilen zurück.
$processOutput = FFMpeg::open('video.mp4') ->export() ->addFilter(['-filter:a', 'volumedetect', '-f', 'null']) ->getProcessOutput();$processOutput->all();$processOutput->errors();$processOutput->out();
Das Media-Objekt, das Sie erhalten, wenn Sie eine Datei „öffnen“, enthält tatsächlich das Media-Objekt, das zum zugrunde liegenden Treiber gehört. Es verarbeitet dynamische Methodenaufrufe, wie Sie hier sehen können. Auf diese Weise stehen Ihnen weiterhin alle Methoden des zugrunde liegenden Treibers zur Verfügung.
// Dadurch erhalten Sie eine Instanz von ProtoneMediaLaravelFFMpegMediaOpener$media = FFMpeg::fromDisk('videos')->open('video.mp4');// Die Methode 'getStreams' wird für das zugrunde liegende Medienobjekt aufgerufen, da// es existiert nicht auf diesem Objekt.$codec = $media->getStreams()->first()->get('codec_name');
Wenn Sie direkten Zugriff auf das zugrunde liegende Objekt wünschen, rufen Sie das Objekt als Funktion auf (invoke):
// Dies gibt Ihnen eine Instanz von ProtoneMediaLaravelFFMpegMediaOpener$media = FFMpeg::fromDisk('videos')->open('video.mp4');// Dies gibt Ihnen eine Instanz von FFMpegMediaMediaTypeInterface$baseMedia = $media();
Der Fortschritts-Listener stellt den transkodierten Prozentsatz bereit, aber das zugrunde liegende Paket verfügt auch über einen internen AbstractProgressListener
, der den aktuellen Durchgang und die aktuelle Zeit offenlegt. Obwohl der Anwendungsfall begrenzt ist, möchten Sie möglicherweise Zugriff auf diese Listener-Instanz erhalten. Sie können dies tun, indem Sie das Format mit dem ProgressListenerDecorator
dekorieren. Diese Funktion ist sehr experimentell. Testen Sie sie daher gründlich, bevor Sie sie in der Produktion verwenden.
use FFMpegFormatProgressListenerAbstractProgressListener;use ProtoneMediaLaravelFFMpegFFMpegProgressListenerDecorator;$format = new FFMpegFormatVideoX264;$decoratedFormat = ProgressListenerDecorator::decorate($format); FFMpeg::open('video.mp4') ->export() ->inFormat($decoratedFormat) ->onProgress(function () use ($decoratedFormat) {$listeners = $decoratedFormat->getListeners(); // Array von Listenern$listener = $listeners[0]; // Instanz von AbstractProgressListener$listener->getCurrentPass() ;$listener->getTotalPass();$listener->getCurrentTime(); }) ->save('new_video.mp4');
Da wir einige der zugrunde liegenden Optionen nicht entfernen können, können Sie mit dem letzten FFmpeg-Befehl interagieren, indem Sie dem Exporter einen Rückruf hinzufügen. Sie können einen oder mehrere Rückrufe hinzufügen, indem Sie die Methode beforeSaving
verwenden:
FFMpeg::open('video.mp4') ->export() ->inFormat(neues X264) ->beforeSaving(function ($commands) {$commands[] = '-hello';return $commands; }) ->save('concat.mp4');
Hinweis: Dies funktioniert nicht mit Verkettung und Frame-Exporten
Hier ist ein Blogbeitrag, der Ihnen den Einstieg in dieses Paket erleichtert:
https://protone.media/en/blog/how-to-use-ffmpeg-in-your-laravel-projects
Hier finden Sie eine 20-minütige Übersicht über die ersten Schritte mit Video.js. Es umfasst die Einbindung von Video.js aus einem CDN, den Import als ES6-Modul mit Laravel Mix (Webpack) und die Erstellung einer wiederverwendbaren Vue.js-Komponente.
https://www.youtube.com/watch?v=nA1Jy8BPjys
Benutzerdefinierte Filter
FFmpeg konnte den Befehl nicht ausführen
Ermitteln Sie die Abmessungen einer Videodatei
Überwachung des Transkodierungsfortschritts
FFProbe kann nicht geladen werden
Weitere Informationen darüber, was sich in letzter Zeit geändert hat, finden Sie im CHANGELOG.
$ Composer-Test
Weitere Informationen finden Sie unter BEITRAGEN.
Inertia Table
: Die ultimative Tabelle für Inertia.js mit integriertem Query Builder.
Laravel Blade On Demand
: Laravel-Paket zum Kompilieren von Blade-Vorlagen im Speicher.
Laravel Cross Eloquent Search
: Laravel-Paket zum Durchsuchen mehrerer Eloquent-Modelle.
Laravel Eloquent Scope as Select
: Hören Sie auf, Ihre Eloquent-Abfragebereiche und -Einschränkungen in PHP zu duplizieren. Mit diesem Paket können Sie Ihre Abfragebereiche und -einschränkungen wiederverwenden, indem Sie sie als Unterabfrage hinzufügen.
Laravel MinIO Testing Tools
: Führen Sie Ihre Tests auf einem MinIO S3-Server aus.
Laravel Mixins
: Eine Sammlung von Laravel-Goodies.
Laravel Paddle
: Paddle.com-API-Integration für Laravel mit Unterstützung für Webhooks/Events.
Laravel Task Runner
: Schreiben Sie Shell-Skripte wie Blade Components und führen Sie sie lokal oder auf einem Remote-Server aus.
Laravel Verify New Email
: Dieses Paket bietet Unterstützung für die Verifizierung neuer E-Mail-Adressen: Wenn ein Benutzer seine E-Mail-Adresse aktualisiert, wird die alte nicht ersetzt, bis die neue verifiziert wurde.
Laravel XSS Protection
: Laravel-Middleware zum Schutz Ihrer App vor Cross-Site-Scripting (XSS). Es bereinigt Anforderungseingaben und kann Blade-Echo-Anweisungen bereinigen.
Wenn Sie sicherheitsrelevante Probleme entdecken, senden Sie bitte eine E-Mail an [email protected], anstatt den Issue-Tracker zu verwenden. Bitte senden Sie keine Fragen per E-Mail. Öffnen Sie ein Problem, wenn Sie eine Frage haben.
Pascal Baljet
Alle Mitwirkenden
Die MIT-Lizenz (MIT). Weitere Informationen finden Sie in der Lizenzdatei.