2

THE SITUATION:

I need it to concatenate multiple videos into one single video.
I am using the library PHP-FFMpeg.
But I don't manage to make it working.

THE VIDEOS:

The videos are recordings made with the MediaRecorder Web API.
The video format is: video/webm;codecs=h264 The audio format is opus.

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

CONCAT USING PHP-FFMPEG (using saveFromSameCodecs):

This is how I try to concat them using saveFromSameCodecs:
(I have checked the paths and are correct)

$video = $ffmpeg->open( $path1 );
$video
    ->concat([$path1, $path2])
    ->saveFromSameCodecs($path_output, TRUE);

But it failed with the following error message:

ffmpeg failed to execute command '/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 USING FFMPEG COMMAND LINE:

On suggestion on @RolandStarke and @LordNeckbeard I have tried using the ffmpeg command line to get a better insight on what is going on.

If I use the following command line:

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

I get the following error, related to the audio opus codec.

enter image description here

If I use the following command line, converting the audio coded to acc:

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

The final video is properly created, as a concatenation of the other videos.

CONCAT USING PHP-FFMPEG: (using saveFromDifferentCodecs)

It seems the problem is ONLY related to the codec. So I have tried using saveFromDifferentCodecs:

$format = new FFMpeg\Format\Video\X264('libfdk_aac', 'libx264');

$result = $video1
    ->concat([$path1, $path2])
    ->saveFromDifferentCodecs($format, $output_path);

But I still get an error:

ffmpeg failed to execute command '/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 USING PHPFFMPEG (but with different videos):

If the problem is only related to the codec, then using two different videos with
video codec: h264 and audio codec aac,
it should work, but it doesn't:

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'

But using the command line it works smoothly: ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

CONCAT USING shell_exec:

I have tried using shell_exec, with the first two videos (opus codec):

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

And it works smoothly. The final output is created, and with the acc audio codec.

TESTING THE LIBRARY:

To see if php-mpeg was actually working, I test it by making a basic resize of a video and it worked correctly.

RESUME:

  • Using ffmpeg command lines everything works fine
  • Using shell_exec everything works fine
  • Using php-ffmpeg I always get the error ffmpeg failed to execute command

QUESTION:

How can I concat videos using php-ffmpeg?

Is the issue caused by wrong encoding?

Thanks!

FrancescoMussi
  • 20,760
  • 39
  • 126
  • 178
  • Are you running this on a live web server or on a local OS such as Mac OS? – Gaz Jones Oct 01 '18 at 15:07
  • At the moment I am testing it on localhost - Mac OS. – FrancescoMussi Oct 01 '18 at 15:09
  • Yes I believe so. I keep open the finder while running the command. I see a temp folder being created, and soon removed after about 1sec. After that I see the error appear. – FrancescoMussi Oct 01 '18 at 15:14
  • 2
    I would test if other commands work. like the first example on basic usage. – Roland Starke Oct 01 '18 at 15:22
  • Good suggestion! I will try it – FrancescoMussi Oct 01 '18 at 15:23
  • It is possible that the script isn't executable? You could always try reinstalling it using composer? I've also just asked a colleague of mine, he says that this can be to do with the version of PHP you are using - which version of PHP are you using? – Gaz Jones Oct 01 '18 at 15:36
  • @RolandStarke I have tried a basic resizing and conversion and it worked fine. Probably it has to do with some small details. I will check more and in case edit the question. – FrancescoMussi Oct 01 '18 at 15:57
  • Thanks @GarethJones. Php version is 7.2.9. FFMpeg should work fine. About the script non executable I am not sure. I think it should. – FrancescoMussi Oct 01 '18 at 15:58
  • 1
    @FrancescoMussi just to update... i get the same error on windows... lets see – Roland Starke Oct 01 '18 at 16:40
  • thank you very much for testing @RolandStarke! And that's actually a bad news :( I would prefer I was missing something in the code... – FrancescoMussi Oct 01 '18 at 16:51
  • I'm not sure if ffmpeg even executed, but if it did the log from that command will be helpful. Did you try running the resulting ffmpeg command unscripted, in a command-line interface before trying to script it? – llogan Oct 01 '18 at 18:21
  • @RolandStarke I have completely edit the question, including several tests with different codecs, using command line, and shell_exec. – FrancescoMussi Oct 02 '18 at 12:56

2 Answers2

2

When encountering issues with php-ffmpeg the best approach is to copy the command from the error message and paste it in terminal. This will give you a better error message.

In your case the the error is

ffmpeg failed to execute command '/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

Debugging this is a bit harder as the temp file /private/var/[...]/ffmpeg-concath1kHiX is deleted when you try to execute the ffmpeg command in the terminal. To test it you can create the temp file yourself like:

$vidoes = [__DIR__ . '/small.mp4', __DIR__ . '/small.mp4'];

file_put_contents('videolist.txt', implode("\n", array_map(function ($path) {
    return 'file ' . addslashes($path);
}, $vidoes)));

Now you can run the ffmpeg command in the terminal

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

So you your case the error is that the output file already existed. The solution is to use an other non-existing output file or delete it before concatenating your videos.

Here an example how to concatenate files (small.mp4 taken from 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);
Roland Starke
  • 1,658
  • 1
  • 14
  • 19
  • Another way to deal with an existing output file (using the `ffmpeg` cli tool) is to automatically overwrite it with the `-y` option (or use the opposite option `-n` to automatically exit if output exists). – llogan Oct 03 '18 at 19:06
  • @LordNeckbeard the `-n` it's a very useful flag. Good suggestion! – FrancescoMussi Oct 03 '18 at 19:44
1

The correct answer is the one from @RolandStarke.
Here I just want to put together a list of suggestions that may be useful to debug other similar problems in dealing with ffmpeg:

  1. Make a reinstall of ffmpeg. It may be a missing option or a missing codec. Here is how to install (for mac), including all possible options (september 2018). It took me 30minutes so be patient.

    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

    To have the updated options list you can run: brew options ffmpeg or just google it.

  2. Try to do the same thing you are trying to do, but using the ffmpeg command line only. It will more insight and a better error reporting. For example for concat:

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

  3. Check that PHP-FFMpeg is properly working. Concat it's a bit more difficult operation. You can try with a simpler one and see if it's working and if the library is properly installed. For example you can try a simple conversion:

    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. Double check every path. And in the case of concat, make sure the output file doesn't already exists.

  5. It may be an encoding problem. Try other types of files with different codecs to see if that's actually the issue. In case you can convert beforehand to the proper codec.

  6. Add line breaks in the source code. In my case I was getting the generic error: Unable to save concatenated video. Here is the source code:

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

    But if I dump the execution and then die it, right before that block:

    dd($this->driver->command($commands));

    It was giving me a more detailed error message.

    You can also dump the commands array: dd($commands);

  7. Finally here is a list of similar issue with PHP-FFMpeg that you can check to see if the solution has already been given: https://github.com/pascalbaljetmedia/laravel-ffmpeg/wiki/FFmpeg-failed-to-execute-command

If you have other suggestions feel free to comment or edit the answer.

FrancescoMussi
  • 20,760
  • 39
  • 126
  • 178