简介
记录在Linux上编译ffmpeg的过程及编译过程的问题,并使用编译库编写测试程序验证是否可用。
环境
- 系统版本:Ubuntu 20.04.5 LTS x86_64
- 编译器:g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
编译
-
安装依赖项
sudo apt-get install git wget
-
下载代码及依赖项解压
代码及依赖项介绍,无需下载,通过脚本统一下载
-
ffmpeg源代码
官网:https://ffmpeg.org/
版本:http://ffmpeg.org/releases/ffmpeg-5.1.2.tar.gz
版本信息:
5.1.2 was released on 2022-09-25. It is the latest stable FFmpeg release from the 5.1 release branch, which was cut from master on 2022-07-13.
-
x264源代码
x264是一个用于将视频流编码为H.264/MPEG-4 AVC压缩格式的免费软件库和应用程序。为了支持ffmpeg的H264编解码必须编译这个。
官网:https://www.videolan.org/developers/x264.html
版本:https://code.videolan.org/videolan/x264.git stable分支
-
nasm
NASM是一个为可移植性与模块化而设计的一个80x86的汇编器。
官网:NASM
版本:https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2
-
Yasm
Yasm是一个完全 重写 的NASM汇编。
官网:The Yasm Modular Assembler Project (tortall.net)
版本:https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz
mkdir ~/ffmpeg cd ~/ffmpeg # 下载nasm wget https://www.nasm.us/pub/nasm/releasebuilds/2.15.05/nasm-2.15.05.tar.bz2 tar xjvf nasm-2.15.05.tar.bz2 # 下载yasm wget https://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz tar xzvf yasm-1.3.0.tar.gz # 下载x264 git clone --branch stable --depth 1 https://code.videolan.org/videolan/x264.git # 下载ffmpeg wget http://ffmpeg.org/releases/ffmpeg-5.1.2.tar.gz tar xvf ffmpeg-5.1.2.tar.gz
-
-
将如下代码保存到脚本中执行
base_path=$(cd `dirname $0`;pwd) ffmpeg_depend_build=$base_path/dependbuild ffmpeg_build=$base_path/build nasm_src=$base_path/nasm-2.15.05 yasm_src=$base_path/yasm-1.3.0 x264_src=$base_path/x264 ffmpeg_src=$base_path/ffmpeg-5.1.2 # nasm cd $nasm_src ./autogen.sh ./configure --prefix="$ffmpeg_depend_build" make make install rm -rf /usr/bin/nasm ln -s $ffmpeg_depend_build/bin/nasm /usr/bin/nasm # yasm cd $yasm_src ./configure --prefix="$ffmpeg_depend_build" make make install rm -rf /usr/bin/yasm ln -s $ffmpeg_depend_build/bin/yasm /usr/bin/yasm # x264 cd $x264_src ./configure --prefix="$ffmpeg_build" --enable-shared make make install # ffmpeg cd $ffmpeg_src export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:$ffmpeg_build/lib/pkgconfig ./configure --prefix=$ffmpeg_build --enable-shared --enable-libx264 --enable-gpl \ --extra-cflags=-l$ffmpeg_build/include \ --extra-ldflags=-L$ffmpeg_build/lib make make install
测试
-
验证ffmpeg可用
-
代码验证
Qt工程添加依赖:
# 项目根目录 ROOT_DIR = $$PWD/.. # 第三方库 3RDPART_DIR = $${ROOT_DIR}/3rdparty # 可执行目录 CONFIG(debug, debug|release){ BIN_DIR = $${ROOT_DIR}/debug } else { BIN_DIR = $${ROOT_DIR}/release } unix:!macx { linux-g++:QMAKE_TARGET.arch = $$QMAKE_HOST.arch linux-g++-32:QMAKE_TARGET.arch = x86 linux-g++-64:QMAKE_TARGET.arch = x86_64 linux-arm-gnueabihf:QMAKE_TARGET.arch = arm contains(QMAKE_TARGET.arch, x86_64) { INCLUDEPATH += $${3RDPART_DIR}/ffmpeg/linux64/include LIBS += -L$${3RDPART_DIR}/ffmpeg/linux64/lib \ -lavformat -lx264 } }
测试代码:
extern "C" { #include <libavformat/avformat.h> } #include <iostream> bool getVedioDuration(const std::string &filePath) { AVFormatContext *fmtCtx = avformat_alloc_context(); if (nullptr == fmtCtx) { return false; } auto ret = avformat_open_input(&fmtCtx, filePath.c_str(), NULL, NULL); if (ret < 0) { std::cout << "open input error." << std::endl; return false; } ret = avformat_find_stream_info(fmtCtx, nullptr); if (ret < 0) { std::cout << "find stream info error." << std::endl; return false; } int videoIndex = -1; int audio_index = -1; int nbStreams = fmtCtx->nb_streams; for (int i = 0; i < nbStreams; i++) { // fmtCtx->streams[i]->codec 新版ffmpeg已弃用 if (fmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { videoIndex = i; } else if (fmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { audio_index = i; } } std::cout << fmtCtx->duration / AV_TIME_BASE << std::endl; if (videoIndex != -1) { auto streamVedio = fmtCtx->streams[videoIndex]; std::cout << "vedio duration: " << (streamVedio->duration * streamVedio->time_base.num / streamVedio->time_base.den) << std::endl; } if (audio_index != -1) { auto streamAudio = fmtCtx->streams[audio_index]; std::cout << "audio duration: " << (streamAudio->duration * streamAudio->time_base.num / streamAudio->time_base.den) << std::endl; } if (videoIndex == -1 && audio_index == -1) { return false; } return true; } int main(int argc, char *argv[]) { getVedioDuration("/home/zcb/Desktop/media/VID_20200221_191406.mp4"); return 0; }
编译后的动态库打包下载地址:ffmpeg在linux上编译的动态库(ubuntu64位非strip版)-编解码文档类资源-CSDN文库