ffmpegvp9

How to make ffmpeg re-encode an vp9 webm with alpha into a vp9 webm with alpha


I am trying to find optimal parameters for encoding a transparent video using ffmpeg in my scenario, and as a test, I have been re-encoding a pre-made transparent .webm (vp9 with alpha channel, made using python vidgear) like this:

$ /usr/bin/ffmpeg -i pre-made.webm pre-made-remade.webm
ffmpeg version 4.3.2-0york0~18.04 Copyright (c) 2000-2021 the FFmpeg developers
  built with gcc 7 (Ubuntu 7.5.0-3ubuntu1~18.04)
  configuration: --prefix=/usr --extra-version='0york0~18.04' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp
--enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libzimg --enable-pocketsphinx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared
  libavutil      56. 51.100 / 56. 51.100
  libavcodec     58. 91.100 / 58. 91.100
  libavformat    58. 45.100 / 58. 45.100
  libavdevice    58. 10.100 / 58. 10.100
  libavfilter     7. 85.100 /  7. 85.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  7.100 /  5.  7.100
  libswresample   3.  7.100 /  3.  7.100
  libpostproc    55.  7.100 / 55.  7.100
Input #0, matroska,webm, from 'pre-made.webm':
  Metadata:
    ENCODER         : Lavf58.45.100
  Duration: 00:01:11.04, start: 0.000000, bitrate: 1107 kb/s
    Stream #0:0: Video: vp9 (Profile 0), yuv420p(tv), 1514x1910, SAR 1:1 DAR 757:955, 25 fps, 25 tbr, 1k tbn, 1k tbc (default)
    Metadata:
      alpha_mode      : 1
      ENCODER         : Lavc58.91.100 libvpx-vp9
      DURATION        : 00:01:11.040000000
Stream mapping:
  Stream #0:0 -> #0:0 (vp9 (native) -> vp9 (libvpx-vp9))
Press [q] to stop, [?] for help
[libvpx-vp9 @ 0x55927254b0c0] v1.7.0
[libvpx-vp9 @ 0x55927254b0c0] Neither bitrate nor constrained quality specified, using default CRF of 32
Output #0, webm, to 'pre-made-remade.webm':
  Metadata:
    encoder         : Lavf58.45.100
    Stream #0:0: Video: vp9 (libvpx-vp9), yuv420p, 1514x1910 [SAR 1:1 DAR 757:955], q=-1--1, 25 fps, 1k tbn, 25 tbc (default)
    Metadata:
      alpha_mode      : 1
      DURATION        : 00:01:11.040000000
      encoder         : Lavc58.91.100 libvpx-vp9
    Side data:
      cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
frame= 1776 fps=8.9 q=0.0 Lsize=    6159kB time=00:01:11.00 bitrate= 710.6kbits/s speed=0.354x
video:6146kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.214488%

According to the ffmpeg logs, the libvpx-vp9 is correctly being chosen, and alpha_mode is 1, which bodes well. However, when actually viewing the video, the video is no longer trasparent.

How could I force ffmpeg to keep the alpha channel when re-encoding the video? (This also applies when trying to merge audio into the .webm)

Bonus question: what arguments do you recommend for efficient vp9 encoding? I have tried using -threads 16 -speed 4 -tile-columns 6 -frame-parallel 1 -row-mt 1 but it seems to fail at fully utilizing all my CPU cores when encoding with the alpha channel (when piping frames from my python script).


Solution

  • See the line

    Stream #0:0: Video: vp9 (Profile 0), yuv420p(tv) ...
    

    The yuv420p indicates that ffmpeg hasn't detected alpha in the input, else it would be yuva420p. To export alpha from VP9 streams, you need to use libvpx decoders, so

    ffmpeg -c:v libvpx-vp9 -i pre-made.webm ...