Ошибка ffmpeg в aws lambda

Я пытаюсь создать функцию перекодирования для коротких видеороликов. Функция размещена на AWS Lambda. Проблема в том, что AWS lambda, похоже, не хватает чего-то, что требуется для FFMPEG, по крайней мере, согласно Amazon.

Я связывался с Amazon ранее, и вот их ответ на проблему:

We found that the FFMPEG operations require at least libx264 and an acc library, both of which will have dependencies of their own. To troubleshoot the issue it will involve diving deeper into the full dependency chain. We can see that it works in the Amazon Linux environment however, the environment is similar but not identical to the lambda environment. There can be some dependencies that exist in Amazon Linux but not in lambda environment as Lambda runs on the container. Here, as FFmpeg is a third party software, diving deeper into the dependency chain and verifying the version compatibilities is very hard to do. Unfortunately going further, this is bound to go into architecture and code support which is out of AWS Support scope 1. I hope you understand our limitations. However should FFmpeg support have any questions specific to the Lambda platform, please do let us know and we will be happy to assist. We will be in better position to investigate further once you receive an update from the FFmpeg support suggesting an issue from Lambda end.

По предложению AWS я связался с FFMPEG в списке рассылки разработчиков, мое сообщение было отклонено по той причине, что он больше подходит для списка рассылки пользователей ffmpeg, чем разработчиков. Я отправил письмо на адрес «ffmpeg-user@ffmpeg.org» неделю назад и пока не получил никакого ответа.

Затем я построил динамически скомпонованную версию ffmpeg, убедившись, что упаковал все библиотеки, проверил ddl на каждой, затем сделал небольшую лямбда-функцию, которая перебирала все двоичные файлы и запускала каждую из них, по сравнению с выводом, который я получил от Amazon. Linux и те же зависимости / версии существуют как для лямбда-выражения, так и для экземпляра AWS Linux, но ffmpeg по-прежнему не работает на лямбда-выражении.

Вы можете найти подробный файл журнала здесь: https://www.datafilehost.com/d/6e5e21bb

И это образец ошибок, которые я получаю, повторяющиеся во всем файле журнала:

2018-08-14T12:27:10.874Z [h264 @ 0x65c2fc0] concealing 2628 DC, 2628 AC, 2628 MV errors in P frame

2018-08-14T12:27:10.874Z [aac @ 0x65d2f00] channel element 2.11 is not allocated

2018-08-14T12:27:10.874Z Error while decoding stream #0:1: Invalid data found when processing input

2018-08-14T12:27:10.874Z [h264 @ 0x67e86c0] Invalid NAL unit size (108085662 > 1649).

2018-08-14T12:27:10.874Z [h264 @ 0x67e86c0] Error splitting the input into NAL units.

2018-08-14T12:27:10.874Z [aac @ 0x65d2f00] channel element 2.0 is not allocated

2018-08-14T12:27:10.874Z Error while decoding stream #0:1: Invalid data found when processing input

2018-08-14T12:27:10.874Z [h264 @ 0x68189c0] Invalid NAL unit size (71106974 > 1085).

2018-08-14T12:27:10.874Z [h264 @ 0x68189c0] Error splitting the input into NAL units.

2018-08-14T12:27:10.874Z [aac @ 0x65d2f00] Pulse tool not allowed in eight short sequence.

Этот журнал создается при попытке выполнить транскодирование HLS для этого файла: https://www.datafilehost.com/d/999a4492

Обратите внимание, что проблема не связана только с этим файлом и не связана с HLS, его общим и случается со всеми видео и любой командой ffmpeg, которая пытается искать поток, даже пыталась извлечь один кадр из видео, используя простейшую возможную форму. например: ffmpeg -ss 00:00:02 -I file.mp4 -vframes 1 -y output.jpg также не работает с теми же ошибками в файле журнала.

Не знаю, как отлаживать это дальше. Пытался включить журналы отладки с помощью «-loglevel debug», но не дал мне никакой дополнительной информации. Любая помощь или предложения

Он работает нормально, когда вы не ищете?

Gyan 10.09.2018 09:32

Кроме того, вы получили ответ на ffmpeg-user, но не отслеживали: lists.ffmpeg.org/pipermail/ffmpeg-user/2018-September/…

Gyan 10.09.2018 09:34

@Gyan Единственное, что работает нормально, это вызов ffmpeg -i file.mp4, когда все попытки прочитать видео терпят неудачу.

Zaid Amir 10.09.2018 10:10

Как исходный файл фактически попадает в контейнер Lambda? Передается ли он в полезной нагрузке запроса на вызов? Если это так, вы можете его повредить, если не передаете его как base64. Lambda API - это JSON, который не поддерживает произвольные двоичные данные, и все, что в полезной нагрузке не является допустимым utf-8, почти наверняка будет приведено к utf-8 с заменой � (U + FFFD / hex 0xEF 0xBF 0xBD) вместо байтов, которые не являются действительными действительными символами. Использование base64 для двоичной полезной нагрузки позволяет избежать этого. Ошибки создают впечатление поврежденных данных, а не проблемы зависимости.

Michael - sqlbot 10.09.2018 11:20

@ Michael-sqlbot файл загружается и сохраняется на диске лямбды. Сначала я думал то же самое, но при вычислении MD5 загруженного файла его правильно. В дополнение к MD5 я попытался повторно загрузить файл на S3 после его загрузки, и двоичный файл был сохранен.

Zaid Amir 10.09.2018 15:12

У меня здесь точно такая же проблема.

derekhh 18.02.2019 09:33
9
6
2 153
3

Ответы 3

Если у вас проблемы с ffmpeg, попробуйте вместо этого avconv. avconv является форком ffmpeg и может вызываться таким же образом. У меня были те же проблемы, что и с ffmpeg, при попытке декодировать аудиопоток aac в среде лямбда, но статическая сборка avconv от Джона Ван Сикла работала для меня, как и ожидалось.

Кроме того, убедитесь, что для лямбда-функции выделено достаточно оперативной памяти. Статические двоичные файлы ffmpeg велики, и для кодирования требуется много оперативной памяти, особенно если вы кодируете видео.

Может быть, ваш ffmpeg был древним.

llogan 26.11.2018 20:04

@LordNeckbeard: я использовал ffmpeg 4.1, который был выпущен менее месяца назад (статическая сборка Джона ван Сикла) и который отлично работает на моей локальной машине debian.

faxi 27.11.2018 21:11

Итак, 4.1 нормально работала с тем же входным файлом на вашей локальной машине debian, но та же версия не работала на лямбде? Было бы неплохо разобраться в этом.

llogan 27.11.2018 22:04

Да, в самом деле. С тем же статическим двоичным файлом ffmpeg 4.1 и тем же входным файлом преобразование из aac в wav не удается на Lambda, но работает на моей локальной машине Debian. И если я заменю ffmpeg статической сборкой avconfig 12.1 (снова статическая сборка Джона ван Сикла), тогда у меня не будет никаких проблем с Lambda. Мне также интересно, как мы можем понять, что там не так.

faxi 30.11.2018 00:09

Вы пробовали использовать статически скомпилированный ffmpeg?

Вот что у меня сработало:

  1. Взял статическую сборку ffmpeg от https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz
  2. Извлечено и отброшено все, кроме самого двоичного файла ffmpeg. chmod этот двоичный файл, чтобы разрешить выполнение и помещенный в bin/ffmpeg внутри папки развертывания (в моем случае папка будет заархивирована и развернута zappa)
  3. Скопировал двоичный файл ffmpeg внутри /tmp. (У меня возникла ошибка «операция не разрешена» при выполнении ffmpeg из /var/task/bin, мои знания о самом ffmpeg ограничены, но я предполагаю, что ffmpeg будет создавать временные файлы во время обработки, а поскольку лямбда имеет файловую систему только для чтения, это можно сделать только внутри /tmp, в моем случае конвертирую caf в mp4)
  4. Добавлен /tmp в пути поиска, поэтому ffmpeg будет доступен по пути. (требуется при использовании некоторых сторонних разработчиков, которые инкапсулируют вызовы ffmpeg внутри, например pydub)

Вот соответствующий код Python, поскольку лямбда-контейнеры будут использоваться повторно, /tmp может уже содержать скопированный ffmpeg.

from os import environ, path
from shutil import copy2

# check if we have ffmpeg inside /tmp, if we do, no need to copy
# otherwise copy ffmpeg from /var/task/bin to /tmp
if environ.get('AWS_EXECUTION_ENV', '').startswith('AWS_Lambda_') and not path.isfile('/tmp/ffmpeg'):
    copy2(path.join(PROJECT_ROOT, 'bin/ffmpeg'), '/tmp/ffmpeg')

# add /tmp to search paths if it's not there
# so ffmpeg executed from pydub will be found
custom_deps_bin_path = '/tmp/'
if environ.get('AWS_EXECUTION_ENV', '').startswith('AWS_Lambda_') and custom_deps_bin_path not in environ['PATH']:
    environ['PATH'] += ":" + custom_deps_bin_path

Также для этого есть несколько соответствующих сторонних организаций:

  1. бинокль / aws-lambda-ffmpeg
  2. ubergarm / zappa-ffmpeg

Сегодня я столкнулся с той же проблемой и потратил несколько часов. Но в конце концов я наткнулся на этот ТАК ответ и нашел решение.

В основном вам нужно убедиться, что вы не передаете STDIN процессу FFmpeg. Это упоминается в re: Invent talk на этом слайде.

Другие вопросы по теме