一般情況下,熟悉了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
#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 modemessage(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
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
#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
#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 libavcodec avformat avutil swresample swscale swscale avfilter #link ffmpeg libm) #link libm.so for math operationsset(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
進入build文件夾,執行命令:
cmake ../
make
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使用不是很復雜,不過比較底層,要想集成進自己的項目里面,工作量不小。