当前位置:   article > 正文

ffmpeg音视频开发从入门到精通——ffmpeg日志及目录操作

ffmpeg日志

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})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 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;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

image-20240621212832462

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})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

#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;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

image-20240621222021634

3. 操作目录重要函数

  1. avio_open_dir():

    • 功能:打开一个目录以供进一步读取。
    • 返回值:成功时返回指向AVIODirContext的指针,失败时返回NULL
    • 使用:此函数用于初始化目录遍历,获取指向目录中第一个条目的指针。
  2. AVIODirContext:

    • 类型:这是一个不透明的结构体,用于表示打开的目录和遍历状态。
    • 用途:在使用avio_open_dir()成功打开目录后,会返回一个AVIODirContext类型的指针,该指针在后续的目录遍历中使用。
  3. avio_read_dir():

    • 功能:读取目录中的下一个条目。
    • 参数:传入AVIODirContext指针。
    • 返回值:成功时返回指向AVIoDirEntry的指针,遍历完成或失败时返回NULL
    • 使用:在每次调用avio_read_dir()后,都会移动到目录中的下一个条目。如果已经到达目录末尾或发生错误,则返回NULL
  4. AVIoDirEntry:

    • 类型:这是一个结构体,包含有关目录条目的信息,如文件名、文件类型等。
    • 用途:通过avio_read_dir()获取的每个条目都是一个AVIoDirEntry对象,它包含了关于文件或目录的信息。
  5. 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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

image-20240622093515869

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读
相关标签
  

闽ICP备14008679号