php - PHP-FFMpeg:如何正确连接两个视频?
问题描述
情况:
我需要它将多个视频连接成一个视频。
我正在使用库PHP-FFMpeg。
但我无法让它发挥作用。
视频:
这些视频是使用MediaRecorder Web API录制的。
视频格式为:video/webm;codecs=h264
音频格式为opus
.
recorder = new MediaRecorder(this.stream, {
mimeType: 'video/webm;codecs=h264'
})
CONCAT 使用 PHP-FFMPEG(使用 saveFromSameCodecs):
这就是我尝试使用它们连接它们的方式saveFromSameCodecs
:(
我已经检查了路径并且是正确的)
$video = $ffmpeg->open( $path1 );
$video
->concat([$path1, $path2])
->saveFromSameCodecs($path_output, TRUE);
但它失败并显示以下错误消息:
ffmpeg 无法执行命令 '/usr/local/bin/ffmpeg' '-f' 'concat' '-safe' '0' '-i' '/private/var/folders/dw/919v2nds7s78pz_qhp7z9rcm0000gn/T/ffmpeg-concath1kHiX ''-c''复制''/Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/storage/app/public/videos/output.mp4'
使用 FFMPEG 命令行连接:
根据@RolandStarke 和@LordNeckbeard 的建议,我尝试使用ffmpeg 命令行来更好地了解正在发生的事情。
如果我使用以下命令行:
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
我收到以下错误,与音频作品编解码器有关。
如果我使用以下命令行,将音频编码转换为acc
:
ffmpeg -f concat -safe 0 -i mylist.txt -c:v copy -c:a aac output.mp4
最终视频已正确创建,作为其他视频的串联。
CONCAT 使用 PHP-FFMPEG:(使用 saveFromDifferentCodecs)
似乎问题仅与编解码器有关。所以我尝试使用saveFromDifferentCodecs
:
$format = new FFMpeg\Format\Video\X264('libfdk_aac', 'libx264');
$result = $video1
->concat([$path1, $path2])
->saveFromDifferentCodecs($format, $output_path);
但我仍然得到一个错误:
ffmpeg 无法执行命令'/usr/local/bin/ffmpeg''-i''/Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/storage/app/public/videos/test1.mp4 ''-i''/Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/storage/app/public/videos/test2.mp4''-filter_complex''[0:v:0] [ 0:a:0] [1:v:0] [1:a:0] concat=n=2:v=1:a=1 [v] [a]' '-map' '[v]' ' -map''[a]''-b:a''128k''/Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/storage/app/public/videos/output.mp4'
CONCAT 使用 PHPFFMPEG(但使用不同的视频):
如果问题仅与编解码器有关,那么将两个不同的视频与
video codec:h264
和 audio codec一起使用aac
,
它应该可以工作,但不能:
ffmpeg failed to execute command '/usr/local/bin/ffmpeg' '-f' 'concat' '-safe' '0' '-i' '/private/var/folders/dw/919v2nds7s78pz_qhp7z9rcm0000gn/T/ffmpeg-concatoJGhLt' '-c' 'copy' '/Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/storage/app/public/videos/output.mp4'
但是使用命令行它可以顺利运行:ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
使用 shell_exec 连接:
我曾尝试使用 shell_exec,前两个视频(作品编解码器):
echo shell_exec("/usr/local/bin/ffmpeg -f concat -safe 0 -i /Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/mylist.txt -c:v copy -c:a aac /Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/output.mp4 2>&1");
它运行顺利。创建最终输出,并使用 acc 音频编解码器。
测试库:
为了查看 php-mpeg 是否实际工作,我通过对视频进行基本调整大小来测试它,它工作正常。
恢复:
- 使用 ffmpeg 命令行一切正常
- 使用 shell_exec 一切正常
- 使用 php-ffmpeg 我总是得到错误
ffmpeg failed to execute command
问题:
如何使用 php-ffmpeg 连接视频?
问题是由错误的编码引起的吗?
谢谢!
解决方案
当遇到 php-ffmpeg 的问题时,最好的方法是从错误消息中复制命令并将其粘贴到终端中。这将为您提供更好的错误消息。
在你的情况下,错误是
ffmpeg 无法执行命令 '/usr/local/bin/ffmpeg' '-f' 'concat' '-safe' '0' '-i' '/private/var/folders/dw/919v2nds7s78pz_qhp7z9rcm0000gn/T/ffmpeg-concath1kHiX ''-c''复制''/Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/storage/app/public/videos/output.mp4
当您尝试在终端中执行 ffmpeg 命令时,临时文件/private/var/[...]/ffmpeg-concath1kHiX会被删除,因此调试起来有点困难。要对其进行测试,您可以自己创建临时文件,例如:
$vidoes = [__DIR__ . '/small.mp4', __DIR__ . '/small.mp4'];
file_put_contents('videolist.txt', implode("\n", array_map(function ($path) {
return 'file ' . addslashes($path);
}, $vidoes)));
现在您可以在终端中运行 ffmpeg 命令
ffmpeg -f concat -safe 0 -i videolist.txt -c copy /Users/[...]/videos/output.mp4
#[...]
#File '/Users/[...]/videos/output.mp4' already exists. Overwrite ? [y/N]
#Not overwriting - exiting
所以你的情况是错误是输出文件已经存在。解决方案是使用其他不存在的输出文件或在连接视频之前将其删除。
这是一个如何连接文件的示例(small.mp4 取自http://techslides.com/sample-webm-ogg-and-mp4-video-files-for-html5)
<?php
require 'vendor/autoload.php';
$ffmpeg = FFMpeg\FFMpeg::create();
$video = $ffmpeg->open(__DIR__ . '/small.mp4');
$video
->concat([__DIR__ . '/small.mp4', __DIR__ . '/small.mp4'])
->saveFromSameCodecs(__DIR__ . '/out-'. time() . '.mp4', true);
推荐阅读
- java - 如何将异常类型与其消息分开
- c# - Retrieve Value From Nested Json
- vue.js - 如何将 axios 全局导入到 vue.js 项目中
- django - Django select option - displaying image in template
- spring-security - Communication between two microservices in JHipster using JWT
- sql - Query to display student_no, prj_name and prj_dur
- c++ - 如何制作arduino串行循环(连续接收数字)
- vim - How to match the white space between two strings in vim?
- java - ListView crashes
- ios - iOS Simulator connection timed out