PHP-FFMpeg:如何正确连接两个视频?

时间:2018-10-01 14:59:24

标签: php laravel laravel-5 ffmpeg php-ffmpeg

情况:

我需要将多个视频连接为一个视频。
我正在使用库PHP-FFMpeg
但是我无法使其正常工作。

视频:

视频是使用MediaRecorder Web API录制的。
视频格式为:video/webm;codecs=h264 音频格式为opus

recorder = new MediaRecorder(this.stream, {
  mimeType: 'video/webm;codecs=h264'
})

使用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'

使用FFMPEG命令行进行匹配:

关于@RolandStarke和@LordNeckbeard的建议,我尝试使用ffmpeg command line来更好地了解正在发生的事情。

如果我使用以下命令行:

ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

我收到与音频作品编解码器有关的以下错误。

enter image description here

如果我使用以下命令行,则将编码的音频转换为acc

ffmpeg -f concat -safe 0 -i mylist.txt -c:v copy -c:a aac output.mp4

最终视频已正确创建,并与其他视频串联在一起。

使用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 /后端/ camera-laravel / storage / app / public / videos /output.mp4'

使用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

使用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连接视频?

问题是由于编码错误引起的吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

遇到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 < / p>

调试此命令有点困难,因为当您尝试在终端中执行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

因此,您遇到的错误是输出文件已经存在。解决方案是在连接视频之前使用其他不存在的输出文件或将其删除。

下面是一个如何串联文件的示例(来自http://techslides.com/sample-webm-ogg-and-mp4-video-files-for-html5的small.mp4)

<?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);

答案 1 :(得分:1)

正确的答案是来自@RolandStarke的答案。
在这里,我只想汇总一些建议,这些建议对于调试与ffmpeg有关的其他类似问题可能很有用:

  1. 重新安装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或只是将其搜索出来。

  2. 尝试执行与尝试执行的操作相同的操作,但只能使用ffmpeg命令行。它将提供更多的见解和更好的错误报告。例如concat:

    ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

  3. 检查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');

  4. 仔细检查每个路径。对于concat,请确保输出文件尚不存在。

  5. 可能是编码问题。尝试使用其他编解码器的其他类型的文件,看是否确实是问题所在。如果您可以事先转换为适当的编解码器。

  6. 在源代码中添加换行符。就我而言,我得到了一般错误: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);

  7. 最后这是PHP-FFMpeg的类似问题列表,您可以检查是否已经给出解决方案:https://github.com/pascalbaljetmedia/laravel-ffmpeg/wiki/FFmpeg-failed-to-execute-command

如果您有其他建议,请随时评论或编辑答案。