I have been trying to transcode an existing video (let's call this input.mkv) to a new video file (output.mp4) in order to be able to send it over Facebook's messenger in the browser. So far, all my attempts are fruitless. Messenger and Messenger Lite for Android seem to recode the video correctly, but my reverse engineering skills are limited, or they use a special API endpoint which does not check for the video codec.

At first, I thought no audio stream was the problem, but I was previously able to send a video without an audio stream through Messenger. I even tried adding a silent audio stream without avail. Also, I'm not looking for copy codec because it is opposite to what I want to achieve.

I have read other threads, but don't seem to achieve much:

By downloading another video file from this service (let's call it sample.mp4) and observing the differences in ffprobe outputs, I can only conclude that the problem of the transcoded output.mp4 is that it has BT709 colorspace (as shown below). However, I can't say for sure if sample.mp4 also has BT709 color space, because there is no colorspace information (unknown) when I tried to get this information from it.

These are the ffprobe outputs:

  • This is my ffmpeg suite version:
ffmpeg version N-106460-g525049097c-20220330 Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 11.2.0 (crosstool-NG
  configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --disable-w32threads --enable-pthreads --enable-iconv --enable-libxml2 --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-lzma --enable-fontconfig --enable-libvorbis --enable-opencl --disable-libpulse --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-avisynth --enable-libdav1d --enable-libdavs2 --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libgme --enable-libass --enable-libbluray --enable-libmp3lame --enable-libopus --enable-librist --enable-libtheora --enable-libvpx --enable-libwebp --enable-lv2 --enable-libmfx --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --disable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc --enable-libplacebo --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-ldflags=-pthread --extra-ldexeflags= --extra-libs=-lgomp --extra-version=20220330
  • This is the format I'm trying to mimic:
E:\capture> ffprobe -hide_banner sample.mp4
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'sample.mp4':
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.20.100
  Duration: 00:00:41.23, start: 0.000000, bitrate: 408 kb/s
  Stream #0:0[0x1](und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(progressive), 1280x720 [SAR 1:1 DAR 16:9], 335 kb/s, 30 fps, 30 tbr, 15360 tbn (default)
      handler_name    : VideoHandler
      vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 64 kb/s (default)
      handler_name    : SoundHandler
      vendor_id       : [0][0][0][0]
  • This is the format of the input:
E:\capture> ffprobe input.mkv
Input #0, matroska,webm, from 'input.mkv':
    ENCODER         : Lavf59.20.101
  Duration: 00:01:28.01, start: 0.000000, bitrate: 194 kb/s
  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 1k tbn
      ENCODER         : Lavc59.25.100 libx264
      DURATION        : 00:01:28.000000000
  Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp
      title           : Track1
      DURATION        : 00:01:28.005000000

I have tried recoding using libx264 with various colorspace as well as profile and level options using this page as a reference on which values correspond to which colorspaces. I was even able to replicate the ffprobe output of sample.mp4, but still Messenger refuses to send my video file. I don't know if the resultant output.mp4 still has BT709 or contains another unsupported colorspace.

Here are the options that I have tried:

  • ffmpeg -i input.mkv -pix_fmt yuv420p output.mp4
  • ffmpeg -i input.mkv -profile:v main -pix_fmt yuv420p output.mp4
  • ffmpeg -i input.mkv -profile:v main -level:v 3.1 -pix_fmt yuv420p output.mp4
  • ffmpeg -i input.mkv -profile:v main -level:v 3.1 -pix_fmt yuv420p -color_range 0 -colorspace 2 -color_primaries 2 -color_trc 2 output.mp4 and various combination of these numbers.

I don't usually work with video files so my understanding is limited, so please bear with me.

EDIT 1: Suprisingly, extracting input.mkv into PNG frames and then reassembling them back works. However this method is messy, inefficient and time consuming as it could potentially generates a lot of files. It is certainly better if one could skip the frame generation altogether.

EDIT 2: With the above observation, I tried piping two ffmpeg processes:

  • First using raw video frame as intermediate format: ffmpeg -i input.mkv -f rawvideo -pix_fmt rgb24 - | ffmpeg -y -f rawvideo -video_size 1920x1080 -r 30 -pix_fmt rgb24 -i - -c:v libx264 -profile:v main -level:v 3.1 -pix_fmt yuv420p output.mp4
  • Then, using PNG as intermediate format: ffmpeg -i input.mkv -c:v png -f image2pipe - | ffmpeg -y -f image2pipe -vcodec png -r 30 -pix_fmt rgb24 -i - -c:v libx264 -profile:v main -level:v 3.1 -pix_fmt yuv420p output.mp4 These two commands doesn't work either.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.