PHP-FFMpeg:如何正确连接两个视频?
PHP-FFMpeg: How to properly concatenate two videos?
情况:
我需要它将多个视频连接成一个视频。
我正在使用库 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' 'copy' '/Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/storage/app/public/videos/output.mp4'
CONCAT 使用 FFMPEG 命令行:
关于@RolandStarke 和@LordNeckbeard 的建议,我尝试使用 ffmpeg command line 来更好地了解正在发生的事情。
如果我使用以下命令行:
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
我收到以下错误,与 audio opus 编解码器有关。
如果我使用以下命令行,将音频编码转换为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(但视频不同):
如果问题仅与编解码器有关,则使用两个不同的视频与
视频编解码器:h264
和音频编解码器 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
CONCAT 使用 shell_exec:
我已经尝试使用 shell_exec,前两个视频(opus 编解码器):
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' 'copy' '/Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/storage/app/public/videos/output.mp4
调试这有点困难,因为临时文件 /private/var/[...]/ffmpeg-concath1kHiX 在您尝试执行 ffmpeg 命令时被删除在终端。要测试它,您可以自己创建临时文件,例如:
$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);
正确答案来自@RolandStarke。
在这里我只是想整理一个建议列表,这些建议可能对调试处理 ffmpeg 的其他类似问题有用:
重新安装 ffmpeg。它可能是缺少选项或缺少编解码器。以下是安装方法(针对 mac),包括所有可能的选项(2018 年 9 月)。我花了 30 分钟所以请耐心等待。
brew install ffmpeg --with-chromaprint --with-fdk-aac --with-fontconfig --with-freetype --with-frei0r --with-game-music-emu --with-libass --with-libbluray --with-libbs2b --with-libcaca --with-libgsm --with-libmodplug --with-librsvg --with-libsoxr --with-libssh --with-libvidstab --with-libvorbis --with-libvpx --with-opencore-amr --with-openh264 --with-openjpeg --with-openssl --with-opus --with-rtmpdump --with-rubberband --with-sdl2 --with-snappy --with-speex --with-srt --with-tesseract --with-theora --with-tools --with-two-lame --with-wavpack --with-webp --with-x265 --with-xz --with-zeromqlibzeromq --with-zimg
要获得更新的选项列表,您可以 运行: brew options ffmpeg
或 google 它。
尝试做你正在尝试做的同样的事情,但只使用 ffmpeg 命令行。它将更有洞察力和更好的错误报告。例如对于连接:
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
检查 PHP-FFMpeg 是否正常工作。 Concat 是有点难度的操作。您可以尝试使用更简单的一个,看看它是否正常工作以及库是否已正确安装。例如你可以尝试一个简单的转换:
FFMpeg::fromDisk('local')
->open('public/videos/test.mp4')
->export()
->toDisk('local')
->inFormat(new FFMpeg\Format\Video\X264('libmp3lame', 'libx264'))
->save('public/videos/converted_test.mp4');
仔细检查每条路径。在 concat 的情况下,确保输出文件不存在。
可能是编码问题。尝试使用不同编解码器的其他类型的文件,看看这是否真的是问题所在。如果您可以事先转换为正确的编解码器。
在源代码中添加换行符。在我的例子中,我得到了一般错误:Unable to save concatenated video
。这是源代码:
try {
$this->driver->command($commands);
} catch (ExecutionFailureException $e) {
$this->cleanupTemporaryFile($outputPathfile);
$this->cleanupTemporaryFile($sourcesFile);
throw new RuntimeException('Unable to save concatenated video', $e->getCode(), $e);
}
但如果我转储执行然后将其终止,就在该块之前:
dd($this->driver->command($commands));
它给了我更详细的错误信息。
您还可以转储命令数组:dd($commands);
最后这里有一个与 PHP-FFMpeg 类似的问题列表,您可以查看是否已经给出了解决方案:https://github.com/pascalbaljetmedia/laravel-ffmpeg/wiki/FFmpeg-failed-to-execute-command
如果您有其他建议,请随时发表评论或编辑答案。
情况:
我需要它将多个视频连接成一个视频。
我正在使用库 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' 'copy' '/Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/storage/app/public/videos/output.mp4'
CONCAT 使用 FFMPEG 命令行:
关于@RolandStarke 和@LordNeckbeard 的建议,我尝试使用 ffmpeg command line 来更好地了解正在发生的事情。
如果我使用以下命令行:
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
我收到以下错误,与 audio opus 编解码器有关。
如果我使用以下命令行,将音频编码转换为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(但视频不同):
如果问题仅与编解码器有关,则使用两个不同的视频与
视频编解码器:h264
和音频编解码器 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
CONCAT 使用 shell_exec:
我已经尝试使用 shell_exec,前两个视频(opus 编解码器):
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' 'copy' '/Users/francescomussi/Desktop/Apps/cameraProject/back-end/camera-laravel/storage/app/public/videos/output.mp4
调试这有点困难,因为临时文件 /private/var/[...]/ffmpeg-concath1kHiX 在您尝试执行 ffmpeg 命令时被删除在终端。要测试它,您可以自己创建临时文件,例如:
$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);
正确答案来自@RolandStarke。
在这里我只是想整理一个建议列表,这些建议可能对调试处理 ffmpeg 的其他类似问题有用:
重新安装 ffmpeg。它可能是缺少选项或缺少编解码器。以下是安装方法(针对 mac),包括所有可能的选项(2018 年 9 月)。我花了 30 分钟所以请耐心等待。
brew install ffmpeg --with-chromaprint --with-fdk-aac --with-fontconfig --with-freetype --with-frei0r --with-game-music-emu --with-libass --with-libbluray --with-libbs2b --with-libcaca --with-libgsm --with-libmodplug --with-librsvg --with-libsoxr --with-libssh --with-libvidstab --with-libvorbis --with-libvpx --with-opencore-amr --with-openh264 --with-openjpeg --with-openssl --with-opus --with-rtmpdump --with-rubberband --with-sdl2 --with-snappy --with-speex --with-srt --with-tesseract --with-theora --with-tools --with-two-lame --with-wavpack --with-webp --with-x265 --with-xz --with-zeromqlibzeromq --with-zimg
要获得更新的选项列表,您可以 运行:
brew options ffmpeg
或 google 它。尝试做你正在尝试做的同样的事情,但只使用 ffmpeg 命令行。它将更有洞察力和更好的错误报告。例如对于连接:
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4
检查 PHP-FFMpeg 是否正常工作。 Concat 是有点难度的操作。您可以尝试使用更简单的一个,看看它是否正常工作以及库是否已正确安装。例如你可以尝试一个简单的转换:
FFMpeg::fromDisk('local') ->open('public/videos/test.mp4') ->export() ->toDisk('local') ->inFormat(new FFMpeg\Format\Video\X264('libmp3lame', 'libx264')) ->save('public/videos/converted_test.mp4');
仔细检查每条路径。在 concat 的情况下,确保输出文件不存在。
可能是编码问题。尝试使用不同编解码器的其他类型的文件,看看这是否真的是问题所在。如果您可以事先转换为正确的编解码器。
在源代码中添加换行符。在我的例子中,我得到了一般错误:
Unable to save concatenated video
。这是源代码:try { $this->driver->command($commands); } catch (ExecutionFailureException $e) { $this->cleanupTemporaryFile($outputPathfile); $this->cleanupTemporaryFile($sourcesFile); throw new RuntimeException('Unable to save concatenated video', $e->getCode(), $e); }
但如果我转储执行然后将其终止,就在该块之前:
dd($this->driver->command($commands));
它给了我更详细的错误信息。
您还可以转储命令数组:
dd($commands);
最后这里有一个与 PHP-FFMpeg 类似的问题列表,您可以查看是否已经给出了解决方案:https://github.com/pascalbaljetmedia/laravel-ffmpeg/wiki/FFmpeg-failed-to-execute-command
如果您有其他建议,请随时发表评论或编辑答案。