Docker 容器中的 Ffmpeg 错误:ffmpeg 已退出,代码为 1:

Ffmpeg error in Docker Container: ffmpeg exited with code 1:

我目前正在做一个项目,几乎可以部署了,但是有一个问题:在我的 Ubuntu 16.04(初级 OS Loki)机器上运行良好的代码没有在 Docker 容器中工作。我的代码可能有什么问题?

这是我的Docker文件:

FROM beevelop/nodejs-python:latest

RUN apt-get -y update && apt-get install -y libav-tools
RUN ffmpeg --help

# Global install yarn package manager
RUN apt-get update && apt-get install -y curl apt-transport-https && \
    curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
    echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
    apt-get update && apt-get install -y yarn

WORKDIR /app
COPY package.json .
RUN yarn
COPY . .
RUN yarn prod:build
EXPOSE 8080
CMD [ "yarn", "start" ]

I 运行 sudo docker exec -it <container-name> ffmpeg --help 并输出预期的帮助打印。在我的代码中,我使用以下代码下载了一个 mp4 格式的 Youtube 视频:

const download = idParam => (
  new Promise((fulfill, reject) => {
    const id = `http://www.youtube.com/watch?v=${idParam}`
    let videoMeta
    youtubedl(id, ['--format=36'], { cwd: __dirname })
      .on('info', (info) => {
        const customDimensions = calculateCustomDimensions(info.format)
        videoMeta = { ...info, ...customDimensions }
      })
      .pipe(fs.createWriteStream(`temp/${idParam}.mp4`))
      .on('finish', () => {
        console.log('Dirname: ', __dirname)
        fulfill(videoMeta)
      })
      .on('error', (err) => {
        console.log('There is an error:', err)
        console.log('Dirname: ', __dirname)
        reject(err)
      })
  })
)

然后尝试使用 fluent-ffmpeg 处理视频:

const processVideo = (videoName, cropStart, cropEnd) => (
  new Promise((resolve, reject) => {
    try {
      console.log('Trying to run ffmpeg binary.')
      ffmpeg()
        .addInput(`temp/${videoName}.mp4`)
        .seekInput(cropStart)
        .duration(cropEnd)
        .outputOption('-movflags frag_keyframe+faststart')
        .on('end', () => {
          console.log('Processing has finished with ffmpeg. ')
          console.log('Resolved for upload: ', [`temp/cropped_${videoName}.mp4`, `temp/${videoName}.mp4`])
          console.log('Going out of processVideo script.')
          resolve([`temp/cropped_${videoName}.mp4`, `temp/${videoName}.mp4`])
        })
        .on('error', (err, stdout, stderr) => {
          console.log('Error. Output option olmasına rağmen: ', err.message)
          console.log('ffmpeg output:\n', stdout)
          console.log('ffmpeg stderr:\n', stderr)
        })
        .save(`temp/cropped_${videoName}.mp4`)
    } catch (e) {
      console.log('There has been an error while converting ffmpeg binary!')
      console.log(e.msg)
      console.log(e.code)
      reject(e)
    }
  })
)

它给出了以下错误:

Entering download script.
WARNING: Assuming --restrict-filenames since file system encoding cannot encode all characters. Set the LC_ALL environment variable to fix this.

`info.resolution` is deprecated, use `info.format`
Dirname:  /app/lib/server/scripts
Download script is done.
Custom dimensions of the downloaded video:  320 180
Crop start and end of the downloaded video:  00:00:00.517 00:00:00.998
Entering processVideo script.
Trying to run ffmpeg binary.
Error:  ffmpeg exited with code 1: 
ffmpeg output:

ffmpeg stderr:
 ffmpeg version 2.8.11-0ubuntu0.16.04.1 Copyright (c) 2000-2017 the FFmpeg developers
  built with gcc 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 20160609
  configuration: --prefix=/usr --extra-version=0ubuntu0.16.04.1 --build-suffix=-ffmpeg --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --cc=cc --cxx=g++ --enable-gpl --enable-shared --disable-stripping --disable-decoder=libopenjpeg --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxvid --enable-libzvbi --enable-openal --enable-opengl --enable-x11grab --enable-libdc1394 --enable-libiec61883 --enable-libzmq --enable-frei0r --enable-libx264 --enable-libopencv
  libavutil      54. 31.100 / 54. 31.100
  libavcodec     56. 60.100 / 56. 60.100
  libavformat    56. 40.101 / 56. 40.101
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 40.101 /  5. 40.101
  libavresample   2.  1.  0 /  2.  1.  0
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.101 /  1.  2.101
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'temp/kfchvCyHmsc.mp4':
  Metadata:
    major_brand     : 3gp6
    minor_version   : 256
    compatible_brands: isom3gp6
    creation_time   : 2015-03-26 09:22:44
  Duration: 00:00:08.27, start: 0.000000, bitrate: 218 kb/s
    Stream #0:0(und): Video: mpeg4 (Simple Profile) (mp4v / 0x7634706D), yuv420p, 320x180 [SAR 1:1 DAR 16:9], 187 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 24k tbc (default)
    Metadata:
      creation_time   : 2015-03-26 09:22:44
      handler_name    : IsoMedia File Produced by Google, 5-11-2011
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 22050 Hz, mono, fltp, 31 kb/s (default)
    Metadata:
      creation_time   : 2015-03-26 09:22:44
      handler_name    : IsoMedia File Produced by Google, 5-11-2011
[libx264 @ 0x2641fc0] using SAR=1/1
[libx264 @ 0x2641fc0] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 AVX2 LZCNT BMI2
[libx264 @ 0x2641fc0] profile High, level 1.2
[libx264 @ 0x2641fc0] 264 - core 148 r2643 5c65704 - H.264/MPEG-4 AVC codec - Copyleft 2003-2015 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=23 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
[aac @ 0x2642f00] The encoder 'aac' is experimental but experimental codecs are not enabled, add '-strict -2' if you want to use it.

我刚刚发现我机器上的两个版本的 ffmpeg 和 Docker 是不同的。将Docker中的那个升级到3.3.4,解决了!

要更详细地了解您控制台的这段摘录 output/log 解释了它失败的原因:

[aac @ 0x2642f00] The encoder 'aac' is experimental but experimental codecs are not enabled, add '-strict -2' if you want to use it.

您的 ffmpeg 已经过时了,您已经发现了。使用过时的 ffmpeg 需要 -strict -2(或别名 -strict experimental)使用内置的 FFmpeg AAC 编码器进行编码,但您的命令缺少这个。

最终改进了 AAC 编码器,experimental status was removed. Using a recent version allows you to encode AAC without -strict. See the FFmpeg Download 页面链接到已编译的 ffmpeg 的最新版本,适用于 Linux、macOS 和 Windows。

有关详细信息,请参阅 FFmpeg Wiki: AAC