Search code examples
node.jsubuntudockerffmpegfluent-ffmpeg

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


I am currently working on a project and almost ready to deploy, but there is one problem: the code which is working perfectly on my Ubuntu 16.04 (Elementary OS Loki) machine does not work in Docker container. What might be the problem in my code?

Here is my Dockerfile:

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 run sudo docker exec -it <container-name> ffmpeg --help and it outputs the expected help print. In my code, I download a Youtube video in mp4 format with this code:

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

And then try to process the video with 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)
    }
  })
)

It gives the following error:

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.

Solution

  • To go into more detail this excerpt from your console output/log explains the reason why it failed:

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

    Your ffmpeg was old, as you already found out. Using the outdated ffmpeg would have required -strict -2 (or the alias -strict experimental) to encode using the built-in FFmpeg AAC encoder, but your command was lacking this.

    Eventually the AAC encoder was improved and the experimental status was removed. Using a recent version allows you to encode AAC without -strict. See the FFmpeg Download page for links to already compiled recent builds of ffmpeg for Linux, macOS, and Windows.

    For more info see FFmpeg Wiki: AAC.