PHP-FFMpeg: Как правильно объединить два видео? - PullRequest
0 голосов
/ 01 октября 2018

СИТУАЦИЯ:

Мне нужно, чтобы объединить несколько видео в одно видео.
Я использую библиотеку 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 / folder / 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 , чтобы лучше понять, что такоепродолжается.

Если я использую следующую командную строку:

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

Я получаю следующую ошибку, связанную с audio opus codec .

enter image description here

Если я использую следующую командную строку, преобразование звука, закодированного в 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 '' / Пользователи / francescomussi / Рабочий стол / Приложения / 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 (нос разными видео):

Если проблема связана только с кодеком, то используйте два разных видео с
видеокодеком: h264 и аудиокодеком aac,
itдолжно работать, но это не так:

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 USING 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 голосов
/ 04 октября 2018

Правильный ответ от @RolandStarke.
Здесь я просто хочу собрать список предложений, которые могут быть полезны для устранения других подобных проблем при работе с ffmpeg:

  1. Выполните переустановку ffmpeg.Это может быть отсутствующий параметр или отсутствующий кодек.Вот как установить (для Mac), включая все возможные варианты (сентябрь 2018).Мне потребовалось 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 работает правильно.Конкат это немного более сложная операция.Вы можете попробовать более простой и посмотреть, работает ли он и правильно ли установлена ​​библиотека.Например, вы можете попробовать простое преобразование:

    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

Если у вас есть другие предложения, не стесняйтесь комментировать или редактировать ответ.

0 голосов
/ 03 октября 2018

При возникновении проблем с php-ffmpeg лучше всего скопировать команду из сообщения об ошибке и вставить ее в терминал.Это даст вам лучшее сообщение об ошибке.

В вашем случае ошибка:

ffmpeg не удалось выполнить команду '/ usr / local / bin / ffmpeg' '-f''concat' '-safe' '0' '-i' '/ private / var / folder / dw / 919v2nds7s78pz_qhp7z9rcm0000gn / T / ffmpeg-concath1kHiX' '-c' 'copy' '/ Пользователи / francescomussi / Рабочий стол / 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);
...