danjones000 / ffmpeg-mappable-media
php-ffmpeg/php-ffmpeg 的插件,提供对输入文件到输出文件映射的更高级控制
Requires
- php: ^8.0
- php-ffmpeg/php-ffmpeg: ^1.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.0
- pestphp/pest: ^1.20
- psy/psysh: ^0.11.8
- spatie/ray: ^1.28
This package is auto-updated.
Last update: 2024-09-11 09:02:30 UTC
README
Mappable Media 是一个针对 PHP-FFMpeg 的插件,它提供了一种将输入文件的单个流映射到输出文件的机制。
它提供了比内置的 AdvancedMedia 插件更高级的针对特定编解码器和元数据的控制。
安装
您可以通过 composer 安装此包
composer require danjones000/ffmpeg-mappable-media
用法
use Danjones\FFMpeg\MappableMedia;
use FFMpeg\FFMpeg;
$ffmpeg = FFMpeg::create();
$media = MappableMedia::make($ffmpeg);
$media->addInput('video.mp4');
$media->addInput('audio.opus');
$media->addInput('sub.srt');
$output1 = $media->map();
$output1->saveAs('no-subs.webm');
$output1->metadata('title', 'The Greatest Stury Ever Hulaed');
$stream1 = $output1->stream();
$stream1->setInput('0:0');
$stream1->video('libvp9');
$stream1->saveStream();
$stream2 = $output1->stream();
$stream2->setInput('1:0');
$stream2->copy();
$stream2->saveStream();
$output1->saveMap();
$output2 = $media->map();
$output2->saveAs('all-copy.mkv');
// Most methods return the object that calls them.
$output2->stream()->setInput('0:0')->copy()->saveStream();
$output2->stream()->setInput('1:0')->copy()->saveStream();
$output2->stream()->setInput('2:0')->copy()->metadata('language', 'eng')->saveStream();
$output2->saveMap();
$media->save();
saveStream
方法返回创建它的 Map
对象。同样,saveMap
返回创建它的 MappableMedia
对象。所有其他方法都是可链的。
因此,这可以写成一个非常长的单个调用,如下所示
MappableMedia::make($ffmpeg)
->addInput('video.mp4')
->addInput('audio.opus')
->addInput('sub.srt')
->map()
->saveAs('no-subs.webm')
->metadata('title', 'The Greatest Story Ever Hulaed')
->stream()->setInput('0:0')->video('libvp9')->saveStream()
->stream()->setInput('1:0')->copy()->saveStream()
->saveMap()
->map()
->saveAs('all-copy.mkv')
->stream()->setInput('0:0')->copy()->saveStream()
->stream()->setInput('1:0')->copy()->saveStream()
->stream()->setInput('2:0')->copy()->metadata('language', 'eng')->saveStream()
->saveMap()
->save()
这两个调用都会执行以下命令
ffmpeg -y -i video.mp4 -i audio.opus -i sub.srt -map 0:0 -c:0 libvp9 -map 1:0 -c:1 copy -metadata title="The Greatest Story Ever Hulaed" no-subs.webm -map 0:0 -c:0 copy -map 1:0 -c:1 copy -map 2:0 -c:2 copy -metadata:s:2 language=eng all-copy.mkv
这将生成两个文件。第一个将是 webm 文件(适用于在浏览器中播放),文件中的 title
字段设置为 "The Greatest Story Ever Hulaed"。第二个文件将直接复制每个文件中的第一个流,并将字幕流的语言设置为英语。
使用 FormatInterface
您还可以使用 PHP-FFMPEG 中的 Formats 从流中设置编解码器。
use FFMpeg\Format\Video\X264;
MappableMedia::make($ffmpeg)
->addInput('input.mkv')
->map()
->saveAs('output.mkv')
->stream()->setCodec(new X264())->saveStream()
->saveMap()
->save()
使用回调
map
和 stream
方法可以接受一个可选的回调,允许您设置这些单个对象的属性。当传递回调时,对象本身被返回,允许您继续链式调用。
MappableMedia::make($ffmpeg)
->addInput('input.mkv')
->map(function (Map $map) {
$map->saveAs('output.mkv')
->stream(function (Stream $stream) {
$stream->copy()->setInput('0:0');
});
})->save()
请注意,在使用回调时,您也不需要调用 saveMap()
或 saveStream()
。
获取进度更新
您可以使用 Format 类在单个流上设置监听器。然而,这并不能可靠地报告特定流的进度。因此,这个包在 MappableMedia
对象本身上添加了一个监听器,该对象代表整个任务的进度。
MappableMedia::make($ffmpeg)
->addInput('input.mkv')
->map()
->saveAs('output.mkv')
->stream()->copy()->saveStream()
->saveMap()
->on('progress', function (MappableMedia $media, int $percent, int $remaining, int $rate) {
echo "Finished {$percent}% of ", $media->getPathfile(), "\n";
})
->save()
附件
某些格式(例如 mkv)支持任意数据附件。这些可以用于封面艺术、字幕的字体或任何任意数据。
FFMpeg 支持将附件作为额外的输入。这对于图像来说效果很好,但对于其他文件类型可能会很棘手。因此,FFMpeg 还支持一个 -attach
标志,可以用来显式附加一个新的流。
由于 FFMpeg 以不同的方式处理 -attach
和 -i
,这些需要被添加到特定映射中的流,而不是整个媒体。以下是一些示例。
MappableMedia::make($ffmpeg)
->addInput('input.mkv')
->map()
->saveAs('output.mkv')
->stream()->copy()->saveStream()
->attach('image.jpg')
->mime('image/jpeg')
->addMetadata('filename', 'cover.jpg')
->saveAttachment()
->saveMap()
->save();
在这个例子中,我们向文件中添加了封面艺术。请注意使用 mime
方法指定 MIME 类型。**这必须始终这样做**。注意,我们还指定了一个不同的文件名,这样媒体播放器就会将其识别为封面艺术。如果您不指定文件名,将使用原始文件。
MappableMedia::make($ffmpeg)
->addInput('input.mkv')
->addInput('subs.ass')
->map()
->saveAs('output.mkv')
->stream()->copy()->saveStream()
->stream()->setInput('1:0')->copy()->saveStream()
->attach(verdana.ttf')
->mime('application/x-truetype-font')
->saveAttachment()
->saveMap()
->save();
在这个例子中,我们添加了一个字体,这很可能是字幕文件 subs.ass
中引用的。
未来计划
- [ ] 添加返回所有 stdin/stderr 的监听器
- [ ] 支持输入的 itsoffset
- [ ] 支持使用 -t 和 -ss
- 我需要弄清楚这将如何影响进度监听器。
贡献
请参阅CONTRIBUTING以获取详细信息。
致谢
许可证
MIT许可证(MIT)。请参阅许可证文件以获取更多信息。