一般情况下,熟悉了ffmpeg的命令行操作,把他当成一个工具来进行编解码啥的问题不大,不过如果要把功能集成进自己的软件中,还是要调用ffmpeg的api才行。
ffmpeg的源码和外带的模块有点太多了,直接用官网别人编译好的库就可以了,下面的操作就是演示使用cmake调用ffmpeg的库,来进行api的开发。
我把最后的工程包放到了我的下载资源里面了:ubuntu中使用ffmpeg库进行开发的cmake工程资源-CSDN文库
1 下载编译好的ffmpeg库
去如下网址下载自己想要的平台的库文件:
Releases · BtbN/FFmpeg-Builds · GitHub
对于ubuntu,下载linux amd64版本。
2 新建cmake工程文件夹架构
就是新建一个工程文件夹,里面包含几个子文件夹,把ffmpeg的库放到lib文件夹里面。
├── build
├── CMakeLists.txt
├── inc
├── lib
│ ├── CMakeLists.txt
│ └── ffmpeg_lib
└── src
├── CMakeLists.txt
├── module
└── system
上面是我的一个文件夹结构,我把ffmpeg的库放到lib文件夹中,自己的代码放到src里面,顶层有CMakeLists.txt,各个子文件夹有各自的CMakeLists.txt。
3 编写CMakeLists.txt,然后编译
顶层的cmakelists.txt
bash
#version required
cmake_minimum_required(VERSION 3.22.1)
#project name
project(ffmpeg_test VERSION 1.0.0)
#include dir
include_directories(inc)
link_directories(lib)
#ffmpeg lib
include_directories(lib/ffmpeg_lib/include)
link_directories(lib/ffmpeg_lib/lib)
#configs
set(BUILD_SHARED_LIBS on) #shared libs
set(CMAKE_BUILD_TYPE debug) #debug mode
message(STATUS build_type:${CMAKE_BUILD_TYPE})
if(CMAKE_BUILD_TYPE)
set(CMAKE_C_FLAGS_DEBUG "-O2 -DDEBUG")
message(STATUS c_flags:${CMAKE_C_FLAGS_DEBUG})
else()
message(STATUS build_type:${CMAKE_BUILD_TYPE})
endif()
#subdirectory
add_subdirectory(src)
add_subdirectory(lib)
message(STATUS "project version:${PROJECT_VERSION}")
message(STATUS system_name:${CMAKE_HOST_SYSTEM_NAME})
message(STATUS system_processor:${CMAKE_HOST_SYSTEM_PROCESSOR})
message(STATUS host_system:${CMAKE_HOST_SYSTEM})
message(STATUS system_version:${CMAKE_HOST_SYSTEM_VERSION})
lib文件夹的cmakelists.txt
bash
set(ffmpeg_lib_dir, ffmpeg_lib/lib)
set(ffmpeg_header_dir, ffmpeg_lib/include)
#IMPORT exist SHARED libs
add_library( avcodec SHARED IMPORTED)
add_library( avfilter SHARED IMPORTED )
add_library( swresample SHARED IMPORTED )
add_library( swscale SHARED IMPORTED )
add_library( avformat SHARED IMPORTED )
add_library( avutil SHARED IMPORTED )
#set lib link dir
set_target_properties( avcodec PROPERTIES IMPORTED_LOCATION ${ffmpeg_lib_dir}/libavcodec.so )
set_target_properties( avfilter PROPERTIES IMPORTED_LOCATION ${ffmpeg_lib_dir}/libavfilter.so )
set_target_properties( swresample PROPERTIES IMPORTED_LOCATION ${ffmpeg_lib_dir}/libswresample.so )
set_target_properties( swscale PROPERTIES IMPORTED_LOCATION ${ffmpeg_lib_dir}/libswscale.so )
set_target_properties( avformat PROPERTIES IMPORTED_LOCATION ${ffmpeg_lib_dir}/libavformat.so )
set_target_properties( avutil PROPERTIES IMPORTED_LOCATION ${ffmpeg_lib_dir}/libavutil.so )
#add include and library directories to system
include_directories(ffmpeg_lib/include)
link_directories(ffmpeg_lib/lib)
#link librarys to system
#target_link_libraries(${PROJECT_NAME} avcodec avformat avutil swresample swscale swscale avfilter )
#get_property(inc_dirs DIRECTORY ./ PROPERTY INCLUDE_DIRECTORIES)
#get_property(lib_dirs DIRECTORY ./ PROPERTY LINK_DIRECTORIES)
#message("cmake ffmpeg... \n include_dirs=${inc_dirs} \n lib_dirs=${lib_dirs}")
src文件夹的cmakelists.txt
bash
#include directory
include_directories(module)
link_directories(module)
#subdirectory
add_subdirectory(module)
add_subdirectory(system)
get_property(inc_dirs DIRECTORY ./ PROPERTY INCLUDE_DIRECTORIES)
get_property(lib_dirs DIRECTORY ./ PROPERTY LINK_DIRECTORIES)
message("cmake src... \n include_dirs=${inc_dirs} \n lib_dirs=${lib_dirs}")
system子文件夹的cmakelists.txt
bash
#bin file, before libs
#aux_source_directory(./ system_files)
#add_executable(${PROJECT_NAME} ${system_files})
#add_executable(${PROJECT_NAME} mux.c)
#add_executable(${PROJECT_NAME} demux_decode.c)
add_executable(${PROJECT_NAME} decode_filter_video.c)
#libs
target_link_libraries(${PROJECT_NAME} PRIVATE
module #link local module lib
avcodec avformat avutil swresample swscale swscale avfilter #link ffmpeg lib
m) #link libm.so for math operations
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
进入build文件夹,执行命令:
bash
cmake ../
make
bash
oushaojun@oushaojun-virtual-machine:~/Desktop/ffmpeg/cmake_project/build$ cmake ../
-- build_type:debug
-- c_flags:-O2 -DDEBUG
cmake src...
include_dirs=/home/oushaojun/Desktop/ffmpeg/cmake_project/inc;/home/oushaojun/Desktop/ffmpeg/cmake_project/lib/ffmpeg_lib/include;/home/oushaojun/Desktop/ffmpeg/cmake_project/src/module
lib_dirs=/home/oushaojun/Desktop/ffmpeg/cmake_project/lib;/home/oushaojun/Desktop/ffmpeg/cmake_project/lib/ffmpeg_lib/lib;/home/oushaojun/Desktop/ffmpeg/cmake_project/src/module
-- project version:1.0.0
-- system_name:Linux
-- system_processor:x86_64
-- host_system:Linux-6.8.0-49-generic
-- system_version:6.8.0-49-generic
-- Configuring done
-- Generating done
-- Build files have been written to: /home/oushaojun/Desktop/ffmpeg/cmake_project/build
oushaojun@oushaojun-virtual-machine:~/Desktop/ffmpeg/cmake_project/build$ make
Consolidate compiler generated dependencies of target module
[ 50%] Built target module
Consolidate compiler generated dependencies of target ffmpeg_test
[100%] Built target ffmpeg_test
oushaojun@oushaojun-virtual-machine:~/Desktop/ffmpeg/cmake_project/build$
去build/bin中就可以看到最后的可执行文件了,当前的可执行程序都是官方的demo,要写自己的代码一样的套路。
ffmpeg的api使用不是很复杂,不过比较底层,要想集成进自己的项目里面,工作量不小。