FFMPEG
1. 操作日志
- 日志级别
AV LOG ERROR
AV LOG WARNING
AV LOG INFO
AV LOG DEBUG
cmake_minimum_required(VERSION 3.27)
project(FFmpeg_exercise)
set(CMAKE_CXX_STANDARD 14)
# 定义FFmpeg的安装路径变量
set(FFMPEG_INSTALL_DIR "/usr/local/ffmpeg")
# 将FFmpeg的头文件目录添加到包含路径
include_directories(${FFMPEG_INSTALL_DIR}/include)
# 定义FFmpeg库的基础名称(根据你的需要调整)
set(FFMPEG_LIBS "avcodec;avformat;avutil") # 用分号分隔库名
# 寻找并链接FFmpeg库
foreach(FFMPEG_LIB ${FFMPEG_LIBS})
find_library(${FFMPEG_LIB}_LIBRARY NAMES ${FFMPEG_LIB}
PATHS ${FFMPEG_INSTALL_DIR}/lib NO_DEFAULT_PATH)
list(APPEND FFMPEG_LIBRARIES ${${FFMPEG_LIB}_LIBRARY})
endforeach()
add_executable(FFmpeg_exercise main.cpp)
# 链接FFmpeg库
target_link_libraries(FFmpeg_exercise ${FFMPEG_LIBRARIES})
- main.cpp
#ifdef __cplusplus
extern "C" {
#endif
// 包含FFmpeg的头文件
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#ifdef __cplusplus
}
#endif
/*
通过预处理器指令#ifdef __cplusplus来检查代码是否在C++环境中编译。
如果是,它将开始一个extern "C"块,这意味着在该块内包含的代码将使用C的链接规则。
这通常用于包含C库的头文件,以确保C++编译器不会对函数名进行名称修饰。
*/
int main() {
av_log_set_level(AV_LOG_DEBUG);
av_log(nullptr,AV_LOG_DEBUG,"Hello World!:%d\n",10);
av_log(nullptr,AV_LOG_INFO,"Hello World! test: INFO\n");
av_log(nullptr,AV_LOG_ERROR,"Hello World! test: ERROR\n");
return 0;
}
2. 文件移动和删除
- api
avpriv_io_delete()
: 删除avpriv_io_move()
:移动
- 案例
cmake_minimum_required(VERSION 3.27)
project(FFmpeg_exercise)
set(CMAKE_CXX_STANDARD 14)
# 定义FFmpeg的安装路径变量
set(FFMPEG_INSTALL_DIR "/usr/local/ffmpeg")
# 将FFmpeg的头文件目录添加到包含路径
include_directories(${FFMPEG_INSTALL_DIR}/include)
# 定义FFmpeg库的基础名称(根据你的需要调整)
set(FFMPEG_LIBS "avcodec;avformat;avutil") # 用分号分隔库名
# 寻找并链接FFmpeg库
foreach(FFMPEG_LIB ${FFMPEG_LIBS})
find_library(${FFMPEG_LIB}_LIBRARY NAMES ${FFMPEG_LIB}
PATHS ${FFMPEG_INSTALL_DIR}/lib NO_DEFAULT_PATH)
list(APPEND FFMPEG_LIBRARIES ${${FFMPEG_LIB}_LIBRARY})
endforeach()
add_executable(FFmpeg_exercise main.cpp)
# 链接FFmpeg库
target_link_libraries(FFmpeg_exercise ${FFMPEG_LIBRARIES})
#ifdef __cplusplus
extern "C" {
#endif
// 包含FFmpeg的头文件
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#ifdef __cplusplus
}
#endif
#include <iostream>
#include <fstream>
/*
通过预处理器指令#ifdef __cplusplus来检查代码是否在C++环境中编译。
如果是,它将开始一个extern "C"块,这意味着在该块内包含的代码将使用C的链接规则。
这通常用于包含C库的头文件,以确保C++编译器不会对函数名进行名称修饰。
*/
int main() {
std::ofstream outfile("./test.txt");
outfile<<"hello world!\n"<<std::endl;
outfile<<"this is a test file"<<std::endl;
outfile.close();
if (outfile.is_open()) {
av_log(nullptr,AV_LOG_ERROR,"Failed to close file: %s","./test.txt");
return 1; // 如果文件未关闭,返回错误代码
}
av_log_set_level(AV_LOG_DEBUG);
int ret {0};
ret = avpriv_io_move("./test.txt","./demo.txt");
if (ret<0){
av_log(nullptr,AV_LOG_ERROR,"Failed to rename text.txt\n");
}
av_log(nullptr,AV_LOG_INFO,"SUCCESSED TO RENAME FILE TEXT.TXT\n");
ret = avpriv_io_delete("./demo.txt");
if (ret<0){
av_log(nullptr,AV_LOG_ERROR,"Failed to delete demo.txt\n");
}
av_log(nullptr,AV_LOG_INFO,"SUCCESSED TO delete FILE TEXT.TXT\n");
// av_log(nullptr,AV_LOG_DEBUG,"Hello World!:%d\n",10);
// av_log(nullptr,AV_LOG_INFO,"Hello World! test: INFO\n");
// av_log(nullptr,AV_LOG_ERROR,"Hello World! test: ERROR\n");
return 0;
}
3. 操作目录重要函数
avio_open_dir()
:
- 功能:打开一个目录以供进一步读取。
- 返回值:成功时返回指向
AVIODirContext
的指针,失败时返回NULL
。 - 使用:此函数用于初始化目录遍历,获取指向目录中第一个条目的指针。
AVIODirContext
:
- 类型:这是一个不透明的结构体,用于表示打开的目录和遍历状态。
- 用途:在使用
avio_open_dir()
成功打开目录后,会返回一个AVIODirContext
类型的指针,该指针在后续的目录遍历中使用。
avio_read_dir()
:
- 功能:读取目录中的下一个条目。
- 参数:传入
AVIODirContext
指针。 - 返回值:成功时返回指向
AVIoDirEntry
的指针,遍历完成或失败时返回NULL
。 - 使用:在每次调用
avio_read_dir()
后,都会移动到目录中的下一个条目。如果已经到达目录末尾或发生错误,则返回NULL
。
AVIoDirEntry
:
- 类型:这是一个结构体,包含有关目录条目的信息,如文件名、文件类型等。
- 用途:通过
avio_read_dir()
获取的每个条目都是一个AVIoDirEntry
对象,它包含了关于文件或目录的信息。
avio_close_dir()
:
- 功能:关闭之前用
avio_open_dir()
打开的目录。 - 参数:传入
AVIODirContext
指针。 - 返回值:返回0表示成功,返回负数表示失败。
- 使用:完成目录遍历后,应当调用此函数来释放与
AVIODirContext
关联的资源。
- 案例
#ifdef __cplusplus
extern "C" {
#endif
// 包含FFmpeg的头文件
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#ifdef __cplusplus
}
#endif
#include <iostream>
#include <fstream>
/*
通过预处理器指令#ifdef __cplusplus来检查代码是否在C++环境中编译。
如果是,它将开始一个extern "C"块,这意味着在该块内包含的代码将使用C的链接规则。
这通常用于包含C库的头文件,以确保C++编译器不会对函数名进行名称修饰。
*/
int main() {
int ret {0};
//# 上下文结构体
AVIODirContext *ctx {nullptr};
AVIODirEntry *entry {nullptr};
ret = avio_open_dir(&ctx,"./", nullptr);
if (ret<0){
av_log(nullptr,AV_LOG_ERROR,"Failed to open dir:%s\n", av_err2str(ret));
goto _fail;;
} else{
av_log(nullptr,AV_LOG_INFO,"Success to open dir:%s\n", av_err2str(ret));
}
while(true){
// 读取文件
ret = avio_read_dir(ctx,&entry);
if (ret<0){
av_log(nullptr,AV_LOG_ERROR,"Failed to read dir:%s\n", av_err2str(ret));
return -1;
} else{
av_log(nullptr,AV_LOG_INFO,"Success to read dir:%s\n", av_err2str(ret));
}
if(!entry){
break;
}
av_log(nullptr,AV_LOG_INFO,"%lld PRID64%s\n",entry->size,entry->name);
// 释放内存,防止内存泄漏
avio_free_directory_entry(&entry);
}
_fail:
avio_close_dir(&ctx);
std::ofstream outfile("./test.txt");
outfile<<"hello world!\n"<<std::endl;
outfile<<"this is a test file"<<std::endl;
outfile.close();
if (outfile.is_open()) {
av_log(nullptr,AV_LOG_ERROR,"Failed to close file: %s","./test.txt");
return 1; // 如果文件未关闭,返回错误代码
}
av_log_set_level(AV_LOG_DEBUG);
ret = avpriv_io_move("./test.txt","./demo.txt");
if (ret<0){
av_log(nullptr,AV_LOG_ERROR,"Failed to rename text.txt\n");
}
av_log(nullptr,AV_LOG_INFO,"SUCCESSED TO RENAME FILE TEXT.TXT\n");
ret = avpriv_io_delete("./demo.txt");
if (ret<0){
av_log(nullptr,AV_LOG_ERROR,"Failed to delete demo.txt\n");
}
av_log(nullptr,AV_LOG_INFO,"SUCCESSED TO delete FILE TEXT.TXT\n");
// av_log(nullptr,AV_LOG_DEBUG,"Hello World!:%d\n",10);
// av_log(nullptr,AV_LOG_INFO,"Hello World! test: INFO\n");
// av_log(nullptr,AV_LOG_ERROR,"Hello World! test: ERROR\n");
return 0;
}