Komplette Video-Streaming-Lösung mit DASH- und HLS-Unterstützung, DRM-Verschlüsselung und Cloud-Speicher-Integration
DASH & HLS mit adaptiver Bitrate
PHP FFmpeg Video Streaming ist ein umfassender Wrapper um PHP-FFMpeg, der FFmpeg nutzt, um Medienpakete zu erstellen, die mit Online-Streaming-Protokollen wie DASH (Dynamic Adaptive Streaming over HTTP) und HLS (HTTP Live Streaming) kompatibel sind.
Erstellen Sie DASH- und HLS-Streams mit mehreren Bitraten-Repräsentationen
AES-128-Verschlüsselung für HLS mit Schlüsselrotationsoptionen
Direkte Integration mit S3, Google Cloud, Azure und mehr
Unterstützung für Live-Streaming von Webcams und Bildschirmaufnahmen
Diese Bibliothek erfordert eine funktionierende FFmpeg-Installation, einschließlich der Binärdateien von FFMpeg und FFProbe.
Kompatibilität: Diese Bibliothek ist nur mit PHP 8.2 oder höher kompatibel.
Mit Composer:
composer require aminyazdanpanah/php-ffmpeg-video-streaming
Alternativ können Sie die Abhängigkeit zu Ihrer composer.json-Datei hinzufügen:
{
"require": {
"aminyazdanpanah/php-ffmpeg-video-streaming": "^1.2"
}
}
Dieses Paket erkennt FFmpeg- und FFprobe-Binärdateien automatisch. Wenn Sie Binärpfade explizit angeben möchten, können Sie ein Array als Konfiguration übergeben. Eine Psr\Logger\LoggerInterface kann auch übergeben werden, um Binärausführungen zu protokollieren.
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Streaming\FFMpeg;
$config = [
'ffmpeg.binaries' => '/usr/bin/ffmpeg',
'ffprobe.binaries' => '/usr/bin/ffprobe',
'timeout' => 3600, // The timeout for the underlying process
'ffmpeg.threads' => 12, // The number of threads that FFmpeg should use
];
$log = new Logger('FFmpeg_Streaming');
$log->pushHandler(new StreamHandler('/var/log/ffmpeg-streaming.log'));
$ffmpeg = FFMpeg::create($config, $log);
require 'vendor/autoload.php'; // path to the autoload file
Es gibt mehrere Möglichkeiten, eine Medienressource zu öffnen:
$video = $ffmpeg->open('/var/media/video.mp4');
Für entfernte Ressourcen:
$video = $ffmpeg->open('https://www.quasarstream.com/?path/to/video.mp4');
$video = $ffmpeg->openFromCloud($from_google_cloud);
$capture = $ffmpeg->capture("CAMERA NAME OR SCREEN NAME");
Dynamic Adaptive Streaming over HTTP (DASH), auch bekannt als MPEG-DASH, ermöglicht hochwertiges Streaming über das Internet, indem Inhalte in kurze HTTP-basierte Datei-Downloads segmentiert werden.
Die Bibliothek generiert automatisch Manifest (MPD)- und Segmentdateien:
$video->dash()
->setAdaption('id=0,streams=v id=1,streams=a')
->x264()
->autoGenerateRepresentations()
->save();
use Streaming\Representation;
$r_144p = (new Representation)->setKiloBitrate(95)->setResize(256, 144);
$r_240p = (new Representation)->setKiloBitrate(150)->setResize(426, 240);
$r_360p = (new Representation)->setKiloBitrate(276)->setResize(640, 360);
$r_480p = (new Representation)->setKiloBitrate(750)->setResize(854, 480);
$r_720p = (new Representation)->setKiloBitrate(2048)->setResize(1280, 720);
$r_1080p = (new Representation)->setKiloBitrate(4096)->setResize(1920, 1080);
$video->dash()
->setSegDuration(30)
->setAdaption('id=0,streams=v id=1,streams=a')
->x264()
->addRepresentations([$r_144p, $r_240p, $r_360p, $r_480p, $r_720p, $r_1080p])
->save('/var/media/dash-stream.mpd');
$r_240p = (new Representation)->setKiloBitrate(150)->setResize(426, 240);
$r_360p = (new Representation)->setKiloBitrate(276)->setResize(640, 360);
$capture->dash()
->setAdaption('id=0,streams=v id=1,streams=a')
->x264()
->addRepresentations([$r_240p, $r_360p])
->save('/var/media/dash-stream.mpd');
autoGenerateRepresentations()
kann nicht für kamerabasierte Medien verwendet werden.
HTTP Live Streaming (HLS) ist ein adaptives Bitraten-Streaming-Protokoll, das HTTP-basierte Datei-Downloads und M3U-Playlists verwendet.
Um HLS-Dateien zu erstellen, verwenden Sie die <code class="inline-code">hls</code>-Instanz und geben Sie den Ausgabedateinamen an:
$video->hls()
->x264()
->autoGenerateRepresentations([720, 360])
->save();
Um die genaue Kilobit-Rate und Größe für jeden Stream festzulegen, erstellen Sie manuell Representation-Objekte und fügen Sie sie der dash- oder hls-Instanz hinzu:
$r_360p = (new Representation)->setKiloBitrate(276)->setResize(640, 360);
$r_480p = (new Representation)->setKiloBitrate(750)->setResize(854, 480);
$r_720p = (new Representation)->setKiloBitrate(2048)->setResize(1280, 720);
$video->hls()
->setHlsBaseUrl('https://bucket.s3-us-west-1.amazonaws.com/videos')
->setHlsTime(5)
->setHlsAllowCache(false)
->x264()
->addRepresentations([$r_360p, $r_480p, $r_720p])
->save();
Für das fragmentierte MP4-Format in HLS verwenden Sie die <code class="inline-code">fragmentedMP4</code>-Methode:
$video->hls()
->fragmentedMP4()
->x264()
->autoGenerateRepresentations([720, 360])
->save();
Für Live-Streaming von einer Kamera oder einem Bildschirm verwenden Sie die <code class="inline-code">hls</code>-Instanz und geben Sie den Ausgabedateinamen an:
$r_480p = (new Representation)->setKiloBitrate(750)->setResize(854, 480);
$capture->hls()
->setHlsListSize(10) // Delete this line if you want to save video after live streaming
->setFlags([\Streaming\HLSFlag::DELETE_SEGMENTS]) // Delete this line if you want to save video after live streaming
->x264()
->addRepresentation($r_480p)
->save('/var/media/hls-stream.m3u8');
autoGenerateRepresentations()
kann nicht für kamerabasierte Medien verwendet werden. HEVC- und VP9-Formate werden für HLS-Packaging nicht unterstützt, es sei denn, Sie verwenden fragmentiertes MP4.
HLS-Verschlüsselung verwendet den Advanced Encryption Standard (AES) im Cipher Block Chaining (CBC)-Modus. Das bedeutet, dass jeder Block mit dem Chiffriertext des vorherigen Blocks verschlüsselt wird. Mehr erfahren
Der folgende Code generiert einen einzigen Schlüssel für alle Segmente:
//A path you want to save a random key to your local machine
$save_to = '/home/public_html/PATH_TO_KEY_DIRECTORY/key';
//A URL (or a path) to access the key on your website
$url = 'https://www.quasarstream.com/?PATH_TO_KEY_DIRECTORY/key';
// or $url = '/PATH_TO_KEY_DIRECTORY/random_key.key';
$video->hls()
->encryption($save_to, $url)
->x264()
->autoGenerateRepresentations([1080, 480, 240])
->save('/var/media/hls-stream.m3u8');
Sie können die Verschlüsselungsschlüssel optional regelmäßig rotieren, indem Sie einen "Schlüsselrotationszeitraum" an die Verschlüsselungsmethode übergeben. Dadurch wird nach einer bestimmten Anzahl von Segmenten ein neuer Schlüssel generiert:
//A path you want to save a random key to your local machine
$save_to = '/home/public_html/PATH_TO_KEY_DIRECTORY/key';
//A URL (or a path) to access the key on your website
$url = 'https://www.quasarstream.com/?PATH_TO_KEY_DIRECTORY/key';
$video->hls()
->encryption($save_to, $url, 10) // New key every 10 segments
->x264()
->autoGenerateRepresentations([720, 240])
->save('/var/media/hls-stream.m3u8');
Es ist entscheidend, Ihre Verschlüsselungsschlüssel auf Ihrer Website zu sichern:
Sie können Untertitel zu HLS-Streams hinzufügen, indem Sie die subtitle-Methode verwenden:
use Streaming\HLSSubtitle;
$persian = new HLSSubtitle('/var/subtitles/subtitles_fa.vtt', 'فارسی', 'fa');
$persian->default();
$english = new HLSSubtitle('/var/subtitles/subtitles_en.vtt', 'english', 'en');
$german = new HLSSubtitle('/var/subtitles/subtitles_de.vtt', 'Deutsch', 'de');
$chinese = new HLSSubtitle('/var/subtitles/subtitles_zh.vtt', '中文', 'zh');
$spanish = new HLSSubtitle('/var/subtitles/subtitles_es.vtt', 'Español', 'es');
$video->hls()
->subtitles([$persian, $english, $german, $chinese, $spanish])
->x264()
->autoGenerateRepresentations([1080, 720])
->save('/var/media/hls-stream.m3u8');
Ein Format kann FFMpeg\Format\ProgressableInterface
erweitern, um Echtzeit-Informationen über den Transkodierungsprozess zu erhalten:
$format = new Streaming\Format\X264();
$start_time = 0;
$percentage_to_time_left = function ($percentage) use (&$start_time) {
if($start_time === 0){
$start_time = time();
return "Calculating...";
}
$diff_time = time() - $start_time;
$seconds_left = 100 * $diff_time / $percentage - $diff_time;
return gmdate("H:i:s", $seconds_left);
};
$format->on('progress', function ($video, $format, $percentage) use($percentage_to_time_left) {
// You can update a field in your database or log it to a file
// You can also create a socket connection and show a progress bar to users
echo sprintf("\rTranscoding...(%s%%) %s [%s%s]",
$percentage,
$percentage_to_time_left($percentage),
str_repeat('#', $percentage),
str_repeat('-', (100 - $percentage))
);
});
$video->dash()
->setFormat($format)
->autoGenerateRepresentations()
->setAdaption('id=0,streams=v id=1,streams=a')
->save();
Sie können den Ausgabeort festlegen, indem Sie einen lokalen Pfad übergeben. Wenn das Verzeichnis nicht existiert, erstellt die Bibliothek es automatisch:
$dash = $video->dash()
->x264()
->autoGenerateRepresentations()
->setAdaption('id=0,streams=v id=1,streams=a');
$dash->save('/var/media/dash/test.mpd');
Wenn Sie den save-Parameter weglassen, werden die Dateien im selben Verzeichnis wie die Eingabedatei gespeichert:
$hls = $video->hls()
->x264()
->autoGenerateRepresentations();
$hls->save();
Speichern Sie gepackte Dateien direkt in Cloud-Speicher-Anbietern (nur Video-on-Demand):
$dash->save(null, [$to_aws_cloud]);
$hls->save('/var/media/hls.m3u8', [$to_google_cloud, $to_custom_cloud]);
Eine Illustration des End-to-End-Prozesses.
Cloud
Lokal
Cloud
Lokal
Laden Sie segmentierte Dateien hoch und aktualisieren Sie Manifestdateien direkt auf einem HTTP-Server:
// DASH
$dash->live('http://YOUR-WEBSITE.COM/live-stream/out.mpd');
// HLS
$hls->setMasterPlaylist('/var/media/live-master-manifest.m3u8')
->live('http://YOUR-WEBSITE.COM/live-stream/out.m3u8');
Informationen aus Multimedia-Streams und Videodateien abrufen:
$hls = $hls->save();
$metadata = $hls->metadata();
print_r($metadata->get()); // print an array
$metadata->saveAsJson('path/to/meta.json'); // save metadata as JSON
var_dump($metadata->getVideoStreams()); // StreamCollection object
var_dump($metadata->getFormat()); // Format object
echo gmdate("H:i:s", intval($metadata->getFormat()->get('duration'))); // duration
Konvertieren Sie zwischen verschiedenen Streaming-Formaten, indem Sie eine Manifest-URL an die input-Methode übergeben:
$stream = $ffmpeg->open('https://www.quasarstream.com/?PATH/TO/HLS-MANIFEST.M3U8');
$stream->dash()
->x264()
->addRepresentations([$r_360p, $r_480p])
->save('/var/media/dash-stream.mpd');
$stream = $ffmpeg->open('https://www.quasarstream.com/?PATH/TO/DASH-MANIFEST.MPD');
$stream->hls()
->x264()
->autoGenerateRepresentations([720, 360])
->save('/var/media/hls-stream.m3u8');
$format = new Streaming\Format\X264();
$format->on('progress', function ($video, $format, $percentage){
echo sprintf("\rTranscoding...(%s%%) [%s%s]",
$percentage,
str_repeat('#', $percentage),
str_repeat('-', (100 - $percentage))
);
});
$stream->stream2file()
->setFormat($format)
->save('/var/media/new-video.mp4');
Sie können andere erweiterte Funktionen der PHP-FFMpeg-Bibliothek nutzen. Die open-Methode enthält das Media-Objekt von PHP-FFMpeg:
Einen Frame zu einem beliebigen Zeitpunkt extrahieren:
$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(42));
$frame->save('/var/media/poster.jpg');
Animierte Bilder aus Videosequenzen erstellen:
$video->gif(
FFMpeg\Coordinate\TimeCode::fromSeconds(2),
new FFMpeg\Coordinate\Dimension(640, 480),
3 // duration in seconds
)
->save('/var/media/animated_image.gif');
Für Produktionsumgebungen sollten Sie die Packaging-Prozesse im Hintergrund ausführen:
Empfohlene Open-Source-Player für die Wiedergabe von gepackten Videos:
Plattform | Player | Unterstützte Formate |
---|---|---|
Android | AndroidX Media | DASH & HLS |
iOS | Native Player | HLS |
Windows/Linux/macOS | FFmpeg (ffplay), VLC media player | DASH & HLS |
Wenn Sie dieses Projekt nützlich finden, unterstützen Sie uns bitte: