edicleoberners / php-ffmpeg-video-streaming
📼 PHP FFMpeg - 视频流 - DASH, HLS http://video.aminyazdanpanah.com
Requires
- php: ^7.2 || ^8.0
- php-ffmpeg/php-ffmpeg: ^0.15 || 0.16 || 0.17 || 0.18 || 0.19
- symfony/filesystem: ^4.0 || ^5.0 || ^6.0
Requires (Dev)
- aws/aws-sdk-php: ^3.0@dev
- google/cloud-storage: dev-master
- microsoft/azure-storage-blob: dev-master
- phpunit/phpunit: ^8.4
Suggests
- aminyazdanpanah/handling-file-uploads: aminyazdanpanah/handling-file-uploads is suggested for uploading and validating a new video.
- aminyazdanpanah/php-shaka: aminyazdanpanah/php-shaka is suggested for using DRM and encryption
- aws/aws-sdk-php: Allow sending stream content to AWS services like S3
- google/cloud-storage: Allow sending stream content to Google services like Google Storage
- microsoft/azure-storage-blob: Allow sending stream content to Google services like Google Storage
- dev-master
- v1.2.15
- v1.2.14
- v1.2.12
- v1.2.11
- v1.2.9
- v1.2.7
- v1.2.0
- v1.1.58
- v1.1.56
- v1.1.55
- v1.1.54
- v1.1.53
- v1.1.51
- v1.1.50
- v1.1.49
- v1.1.48
- v1.1.47
- v1.1.46
- v1.1.45
- v1.1.44
- v1.1.43
- v1.1.42
- v1.1.41
- v1.1.39
- v1.1.38
- v1.1.37
- v1.1.36
- v1.1.35
- v1.1.34
- v1.1.33
- v1.1.32
- v1.1.31
- v1.1.30
- v1.1.29
- v1.1.28
- v1.1.27
- v1.1.26
- v1.1.25
- v1.1.24
- v1.1.23
- v1.1.22
- v1.1.21
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0
- dev-patch-1
- dev-renovate/pin-dependencies
- dev-add-code-of-conduct-1
This package is not auto-updated.
Last update: 2024-09-20 00:07:06 UTC
README
概述
这个库是围绕 PHP-FFMpeg 封装的,用于打包在线流媒体内容,如 DASH 和 HLS。您还可以使用 DRM 对 HLS 进行打包。还有多种选项可以从云端打开文件并将文件保存到云端。
内容
要求
安装
通过 composer 安装软件包
composer require aminyazdanpanah/php-ffmpeg-video-streaming
或者,直接将依赖项添加到您的 composer.json
文件中
"require": { "aminyazdanpanah/php-ffmpeg-video-streaming": "^1.2" }
快速入门
首先,您需要将软件包包含到您的代码中
require 'vendor/autoload.php'; // path to the autoload file
配置
此软件包将自动检测 FFmpeg 和 FFprobe 二进制文件。如果您想显式指定二进制路径,可以传递一个数组作为配置。还可以传递一个 Psr\Logger\LoggerInterface 以记录二进制执行。
use Monolog\Handler\StreamHandler; use Monolog\Logger; $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')); // path to log file $ffmpeg = Streaming\FFMpeg::create($config, $log);
打开资源
打开资源有几种方法。
1. 从 FFmpeg 支持的资源
您可以将视频(或支持的资源)的本地路径传递给 open
方法
$video = $ffmpeg->open('/var/media/video.mp4');
有关支持的资源(如 HTTP、FTP 等)的更多信息,请参阅 FFmpeg 协议文档
例如
$video = $ffmpeg->open('https://www.aminyazdanpanah.com/?"PATH TO A VIDEO FILE" or "PATH TO A LIVE HTTP STREAM"');
2. 从云端
您可以通过传递一个云配置数组到 openFromCloud
方法来从云端打开一个文件。
$video = $ffmpeg->openFromCloud($from_google_cloud);
访问 此页面 以查看从 Amazon S3、Google Cloud Storage、Microsoft Azure Storage 和自定义云打开文件的示例。
3. 捕获网络摄像头或屏幕(直播流)
您可以将支持并连接的捕获设备(例如网络摄像头的名称、相机、屏幕等)的名称传递给 capture
方法,通过网络进行直播媒体流。
$capture = $ffmpeg->capture("CAMERA NAME OR SCREEN NAME");
要列出支持的、已连接的捕获设备,请参阅 FFmpeg 捕获摄像头 和 FFmpeg 捕获桌面。
DASH
基于HTTP的动态自适应流(DASH),也称为 MPEG-DASH,是一种自适应比特率流技术,它使得通过传统的HTTP网络服务器在互联网上传输高质量媒体内容成为可能。 了解更多
创建 DASH 文件
$video->dash() ->x264() // Format of the video. Alternatives: hevc() and vp9() ->autoGenerateRepresentations() // Auto generate representations ->save(); // It can be passed a path to the method or it can be null
手动生成表示形式
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); $r_2k = (new Representation)->setKiloBitrate(6144)->setResize(2560, 1440); $r_4k = (new Representation)->setKiloBitrate(17408)->setResize(3840, 2160); $video->dash() ->x264() ->addRepresentations([$r_144p, $r_240p, $r_360p, $r_480p, $r_720p, $r_1080p, $r_2k, $r_4k]) ->save('/var/media/dash-stream.mpd');
请参阅文档中的 DASH 部分,以获取更多示例。
HLS
HTTP实时流(也称为HLS) 是苹果公司作为其 QuickTime、Safari、OS X 和 iOS 软件的一部分实现的一种基于 HTTP 的自适应比特率流通信协议。客户端实现也适用于 Microsoft Edge、Firefox 和一些版本的 Google Chrome。在流媒体服务器中支持广泛。 了解更多
创建 HLS 文件
$video->hls() ->x264() ->autoGenerateRepresentations([720, 360]) // You can limit the number of representatons ->save();
手动生成表示形式
use Streaming\Representation; $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() ->x264() ->addRepresentations([$r_360p, $r_480p, $r_720p]) ->save();
请参阅文档中的 HLS 部分,以获取更多示例,例如分段 MP4、来自摄像头/屏幕的实时流等。
加密(DRM)
加密过程需要某种形式的秘密(密钥)和加密算法。HLS 使用 AES 在密文块链(CBC)模式下。这意味着每个块都是使用前一个块的密文进行加密的。 了解更多
您必须指定一个路径以将随机密钥保存到您的本地机器上,并指定一个 URL(或路径)以在您的网站上访问密钥(您要保存的密钥必须可以从您的网站访问)。您必须将这两个参数传递给 encryption
方法
单个密钥
以下代码为所有段文件生成密钥。
//A path you want to save a random key to your local machine $save_to = '/home/public_html/"PATH TO THE KEY DIRECTORY"/key'; //An URL (or a path) to access the key on your website $url = 'https://www.aminyazdanpanah.com/?"PATH TO THE KEY DIRECTORY"/key'; // or $url = '/"PATH TO THE KEY DIRECTORY"/key'; $video->hls() ->encryption($save_to, $url) ->x264() ->autoGenerateRepresentations([1080, 480, 240]) ->save('/var/media/hls-stream.m3u8');
密钥轮换
可以将一个整数作为“密钥轮换周期”传递给 encryption
方法(即 encryption($save_to, $url, 10)
),为每个段集使用不同的密钥,在生成这么多段之后轮换到新密钥。例如,如果生成了 10 个段文件,那么将生成一个新的密钥。如果您将此值设置为 1
,则每个段文件都将使用新的加密密钥进行加密。这可以提高安全性并提供更大的灵活性。
请参阅 示例 以获取更多信息。
重要:在您的网站上保护您的密钥非常重要。例如,您可以使用令牌(使用 Get 或 Post HTTP 方法)检查用户是否有权访问密钥。您还可以在您的网站上使用会话(或cookie)来限制对密钥(强烈推荐)的访问。
DRM
然而,FFmpeg 支持 HLS 打包的 AES 加密,您可以加密内容,但这不是一个完整的 DRM 解决方案。如果您想使用完整的 DRM 解决方案,我建议尝试 FairPlay Streaming 解决方案,该方案可以安全地交换密钥,并保护设备上的播放。
除了 Apple的FairPlay 数字版权管理(DRM)系统外,您还可以使用其他DRM系统,例如 Microsoft的PlayReady 和 Google的Widevine。
字幕
您可以使用 subtitle
方法向HLS流添加字幕。
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');
注意:所有m3u8文件都将根据 RFC 8216 的规则生成。目前只接受 WebVTT 文件。
转码
一种格式也可以扩展 FFMpeg\Format\ProgressableInterface
以获取转码的实时信息。
$format = new Streaming\Format\X264(); $format->on('progress', function ($video, $format, $percentage){ // You can update a field in your database or can 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]", $percentage, str_repeat('#', $percentage), str_repeat('-', (100 - $percentage))); }); $video->dash() ->setFormat($format) ->autoGenerateRepresentations() ->save();
终端输出
保存文件
有多种保存文件的方式。
1. 保存到本地路径
您可以将本地路径传递给 save
方法。如果路径中没有目录,则该包会自动创建目录。
$dash = $video->dash() ->x264() ->autoGenerateRepresentations() $dash->save('/var/media/dash-stream.mpd');
它也可以是 null。保存文件的默认路径是输入路径。
$hls = $video->hls() ->x264() ->autoGenerateRepresentations(); $hls->save();
注意:如果您从云中打开文件而未传递将文件保存到本地计算机的路径,则必须在 save
方法中传递本地路径。
2. 保存到云
您可以通过将云配置数组传递给 save
方法来将文件保存到云。
$dash->save(null, [$to_aws_cloud, $to_google_cloud, $to_microsoft_azure, $to_custom_cloud]);
您也可以传递一个路径来将文件的副本保存到您的本地计算机。
$hls->save('/var/media/hls-stream.m3u8', [$to_google_cloud, $to_custom_cloud]);
访问 此页面 以查看将文件保存到 Amazon S3、Google Cloud Storage、Microsoft Azure Storage 和自定义云的一些示例。
注意:此选项(保存到云)仅适用于 VOD(它不支持直播)。
模式:关系是 一对一
3. 立即保存到服务器
您可以通过将URL(或支持的资源,如 FTP
)传递给直播方法,使用HTTP PUT方法将所有段文件上传到HTTP服务器(或其他协议),并在每次刷新时更新Manifest文件。
// DASH $dash->live('http://YOUR-WEBSITE.COM/live-stream/out.mpd'); // HLS $hls ->setMasterPlaylist('/var/www/stream/live-master-manifest.m3u8') ->live('http://YOUR-WEBSITE.COM/live-stream/out.m3u8');
注意:在HLS格式中,您必须手动上传主播放列表到服务器。(将 /var/www/stream/live-master-manifest.m3u8
文件上传到 http://YOUR-WEBSITE.COM
)
有关更多信息,请参阅 FFmpeg协议文档。
元数据
您可以使用以下代码从多媒体流和视频文件中获取信息。
$hls = $hls->save(); $metadata = $hls->metadata()->export(); print_r($metadata);
有关更多信息,请参阅 示例。
转换
您可以将流转换为文件或将流转换为其他流协议。您应将流的Manifest传递给 open
方法
1. HLS到DASH
$stream = $ffmpeg->open('https://www.aminyazdanpanah.com/?PATH/TO/HLS-MANIFEST.M3U8'); $stream->dash() ->x264() ->addRepresentations([$r_360p, $r_480p]) ->save('/var/media/dash-stream.mpd');
2. DASH到HLS
$stream = $ffmpeg->open('https://www.aminyazdanpanah.com/?PATH/TO/DASH-MANIFEST.MPD'); $stream->hls() ->x264() ->autoGenerateRepresentations([720, 360]) ->save('/var/media/hls-stream.m3u8');
3. 流(DASH或HLS)到文件
$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');
其他高级功能
您可以轻松使用 PHP-FFMpeg 库中的其他高级功能。实际上,当您使用 open
方法(或 openFromCloud
)打开文件时,它持有属于PHP-FFMpeg的Media对象。
$ffmpeg = Streaming\FFMpeg::create(); $video = $ffmpeg->openFromCloud($from_cloud, '/var/media/new/video.mp4');
提取图像
您可以使用 FFMpeg\Media\Video::frame
方法在任何时间码提取帧。
$frame = $video->frame(FFMpeg\Coordinate\TimeCode::fromSeconds(42)); $frame->save('/var/media/poster.jpg');
注意:您可以将图像用作视频的海报。
Gif
Gif是从视频序列中提取的动画图像。
您可以使用 FFMpeg\Media\Gif::save
方法保存gif文件。
$video ->gif(FFMpeg\Coordinate\TimeCode::fromSeconds(2), new FFMpeg\Coordinate\Dimension(640, 480), 3) ->save('/var/media/animated_image.gif');
此方法有一个可选的第三个布尔参数,即动画的持续时间。如果您不设置它,您将得到一个固定的GIF图像。
注意:您可以使用GIF作为视频的缩略图。
要查看更多示例,请访问 PHP-FFMpeg 文档 页面。
异步任务执行
打包过程可能需要一段时间,建议在后台(或云中,例如AWS)运行。有一些库可以用于此用途。
-
Symphony(控制台组件):您可以使用此库创建命令行命令。您的控制台命令可用于任何重复性任务,例如cron作业、导入或其他批处理作业。了解更多
-
Laravel(队列):如果您使用Laravel进行开发,Laravel队列是此用途的绝佳工具。它允许您创建一个作业并调度它。了解更多
注意:您还可以创建一个脚本并在cron作业中运行它。
多个开源播放器
您可以使用这些库来播放您的流。
- WEB
- DASH和HLS
- DASH
- HLS
- Android
- DASH和HLS
- ExoPlayer(推荐)
- Android的VLC
- DASH和HLS
- IOS
- DASH
- HLS
- Android和IOS
- DASH和HLS
- Windows、Linux和macOS
- DASH和HLS
常见问题解答
我已经创建了流文件,现在我应该向播放器传递什么?您必须向播放器传递一个主播放列表(manifest)URL(例如 https://www.aminyazdanpanah.com/?"PATH TO STREAM DIRECTORY"/dash-stream.mpd
或 /PATH_TO_STREAM_DIRECTORY/hls-stream.m3u8
)。有关更多信息,请参阅这些播放器的演示页面(hls.js 演示,dash.js 演示,videojs 演示 等)。
我的播放器没有显示视频质量选择按钮来更改视频质量?一些播放器没有内置的视频质量选择按钮来更改此选项,您应该安装(或添加)用于此用途的插件。例如,如果您使用Videojs播放流,您可以安装 videojs-hls-quality-selector 以显示质量选择器。对于其他播放器,您可以通过Google轻松找到插件!
我已经将流文件上传到云中,但它在网站上无法播放?如果您将流内容保存到云中(例如 Amazon S3),请确保您的内容是公开的。如果不是,您必须更改访问控制。
IOS是否支持DASH流? 不,IOS没有原生支持DASH。尽管有一些库,例如Viblast和MPEGDASH-iOS-Player支持这种技术,但我从未测试过它们。所以可能有些不会正常工作。
有关更多常见问题,请参阅此页面。
贡献和报告错误
我很乐意得到您的帮助来改进、纠正或添加规范。请提交一个问题或提交一个pull请求。
致谢
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。