FFmpeg collection and memo.

🌵 Install

This is the simplest and least error-prone method to install ffmpeg.

Get builds from FFmpeg.ory, and set your shell PATH.

Note that pip install opencv-python install OpenCV has some problems like not support x264. Better use following way to install OpenCV.

1
2
conda install x264=='1!152.20180717' ffmpeg=4.0.2 -c conda-forge
conda install opencv

注意: 使用上述命令安装支持读写 x264 的 OpenCV,之后再删除通过 conda 安装的 ffmpeg,改为静态库版本。因为通过 conda 安装的 ffmpeg 不支持 mp3 的读写。

stackoverflow: How to use libx264 ffmpeg in conda environment?

Another way is to build ffmpeg from source.

FFMPEG: Compile FFmpeg on CentOS

You can build static or dynamic libs.

🚩注意: 当编译动态库版本的 ffmpeg 时,其依赖也需要编译成动态库版本。如果需要编译动态库版本的 OpenCV,ffmpeg 也需要使用动态库。

👍stackoverflow: FFmpeg doesn’t compile with shared libraries

Problem & Solution

libaom.a cannot be used when making a shared object

1
/usr/bin/ld: /home/rivergold/software/lib/ffmpeg/ffmpeg-build/lib/libaom.a(noise_model.c.o): relocation R_X86_64_PC32 against symbol `stderr@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC

Solution:

Build libaom with enable shared libs.

1
2
3
4
5
6
7
# libaom
cd ${FFPEG_SOURCE_DIR} &&
mkdir -p aom_build &&
cd aom_build &&
PATH="$PREFIX_DIR/bin:$PATH" cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX="$PREFIX_DIR" -DBUILD_SHARED_LIBS=on -DENABLE_NASM=on ../aom &&
PATH="$PREFIX_DIR/bin:$PATH" make &&
make install

注意: ffmpeg 官网的教程仅说明了如何编译 static 版本的 ffmpeg,且编译libaom的参数ENABLE_SHARED在 CMakeLists.txt 中没有记录,需要改为BUILD_SHARED_LIBS

🌵 Get Video Information

mediainfo is a very good tool to get media information. And pymediainfo is Python API of mediainfo.

Install mediainfo

  1. Download CLI, libmediainfo and libzen

  2. Install

    1
    2
    3
    rpm -i libzen
    rpm -i libmediainfo
    rpm cli

ffprobe get json format information

1
ffprobe -print_format json <video>

Github Gist: jaivikram/getVideoDetails.py
Github Gist: oldo/video-metada-finder.py

🌵 Change Video Format

1
ffmpeg -i <in_video_path> -c copy <out_video_path>

E.g.

1
ffmpeg -i in.ts -c copy out.mp4

🌵 Change Video Encode Format

1
ffmpeg -i <in_video_path> -c:v <video_encode> -c:a copy <out_video_path>

E.g.

1
ffmpeg -i in.ts -c:v libx264 -c:a copy out.mp4

Change Encode while Keep Bitrate

1
ffmpeg -i <in_video_path> -c:v <video_encode> -b:v <video_bitrate> -c:a copy <out_video_path>

E.g.

1
ffmpeg -i in.ts -c:v libx264 -b:v 20M -c:a copy out.mp4

stackoverflow: How to convert .ts file into a mainstream format losslessly?

🌵 Extract Frame from Video

Extract One Frame

1
ffmpeg -ss <time> -i <input_video> -vframes 1 -q:v 2 output.jpg

stackoverflow: How to extract 1 screenshot for a video with ffmpeg at a given time?

Extract All Frame

1
ffmpeg -loglevel warning -y -vsync 0 -i <in_video_path> -vf "select=between(n\,1\,300000)*not(mod(n\,1))" -q:v 0 -deinterlace frm_%d.jpg

@rivergold: 该命令会舍弃视频的第一帧(0 号帧)。因为 FFmpeg 导出图片时 index 是从 1 开始计数的,如果舍弃第一帧,则帧号与从 0 开始计数的方式保持一致。

🌵 Cut Video

1
2
3
4
# start_time, end_time
ffmpeg -ss <start_time> -to <end_time> -i <in_video_path> <out_video_path>
# start_time, duration
ffmepg -ss <start_time> -t <duration> -i <in_video_path> <out_video_path>