Paket ini menyediakan integrasi dengan FFmpeg untuk Laravel 10. Sistem File Laravel menangani penyimpanan file.
Kami dengan bangga mendukung komunitas dengan mengembangkan paket Laravel dan membagikannya secara gratis. Jika paket ini menghemat waktu Anda atau jika Anda mengandalkannya secara profesional, mohon pertimbangkan untuk mensponsori pemeliharaan dan pengembangan dan lihat paket premium terbaru kami: Tabel Inersia. Melacak masalah dan permintaan penarikan memerlukan waktu, namun kami dengan senang hati membantu!
Pembungkus PHP-FFMpeg yang sangat mudah, termasuk dukungan untuk filter dan fitur lanjutan lainnya.
Integrasi dengan Sistem File Laravel, sistem konfigurasi dan penanganan logging.
Kompatibel dengan Laravel 10, dukungan untuk Package Discovery.
Dukungan bawaan untuk HLS.
Dukungan bawaan untuk HLS terenkripsi (AES-128) dan kunci berputar (opsional).
Dukungan bawaan untuk penggabungan, beberapa input/output, urutan gambar (timelapse), filter kompleks (dan pemetaan), ekspor bingkai/thumbnail.
Dukungan bawaan untuk tanda air (pemosisian dan manipulasi).
Dukungan bawaan untuk membuat mosaik/sprite/ubin dari video.
Dukungan bawaan untuk menghasilkan file Thumbnail Pratinjau VTT .
Membutuhkan PHP 8.1 atau lebih tinggi.
Diuji dengan FFmpeg 4.4 dan 5.0.
Pastikan Anda telah menginstal FFmpeg versi terbaru:
ffmpeg -versi
Anda dapat menginstal paket melalui composer:
komposer memerlukan pbmedia/laravel-ffmpeg
Tambahkan Penyedia Layanan dan Fasad ke file konfigurasi app.php
Anda jika Anda tidak menggunakan Package Discovery.
// config/app.php'providers' => [ ...ProtoneMediaLaravelFFMpegSupportServiceProvider::kelas, ... ];'alias' => [ ...'FFMpeg' => ProtoneMediaLaravelFFMpegSupportFFMpeg::class ... ];
Publikasikan file konfigurasi menggunakan alat artisan CLI:
vendor tukang php:publish --provider="ProtoneMediaLaravelFFMpegSupportServiceProvider"
Kunci konfigurasi set_command_and_error_output_on_exception
sekarang defaultnya adalah true
, sehingga membuat pengecualian menjadi lebih informatif. Baca selengkapnya di bagian Menangani pengecualian.
Kunci konfigurasi enable_logging
telah diganti dengan log_channel
untuk memilih saluran log yang digunakan saat menulis pesan ke log. Jika Anda masih ingin menonaktifkan logging sepenuhnya, Anda dapat menyetel kunci konfigurasi baru ke false
.
Panjang segmen dan interval bingkai utama ekspor HLS harus 2
atau lebih; less tidak didukung lagi.
Karena Laravel 9 telah bermigrasi dari Flysystem 1.x ke 3.x, versi ini tidak kompatibel dengan Laravel 8 atau yang lebih lama.
Jika Anda menggunakan fitur manipulasi Watermark, pastikan Anda mengupgrade spatie/image
ke v2.
Namespace telah diubah menjadi ProtoneMediaLaravelFFMpeg
, fasad telah diubah namanya menjadi ProtoneMediaLaravelFFMpegSupportFFMpeg
, dan Penyedia Layanan telah diubah namanya menjadi ProtoneMediaLaravelFFMpegSupportServiceProvider
.
Ekspor berantai masih didukung, tetapi Anda harus menerapkan kembali filter untuk setiap ekspor.
Daftar putar HLS sekarang menyertakan data bitrate, framerate, dan resolusi. Segmen tersebut juga menggunakan pola penamaan baru (baca selengkapnya). Harap verifikasi bahwa ekspor Anda masih berfungsi di pemutar Anda.
Ekspor HLS sekarang dijalankan sebagai satu pekerjaan alih-alih mengekspor setiap format/aliran secara terpisah. Ini menggunakan fitur map
dan filter_complex
FFMpeg. Mungkin cukup mengganti semua panggilan ke addFilter
dengan addLegacyFilter
, namun beberapa filter harus dimigrasikan secara manual. Silakan baca dokumentasi di HLS untuk mengetahui lebih lanjut tentang menambahkan filter.
Mengonversi file audio atau video:
FFMpeg::fromDisk('lagu') ->buka('kemarin.mp3') ->ekspor() ->toDisk('lagu_dikonversi') ->inFormat(FFMpegFormatAudioAac baru) ->save('kemarin.aac');
Selain metode fromDisk()
Anda juga dapat menggunakan metode fromFilesystem()
, dengan $filesystem
merupakan turunan dari IlluminateContractsFilesystemFilesystem
.
$media = FFMpeg::fromFilesystem($filesystem)->open('yesterday.mp3');
Anda dapat memantau kemajuan transcoding. Gunakan metode onProgress
untuk memberikan panggilan balik, yang memberi Anda persentase penyelesaian. Dalam versi sebelumnya dari paket ini Anda harus meneruskan panggilan balik ke objek format.
FFMpeg::open('steve_howe.mp4') ->ekspor() ->onProgress(function ($percentage) {echo "{$percentage}% ditranskode"; });
Callback juga dapat mengekspos $remaining
(dalam hitungan detik) dan $rate
:
FFMpeg::open('steve_howe.mp4') ->ekspor() ->onProgress(function ($percentage, $remaining, $rate) {echo "{$remaining} detik tersisa pada rate: {$rate}"; });
Anda dapat membuka file yang diunggah langsung dari instance Request
. Mungkin lebih baik menyimpan terlebih dahulu file yang diunggah jika permintaan dibatalkan, namun jika Anda mau, Anda dapat membuka instance UploadedFile
:
kelas UploadVideoController {fungsi publik __invoke(Permintaan $permintaan) { FFMpeg::open($request->file('video')); } }
Anda dapat membuka file dari web dengan menggunakan metode openUrl
. Anda dapat menentukan header HTTP khusus dengan parameter opsional kedua:
FFMpeg::openUrl('https://videocoursebuilder.com/lesson-1.mp4'); FFMpeg::openUrl('https://videocoursebuilder.com/lesson-2.mp4', ['Otorisasi' => 'Dasar YWRtaW46MTIzNA==', ]);
Ketika pengkodean gagal, ProtoneMediaLaravelFFMpegExportersEncodingException
akan dilempar, yang memperluas kelas FFMpegExceptionRuntimeException
yang mendasarinya. Kelas ini memiliki dua metode yang dapat membantu Anda mengidentifikasi masalahnya. Dengan menggunakan metode getCommand
, Anda bisa mendapatkan perintah yang dieksekusi dengan semua parameter. Metode getErrorOutput
memberi Anda log keluaran lengkap.
Pada versi sebelumnya dari paket ini, pesan pengecualian selalu Encoding failed . Anda dapat menurunkan versi ke pesan ini dengan memperbarui kunci konfigurasi set_command_and_error_output_on_exception
ke false
.
mencoba { FFMpeg::open('kemarin.mp3') ->ekspor() -> dalam Format (Aac baru) ->save('kemarin.aac'); } catch (EncodingException $pengecualian) {$command = $pengecualian->getCommand();$errorLog = $pengecualian->getErrorOutput(); }
Anda dapat menambahkan filter melalui Closure
atau dengan menggunakan objek Filter PHP-FFMpeg:
gunakan FFMpegFiltersVideoVideoFilters; FFMpeg::fromDisk('video') ->buka('steve_howe.mp4') ->addFilter(fungsi (VideoFilters $filters) {$filters->mengubah ukuran(FFMpegCoordinateDimension(640, 480)) baru; }) ->ekspor() ->toDisk('video_konversi') -> dalamFormat(FFMPegFormatVideoX264 baru) ->save('small_steve.mkv');// or$start = FFMpegCoordinateTimeCode::fromSeconds(5)$clipFilter = FFMpegFiltersVideoClipFilter($start) baru; FFMpeg::fromDisk('video') ->buka('steve_howe.mp4') ->tambahkanFilter($klipFilter) ->ekspor() ->toDisk('video_konversi') -> dalamFormat(FFMPegFormatVideoX264 baru) ->simpan('short_steve.mkv');
Anda juga dapat memanggil metode addFilter
setelah metode export
:
gunakan FFMpegFiltersVideoVideoFilters; FFMpeg::fromDisk('video') ->buka('steve_howe.mp4') ->ekspor() ->toDisk('video_konversi') -> dalamFormat(FFMPegFormatVideoX264 baru) ->addFilter(fungsi (VideoFilters $filters) {$filters->mengubah ukuran(FFMpegCoordinateDimension(640, 480)) baru; }) ->simpan('small_steve.mkv');
Karena mengubah ukuran adalah operasi umum, kami telah menambahkan metode khusus untuk itu:
FFMpeg::open('steve_howe.mp4') ->ekspor() -> dalamFormat(FFMPegFormatVideoX264 baru) -> mengubah ukuran (640, 480) ->simpan('steve_howe_resized.mp4');
Argumen pertama adalah lebarnya, dan argumen kedua adalah tingginya. Argumen opsional ketiga adalah modus. Anda dapat memilih antara fit
(default), inset
, width
atau height
. Argumen opsional keempat adalah boolean apakah akan memaksakan penggunaan rasio standar atau tidak. Anda dapat mengetahui tentang mode ini di kelas FFMpegFiltersVideoResizeFilter
.
Terkadang Anda tidak ingin menggunakan filter bawaan. Anda dapat menerapkan filter Anda sendiri dengan memberikan serangkaian opsi. Ini bisa berupa array atau beberapa string sebagai argumen:
FFMpeg::fromDisk('video') ->buka('steve_howe.mp4') ->addFilter(['-itsoffset', 1]);// atauFFMpeg::fromDisk('videos') ->buka('steve_howe.mp4') ->addFilter('-offsetnya', 1);
Anda dapat dengan mudah menambahkan watermark menggunakan metode addWatermark
. Dengan WatermarkFactory
, Anda dapat membuka file watermark dari disk tertentu, seperti membuka file audio atau video. Saat Anda membuang metode fromDisk
, metode ini menggunakan disk default yang ditentukan dalam file konfigurasi filesystems.php
.
Setelah membuka file watermark, Anda dapat memposisikannya dengan metode top
, right
, bottom
, dan left
. Parameter pertama dari metode ini adalah offset, yang bersifat opsional dan dapat bernilai negatif.
gunakan ProtoneMediaLaravelFFMpegFiltersWatermarkFactory; FFMpeg::fromDisk('video') ->buka('steve_howe.mp4') ->tambahkanTanda Air(fungsi(WatermarkFactory $tanda air) {$tanda air->dariDisk('lokal') ->buka('logo.png') -> benar(25) ->bawah(25); });
Selain menggunakan metode posisi, Anda juga dapat menggunakan metode horizontalAlignment
dan verticalAlignment
.
Untuk perataan horizontal, Anda dapat menggunakan konstanta WatermarkFactory::LEFT
, WatermarkFactory::CENTER
dan WatermarkFactory::RIGHT
. Untuk perataan vertikal, Anda dapat menggunakan konstanta WatermarkFactory::TOP
, WatermarkFactory::CENTER
dan WatermarkFactory::BOTTOM
. Kedua metode mengambil parameter opsional kedua, yaitu offset.
FFMpeg::open('steve_howe.mp4') ->tambahkanTanda Air(fungsi(WatermarkFactory $tanda air) {$tanda air->buka('logo.png') ->Penjajaran horizontal(Pabrik Tanda Air::KIRI, 25) ->Penjajaran vertikal(WatermarkFactory::TOP, 25); });
WatermarkFactory
juga mendukung pembukaan file dari web dengan metode openUrl
. Ini juga mendukung header HTTP khusus.
FFMpeg::open('steve_howe.mp4') ->addWatermark(function(WatermarkFactory $watermark) {$watermark->openUrl('https://videocoursebuilder.com/logo.png');// atau$watermark->openUrl('https://videocoursebuilder.com/ logo.png', ['Otorisasi' => 'Dasar YWRtaW46MTIzNA==', ]); });
Jika Anda ingin kontrol lebih besar atas permintaan GET, Anda dapat meneruskan parameter opsional ketiga, yang memberi Anda sumber daya Curl.
$watermark->openUrl('https://videocoursebuilder.com/logo.png', ['Otorisasi' => 'YWRtaW46MTIzNA==' Dasar, ], fungsi($curl) {curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); });
Paket ini dapat memanipulasi watermark dengan menggunakan paket Image Spatie. Untuk memulai, instal paket dengan Composer:
komposer membutuhkan spatie/gambar
Sekarang Anda dapat merangkai satu metode manipulasi lagi pada instance WatermarkFactory
:
FFMpeg::open('steve_howe.mp4') ->tambahkanTanda Air(fungsi(WatermarkFactory $tanda air) {$tanda air->buka('logo.png') -> benar(25) -> bawah(25) ->lebar(100) -> tinggi(100) ->skala abu-abu(); });
Lihat dokumentasi untuk semua metode yang tersedia.
Paket ini dilengkapi dengan kelas ProtoneMediaLaravelFFMpegFFMpegCopyFormat
yang memungkinkan Anda mengekspor file tanpa melakukan transcoding aliran. Anda mungkin ingin menggunakan ini untuk menggunakan wadah lain:
gunakan ProtoneMediaLaravelFFMpegFFMpegCopyFormat; FFMpeg::open('video.mp4') ->ekspor() ->inFormat(CopyFormat baru) ->simpan('video.mkv');
// Metode 'fromDisk()' tidak diperlukan, file sekarang akan// dibuka dari 'disk' default, sebagaimana ditentukan dalam// file konfigurasi.FFMpeg::open('my_movie.mov')// ekspor ke FTP, dikonversi dalam WMV->export() ->keDisk('ftp') ->inFormat(FFMPegFormatVideoWMV baru) ->save('my_movie.wmv')// ekspor ke Amazon S3, dikonversi dalam X264->export() -> ke Disk('s3') -> dalamFormat(FFMPegFormatVideoX264 baru) ->save('my_movie.mkv');// Anda bahkan dapat membuang metode 'toDisk()',// sekarang file yang dikonversi akan disimpan ke// disk yang sama dengan sumbernya!->export() ->inFormat(FFMPegFormatVideoWebM baru) ->save('my_movie.webm')// secara opsional Anda dapat mengatur visibilitas// file yang diekspor->export() ->inFormat(FFMPegFormatVideoWebM baru) ->denganVisibilitas('publik') ->simpan('film_saya.webm')
FFMpeg::fromDisk('video') ->buka('steve_howe.mp4') ->dapatkanFrameFromSeconds(10) ->ekspor() ->toDisk('thumbnail') ->save('FrameAt10sec.png');// Daripada menggunakan metode 'getFrameFromSeconds()', Anda dapat// juga menggunakan metode 'getFrameFromString()' atau // 'getFrameFromTimecode()':$media = FFMpeg ::open('steve_howe.mp4');$frame = $media->getFrameFromString('00:00:13.37');// atau$timecode = FFMpegCoordinateTimeCode(...);$frame = $media->getFrameFromTimecode($timecode);
Anda juga bisa mendapatkan konten mentah dari frame alih-alih menyimpannya ke sistem file:
$isi = FFMpeg::open('video.mp4') ->dapatkanFrameFromSeconds(2) ->ekspor() ->dapatkanFrameContents();
Ada TileFilter
yang mendukung fitur Tile. Untuk membuat ekspor beberapa frame menjadi lebih cepat dan sederhana, kami memanfaatkan fitur ini untuk menambahkan beberapa metode bantuan. Misalnya, Anda dapat menggunakan metode exportFramesByInterval
untuk mengekspor bingkai dengan interval tetap. Alternatifnya, Anda dapat meneruskan jumlah frame yang ingin Anda ekspor ke metode exportFramesByAmount
, yang kemudian akan menghitung interval berdasarkan durasi video.
FFMpeg::open('video.mp4') ->eksporFramesByInterval(2) ->simpan('ibu jari_%05d.jpg');
Kedua metode menerima argumen opsional kedua dan ketiga untuk menentukan lebar dan tinggi bingkai. Daripada melewati lebar dan tinggi, Anda juga bisa melewati salah satunya saja. FFmpeg akan menghormati rasio aspek sumber.
FFMpeg::open('video.mp4') ->eksporFramesByAmount(10, 320, 180) ->simpan('ibu jari_%05d.png');
Kedua metode menerima argumen opsional keempat untuk menentukan kualitas gambar saat Anda mengekspor ke format lossy seperti JPEG. Kisaran untuk JPEG adalah 2-31
, dengan 2
sebagai kualitas terbaik dan 31
sebagai kualitas terburuk.
FFMpeg::open('video.mp4') ->eksporFramesByInterval(2, 640, 360, 5) ->simpan('ibu jari_%05d.jpg');
Anda dapat membuat ubin dari video. Anda dapat memanggil metode exportTile
untuk menentukan bagaimana ubin Anda harus dibuat. Pada contoh di bawah, setiap gambar yang dihasilkan terdiri dari grid 3x5 (berisi 15 frame) dan setiap frame berukuran 160x90 piksel. Sebuah bingkai akan diambil setiap 5 detik dari video. Daripada melewati lebar dan tinggi, Anda juga bisa melewati salah satunya saja. FFmpeg akan menghormati rasio aspek sumber.
gunakan ProtoneMediaLaravelFFMpegFiltersTileFactory; FFMpeg::open('steve_howe.mp4') ->exportTile(fungsi (TileFactory $pabrik) {$pabrik->interval(5) ->skala(160, 90) ->kisi(3, 5); }) ->simpan('tile_%05d.jpg');
Daripada meneruskan lebar dan tinggi, Anda juga dapat meneruskan salah satunya saja seperti scale(160)
atau scale(null, 90)
. Rasio aspek akan dihormati. TileFactory
juga memiliki metode margin
, padding
, width
, dan height
. Ada juga metode quality
untuk menentukan kualitas saat mengekspor ke format lossy seperti JPEG. Kisaran untuk JPEG adalah 2-31
, dengan 2
sebagai kualitas terbaik dan 31
sebagai kualitas terburuk.
Paket ini juga dapat menghasilkan file WebVTT untuk menambahkan Thumbnail Pratinjau ke pemutar video Anda. Ini didukung langsung oleh JW player dan tersedia juga plugin berbasis komunitas untuk Video.js. Anda dapat memanggil metode generateVTT
di TileFactory
dengan nama file yang diinginkan:
FFMpeg::open('steve_howe.mp4') ->exportTile(fungsi (TileFactory $pabrik) {$pabrik->interval(10) ->skala(320, 180) -> kisi(5, 5) ->generateVTT('thumbnail.vtt'); }) ->simpan('tile_%05d.jpg');
Merangkai beberapa konversi berfungsi karena metode save
MediaExporter
mengembalikan instance MediaOpener
yang baru. Anda dapat menggunakan ini untuk mengulang item, misalnya, untuk mengekspor beberapa frame dari satu video:
$mediaOpener = FFMpeg::open('video.mp4');foreach ([5, 15, 25] sebagai $key => $detik) {$mediaOpener = $mediaOpener->getFrameFromSeconds($detik) ->ekspor() ->simpan("ibu jari_{$kunci}.png"); }
MediaOpener
juga hadir dengan each
metode. Contoh di atas dapat difaktorkan ulang seperti ini:
FFMpeg::open('video.mp4')->masing-masing([5, 15, 25], fungsi ($ffmpeg, $detik, $kunci) {$ffmpeg->getFrameFromSeconds($detik)->ekspor()- >simpan("ibu jari_{$kunci}.png"); });
Anda dapat membuat timelapse dari rangkaian gambar dengan menggunakan metode asTimelapseWithFramerate
pada eksportir
FFMpeg::open('feature_%04d.png') ->ekspor() ->sebagai TimelapseDenganFramerate(1) -> dalam Format (X264 baru) ->simpan('timelapse.mp4');
Anda dapat membuka banyak input, bahkan dari disk yang berbeda. Ini menggunakan fitur map
dan filter_complex
FFMpeg. Anda dapat membuka banyak file dengan merangkai metode open
menggunakan array. Anda dapat mencampur input dari disk yang berbeda.
FFMpeg::open('video1.mp4')->open('video2.mp4'); FFMpeg::open(['video1.mp4', 'video2.mp4']); FFMpeg::fromDisk('upload') ->buka('video1.mp4') ->dariDisk('arsip') ->buka('video2.mp4');
Saat Anda membuka beberapa input, Anda harus menambahkan pemetaan sehingga FFMpeg mengetahui cara merutekannya. Paket ini menyediakan metode addFormatOutputMapping
, yang mengambil tiga parameter: format, output, dan label output dari bagian -filter_complex
.
Outputnya (argumen ke-2) harus berupa instance dari ProtoneMediaLaravelFFMpegFilesystemMedia
. Anda dapat membuat instance dengan metode make
, memanggilnya dengan nama disk dan jalurnya (lihat contoh).
Lihat contoh ini, yang memetakan input video dan audio terpisah menjadi satu output.
FFMpeg::fromDisk('lokal') ->buka(['video.mp4', 'audio.m4a']) ->ekspor() ->addFormatOutputMapping(X264 baru, Media::make('local', 'new_video.mp4'), ['0:v', '1:a']) ->simpan();
Ini adalah contoh dari perpustakaan yang mendasarinya:
// Kode ini mengambil 2 video masukan, menumpuknya secara horizontal dalam 1 video keluaran dan// menambahkan audio dari video pertama ke video baru ini. (Tidak mungkin// dengan grafik filter sederhana yang hanya memiliki 1 masukan dan hanya 1 keluaran).FFMpeg::fromDisk('local') ->buka(['video.mp4', 'video2.mp4']) ->ekspor() ->addFilter('[0:v][1:v]', 'hstack', '[v]') // $in, $parameters, $out->addFormatOutputMapping(X264 baru, Media::make(' lokal', 'stacked_video.mp4'), ['0:a', '[v]']) ->simpan();
Sama seperti input tunggal, Anda juga dapat meneruskan panggilan balik ke metode addFilter
. Ini akan memberi Anda contoh FFMpegFiltersAdvancedMediaComplexFilters
:
gunakan FFMpegFiltersAdvancedMediaComplexFilters; FFMpeg::open(['video.mp4', 'video2.mp4']) ->ekspor() ->addFilter(function(ComplexFilters $filters) {// $filters->tanda air(...);});
Membuka file dari web bekerja dengan cara yang sama. Anda dapat meneruskan serangkaian URL ke metode openUrl
, secara opsional dengan header HTTP khusus.
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', ], ['Otorisasi' => 'Dasar YWRtaW46MTIzNA==', ]);
Jika Anda ingin menggunakan kumpulan header HTTP lain untuk setiap URL, Anda dapat merangkai metode openUrl
:
FFMpeg::openUrl('https://videocoursebuilder.com/lesson-5.mp4', ['Otorisasi' => 'Dasar YWRtaW46MTIzNA==', ])->openUrl('https://videocoursebuilder.com/lesson-6.mp4', ['Otorisasi' => 'Dasar bmltZGE6NDMyMQ==', ]);
FFMpeg::fromDisk('lokal') ->buka(['video.mp4', 'video2.mp4']) ->ekspor() ->concatTanpaTranscoding() ->simpan('concat.mp4');
FFMpeg::fromDisk('lokal') ->buka(['video.mp4', 'video2.mp4']) ->ekspor() -> dalam Format (X264 baru) ->concatWithTranscoding($hasVideo = benar, $hasAudio = benar) ->simpan('concat.mp4');
Dengan kelas Media
Anda dapat menentukan durasi file:
$media = FFMpeg::open('wwdc_2006.mp4');$durationInSeconds = $media->getDurationInSeconds(); // mengembalikan int$durationInMiliseconds = $media->getDurationInMiliseconds(); // mengembalikan pelampung
Saat membuka atau menyimpan file dari atau ke disk jarak jauh, file sementara akan dibuat di server Anda. Setelah selesai mengekspor atau memproses file ini, Anda dapat membersihkannya dengan memanggil metode cleanupTemporaryFiles()
:
FFMpeg::cleanupTemporaryFiles();
Secara default, akar direktori sementara dievaluasi dengan metode sys_get_temp_dir()
PHP, namun Anda dapat memodifikasinya dengan mengatur kunci konfigurasi temporary_files_root
ke jalur khusus.
Anda dapat membuat playlist M3U8 untuk melakukan HLS.
$lowBitrate = (X264 baru)->setKiloBitrate(250);$midBitrate = (X264 baru)->setKiloBitrate(500);$highBitrate = (X264 baru)->setKiloBitrate(1000); FFMpeg::fromDisk('video') ->buka('steve_howe.mp4') ->eksporUntukHLS() ->setSegmentLength(10) // opsional->setKeyFrameInterval(48) // opsional->addFormat($lowBitrate) ->addFormat($midBitrate) ->tambahkanFormat($kecepatan bit tinggi) ->simpan('adaptive_steve.m3u8');
Metode addFormat
eksportir HLS mengambil parameter opsional kedua yang dapat menjadi metode panggilan balik. Ini memungkinkan Anda menambahkan filter berbeda per format. Pertama, lihat bagian Beberapa masukan untuk memahami cara menangani filter kompleks.
Anda dapat menggunakan metode addFilter
untuk menambahkan filter kompleks (lihat contoh $lowBitrate
). Karena filter scale
sering digunakan, ada metode pembantu (lihat contoh $midBitrate
). Anda juga dapat menggunakan callable untuk mendapatkan akses ke instance ComplexFilters
. Paket ini menyediakan argumen $in
dan $out
sehingga Anda tidak perlu mengkhawatirkannya (lihat contoh $highBitrate
).
Ekspor HLS dibuat menggunakan fitur map
dan filter_complex
FFMpeg. Ini merupakan perubahan besar dari versi sebelumnya (1.x - 6.x) yang melakukan ekspor tunggal untuk setiap format. Jika Anda meningkatkan versi, ganti panggilan addFilter
dengan panggilan addLegacyFilter
dan verifikasi hasilnya (lihat contoh $superBitrate
). Tidak semua filter berfungsi dengan cara ini dan beberapa filter perlu ditingkatkan secara manual.
$lowBitrate = (X264 baru)->setKiloBitrate(250);$midBitrate = (X264 baru)->setKiloBitrate(500);$highBitrate = (X264 baru)->setKiloBitrate(1000);$superBitrate = (X264 baru)- >setKiloBitrate(1500); FFMpeg::open('steve_howe.mp4') ->eksporUntukHLS() ->addFormat($lowBitrate, function($media) {$media->addFilter('scale=640:480'); }) ->addFormat($midBitrate, function($media) {$media->skala(960, 720); }) ->addFormat($highBitrate, function ($media) {$media->addFilter(function ($filters, $in, $out) {$filters->custom($in, 'scale=1920:1200', $out ); // $masuk, $parameter, $keluar}); }) ->addFormat($superBitrate, function($media) {$media->addLegacyFilter(function ($filters) {$filters->resize(new FFMpegCoordinateDimension(2560, 1920)); }); }) ->simpan('adaptive_steve.m3u8');
Anda dapat menggunakan pola khusus untuk memberi nama segmen dan daftar putar. useSegmentFilenameGenerator
memberi Anda 5 argumen. Argumen pertama, kedua, dan ketiga memberikan informasi tentang nama dasar ekspor, format iterasi saat ini, dan kunci iterasi saat ini. Argumen keempat adalah panggilan balik yang harus Anda panggil dengan pola segmen Anda. Argumen kelima adalah panggilan balik yang harus Anda panggil dengan pola playlist Anda. Perhatikan bahwa ini bukan nama playlist utama, melainkan nama playlist dari setiap format.
FFMpeg::fromDisk('video') ->buka('steve_howe.mp4') ->eksporUntukHLS() ->useSegmentFilenameGenerator(fungsi ($name, $format, $key, $segments yang dapat dipanggil, $playlist yang dapat dipanggil) {$segments("{$name}-{$format->getKiloBitrate()}-{$key}-%03d .ts");$playlist("{$name}-{$format->getKiloBitrate()}-{$key}.m3u8"); });
Anda dapat mengenkripsi setiap segmen HLS menggunakan enkripsi AES-128. Untuk melakukannya, panggil metode withEncryptionKey
pada eksportir HLS dengan kunci. Kami menyediakan metode pembantu generateEncryptionKey
pada kelas HLSExporter
untuk menghasilkan kunci. Pastikan Anda menyimpan kunci dengan baik, karena hasil yang diekspor tidak ada gunanya tanpa kunci tersebut. Secara default, nama file kuncinya adalah secret.key
, tetapi Anda dapat mengubahnya dengan parameter opsional kedua dari metode withEncryptionKey
.
gunakan ProtoneMediaLaravelFFMpegExportersHLSExporter;$encryptionKey = HLSExporter::generateEncryptionKey(); FFMpeg::open('steve_howe.mp4') ->eksporUntukHLS() ->denganEncryptionKey($encryptionKey) ->tambahkanFormat($Kecepatan Bit rendah) ->addFormat($midBitrate) ->tambahkanFormat($kecepatan bit tinggi) ->simpan('adaptive_steve.m3u8');
Untuk lebih mengamankan ekspor HLS Anda, Anda dapat memutar kunci pada setiap segmen yang diekspor. Dengan melakukan itu, ini akan menghasilkan beberapa kunci yang perlu Anda simpan. Gunakan metode withRotatingEncryptionKey
untuk mengaktifkan fitur ini dan menyediakan callback yang mengimplementasikan penyimpanan kunci.
FFMpeg::open('steve_howe.mp4') ->eksporUntukHLS() ->withRotatingEncryptionKey(function ($filename, $contents) {$videoId = 1;// gunakan panggilan balik ini untuk menyimpan kunci enkripsiStorage::disk('secrets')->put($videoId . '/' . $filename, $isi);// atau...DB::table('hls_secrets')->insert(['video_id' => $videoId,'namafile' => $namafile,'isi' => $isi, ]); }) ->tambahkanFormat($Kecepatan Bit rendah) ->addFormat($midBitrate) ->tambahkanFormat($kecepatan bit tinggi) ->simpan('adaptive_steve.m3u8');
Metode withRotatingEncryptionKey
memiliki argumen opsional kedua untuk mengatur jumlah segmen yang menggunakan kunci yang sama. Ini defaultnya adalah 1
.
FFMpeg::open('steve_howe.mp4') ->eksporUntukHLS() ->denganRotatingEncryptionKey($dapat dipanggil, 10);
Beberapa sistem file, terutama pada VPS yang murah dan lambat, tidak cukup cepat untuk menangani kunci yang berputar. Hal ini dapat menyebabkan pengecualian penyandian, seperti No key URI specified in key info file
. Salah satu solusi yang mungkin adalah dengan menggunakan penyimpanan berbeda untuk kunci, yang dapat Anda tentukan menggunakan kunci konfigurasi temporary_files_encrypted_hls
. Pada sistem berbasis UNIX, Anda dapat menggunakan sistem file tmpfs
untuk meningkatkan kecepatan baca/tulis:
// config/laravel-ffmpeg.phpreturn ['temporary_files_encrypted_hls' => '/dev/shm'];
Untuk membuat bekerja dengan HLS terenkripsi menjadi lebih baik, kami telah menambahkan kelas DynamicHLSPlaylist
yang mengubah daftar putar dengan cepat dan khusus untuk aplikasi Anda. Dengan cara ini, Anda dapat menambahkan logika autentikasi dan otorisasi Anda. Karena kami menggunakan pengontrol Laravel biasa, Anda dapat menggunakan fitur seperti Gates dan Middleware.
Dalam contoh ini, kami telah menyimpan ekspor HLS ke disk public
, dan kami telah menyimpan kunci enkripsi ke disk secrets
, yang tidak tersedia untuk umum. Karena browser tidak dapat mengakses kunci enkripsi, browser tidak dapat memutar video. Setiap playlist memiliki jalur ke kunci enkripsi, dan kita perlu mengubah jalur tersebut agar mengarah ke titik akhir yang dapat diakses.
Implementasi ini terdiri dari dua jalur. Yang merespons dengan kunci enkripsi dan yang merespons dengan playlist yang dimodifikasi. Rute pertama ( video.key
) relatif sederhana, dan di sinilah Anda harus menambahkan logika tambahan.
Rute kedua ( video.playlist
) menggunakan kelas DynamicHLSPlaylist
. Panggil metode dynamicHLSPlaylist
pada fasad FFMpeg
, dan mirip dengan membuka file media, Anda dapat membuka playlist menggunakan metode fromDisk
dan open
. Maka Anda harus memberikan tiga panggilan balik. Masing-masing memberi Anda jalur relatif dan mengharapkan jalur penuh sebagai balasannya. Saat kelas DynamicHLSPlaylist
mengimplementasikan antarmuka IlluminateContractsSupportResponsable
, Anda dapat mengembalikan instance tersebut.
Callback pertama (KeyUrlResolver) memberi Anda jalur relatif ke kunci enkripsi. Callback kedua (MediaUrlResolver) memberi Anda jalur relatif ke segmen media (file .ts). Callback ketiga (PlaylistUrlResolver) memberi Anda jalur relatif ke playlist.
Sekarang daripada menggunakan Storage::disk('public')->url('adaptive_steve.m3u8')
untuk mendapatkan url lengkap ke playlist utama Anda, Anda dapat menggunakan route('video.playlist', ['playlist' => 'adaptive_steve.m3u8'])
. Kelas DynamicHLSPlaylist
menangani semua jalur dan url.
Rute::dapatkan('/video/rahasia/{kunci}', fungsi ($kunci) {kembali Penyimpanan::disk('rahasia')->unduh($kunci); })->nama('video.kunci'); Rute::dapatkan('/video/{playlist}', fungsi ($daftar putar) {return FFMpeg::dynamicHLSPlaylist() ->dariDisk('publik') ->buka($daftar putar) ->setKeyUrlResolver(fungsi ($kunci) {rute kembali('video.kunci', ['kunci' => $kunci]); }) ->setMediaUrlResolver(fungsi ($mediaFilename) {return Storage::disk('public')->url($mediaFilename); }) ->setPlaylistUrlResolver(fungsi ($playlistFilename) {rute kembali('video.playlist', ['playlist' => $playlistFilename]); }); })->nama('video.daftar putar');
Di sini Anda dapat menemukan Sesi Pengodean Langsung tentang enkripsi HLS:
https://www.youtube.com/watch?v=WlbzWoAcez4
Anda bisa mendapatkan keluaran proses mentah dengan memanggil metode getProcessOutput
. Meskipun kasus penggunaannya terbatas, Anda dapat menggunakannya untuk menganalisis file (misalnya, dengan filter volumedetect
). Ia mengembalikan kelas ProtoneMediaLaravelFFMpegSupportProcessOutput
yang memiliki tiga metode: all
, errors
dan output
. Setiap metode mengembalikan array dengan baris yang sesuai.
$processOutput = FFMpeg::open('video.mp4') ->ekspor() ->addFilter(['-filter:a', 'volumedeteksi', '-f', 'null']) ->getProcessOutput();$processOutput->all();$processOutput->errors();$processOutput->out();
Objek Media yang Anda dapatkan saat 'membuka' file, sebenarnya menyimpan objek Media milik driver yang mendasarinya. Ini menangani panggilan metode dinamis seperti yang Anda lihat di sini. Dengan cara ini semua metode driver yang mendasarinya masih tersedia untuk Anda.
// Ini memberi Anda instance ProtoneMediaLaravelFFMpegMediaOpener$media = FFMpeg::fromDisk('videos')->open('video.mp4');// Metode 'getStreams' akan dipanggil pada objek Media yang mendasarinya sejak// itu tidak ada pada objek ini.$codec = $media->getStreams()->first()->get('codec_name');
Jika Anda ingin akses langsung ke objek yang mendasarinya, panggil objek tersebut sebagai fungsi (panggil):
// Ini memberi Anda sebuah instance dari ProtoneMediaLaravelFFMpegMediaOpener$media = FFMpeg::fromDisk('videos')->open('video.mp4');// Ini memberi Anda sebuah instance dari FFMpegMediaMediaTypeInterface$baseMedia = $media();
Pemroses kemajuan memperlihatkan persentase yang ditranskode, tetapi paket yang mendasarinya juga memiliki AbstractProgressListener
internal yang memperlihatkan lintasan saat ini dan waktu saat ini. Meskipun kasus penggunaannya terbatas, Anda mungkin ingin mendapatkan akses ke instance pendengar ini. Anda dapat melakukan ini dengan mendekorasi format dengan ProgressListenerDecorator
. Fitur ini sangat eksperimental, jadi pastikan untuk mengujinya secara menyeluruh sebelum menggunakannya dalam produksi.
gunakan FFMpegFormatProgressListenerAbstractProgressListener; gunakan ProtoneMediaLaravelFFMpegFFMpegProgressListenerDecorator;$format = FFMpegFormatVideoX264 baru;$decoratedFormat = ProgressListenerDecorator::decorate($format); FFMpeg::open('video.mp4') ->ekspor() ->inFormat($dihiasiFormat) ->onProgress(function () use ($decoratedFormat) {$listeners = $decoratedFormat->getListeners(); // array pendengar$listener = $listeners[0]; // instance dari abstractProgressListener$listener->getCurrentPass() ;$listener->getTotalPass();$listener->getCurrentTime(); }) ->simpan('video_baru.mp4');
Karena kami tidak dapat menghilangkan beberapa opsi yang mendasarinya, Anda dapat berinteraksi dengan perintah FFmpeg terakhir dengan menambahkan panggilan balik ke eksportir. Anda dapat menambahkan satu atau lebih callback dengan menggunakan metode beforeSaving
:
FFMpeg::open('video.mp4') ->ekspor() -> dalam Format (X264 baru) ->beforeSaving(function ($commands) {$commands[] = '-hello';return $commands; }) ->simpan('concat.mp4');
Catatan: ini tidak berfungsi dengan penggabungan dan ekspor bingkai
Berikut postingan blog yang akan membantu Anda memulai dengan paket ini:
https://protone.media/en/blog/how-to-use-ffmpeg-in-your-laravel-projects
Berikut ikhtisar 20 menit tentang cara memulai Video.js. Ini mencakup penyertaan Video.js dari CDN, mengimpornya sebagai modul ES6 dengan Laravel Mix (Webpack) dan membuat komponen Vue.js yang dapat digunakan kembali.
https://www.youtube.com/watch?v=nA1Jy8BPjys
Filter khusus
FFmpeg gagal menjalankan perintah
Dapatkan dimensi file Video
Memantau kemajuan transcoding
Tidak dapat memuat FFProbe
Silakan lihat CHANGELOG untuk informasi lebih lanjut tentang apa yang berubah baru-baru ini.
$ tes komposer
Silakan lihat KONTRIBUSI untuk rinciannya.
Inertia Table
: Tabel Utama untuk Inertia.js dengan Pembuat Kueri bawaan.
Laravel Blade On Demand
: Paket Laravel untuk mengkompilasi template Blade di memori.
Laravel Cross Eloquent Search
: Paket Laravel untuk mencari melalui beberapa model Eloquent.
Laravel Eloquent Scope as Select
: Berhenti menduplikasi cakupan dan batasan kueri Eloquent Anda di PHP. Paket ini memungkinkan Anda menggunakan kembali cakupan dan batasan kueri dengan menambahkannya sebagai subkueri.
Laravel MinIO Testing Tools
: Jalankan pengujian Anda terhadap server MinIO S3.
Laravel Mixins
: Kumpulan barang Laravel.
Laravel Paddle
: Integrasi API Paddle.com untuk Laravel dengan dukungan untuk webhook/acara.
Laravel Task Runner
: Tulis skrip Shell seperti Blade Components dan jalankan secara lokal atau di server jarak jauh.
Laravel Verify New Email
: Paket ini menambahkan dukungan untuk memverifikasi alamat email baru: ketika pengguna memperbarui alamat emailnya, ia tidak akan mengganti alamat email lama sampai alamat email baru diverifikasi.
Laravel XSS Protection
: Laravel Middleware untuk melindungi aplikasi Anda dari skrip lintas situs (XSS). Ini membersihkan masukan permintaan, dan dapat mensanitasi pernyataan gema Blade.
Jika Anda menemukan masalah apa pun terkait keamanan, silakan kirim email ke [email protected] alih-alih menggunakan pelacak masalah. Harap jangan mengirim email pertanyaan apa pun, buka masalah jika Anda memiliki pertanyaan.
Pascal Baljet
Semua Kontributor
Lisensi MIT (MIT). Silakan lihat File Lisensi untuk informasi lebih lanjut.