51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

FFmpeg Hello World

FFmpeg 是一个功能强大、开源的音视频处理工具,可以满足用户在音视频处理方面的各种需求。可以用于录制、转换、编辑、播放和流媒体处理等。它是一个跨平台的工具,支持 Windows、Mac、Linux 等操作系统。

FFmpeg 可以处理多种格式的音视频文件,包括常见的 AVI、MP4、MOV、FLV、WMV、MKV 等格式,以及音频格式如 MP3、WAV、AAC、FLAC 等。以下是一些它可以完成的任务:

  1. 转换音视频格式:可以将各种格式的音视频文件转换成所需的格式,例如将 MP4 文件转换为 AVI 文件。
  2. 剪辑和编辑视频:可以从视频文件中剪切出一段、拼接多段视频、添加字幕和水印等。
  3. 提取音频:可以从视频文件中提取出音频,将其保存成独立的音频文件。
  4. 视频截图:可以从视频文件中截取出一帧作为图片,用于制作视频预览图或者制作视频缩略图。
  5. 流媒体处理:可以使用 FFmpeg 构建流媒体服务器,对音视频进行实时编码和流式传输。
  6. 录制视频:可以使用 FFmpeg 进行屏幕录制,捕捉摄像头视频等。

本篇是一个简单的 Hello World 文档,主要记录下:

  1. 如何编译安装 FFmpeg
  2. 使用 FFmpeg获得视频信息

下面的例子使用的环境是:windows 11 + visual studio 2022

  1. FFmpeg 安装 {#title-0} =======================

FFmpeg 安装有两种方式,一种是直接下载编译好的,另外一种就是自己下载源码自己编译。

1.1 自己编译 {#title-1}

由于 FFmpeg 在 Unix/Linux 上编写时,使用了很多 Unix/Linux 系统上的库和工具,如 GCC、make、yasm、pkg-config 等,这些工具和库在 Windows 系统上并不存在,因此无法直接编译。为了能够去编译 FFmpeg,我们需要一个能在 windows 上运行的类 Unix/Linux 的环境。

MSYS2 就是一个在 Windows 操作系统上运行的类 Unix/Linux 的环境和开发工具和库,例如:当我们需要 gcc 时,可以直接在 MSYS2 环境里通过命令安装,实现在 Windows 平台上编译和运行开源软件。MSYS2 最终能够生成 Windows 平台上可执行的二进制文件。

首先从 www.msys2.org下载安装 MSYS2,或者从百度网盘:链接:https://pan.baidu.com/s/1leQZrvMcUHFI6Q3zEoAbLg,提取码:h57e

然后再 MSYS2 命令界面执行:

# 安装 gcc
pacman -S --needed base-devel git mingw-w64-x86_64-toolchain
# 安装汇编编译工具,这个是 FFmpeg 编译过程中需要的
pacman -S nasm yasm

接着从 Download FFmpeg下载 FFmpeg 源码,或者从百度网盘下载:链接:https://pan.baidu.com/s/1gSSAkFamNSgm6vToyQ4a2A 提取码:22di

然后 cd 到 FFmpeg 源码目录(注意:路径字符串放在双引号中),开始配置编译环境:

./configure --enable-shared --disable-static

然后开始编译 FFmpeg:

make

最后是安装软件,这一步就是将 FFmpeg 库、可执行文件、相关的头文件、配置文件拷贝到指定目录:

make install prefix="C:\Users\china\Downloads\ffmpeg-snapshot\ffmpeg\install"

最后将 bin 目录中的所有的 *.lib 文件都拷贝到 lib 目录下

1.2 直接下载 {#title-2}

点击链接 Download FFmpeg 按照图上的标注下载即可,也可以直接从百度网盘下载:链接:https://pan.baidu.com/s/1_X_aBYj4tIKzFPBcmLi1SQ 提取码:e2cj

  1. FFmpeg 示例 {#title-3} =======================

创建一个空项目,做如下配置:

  1. 将 bin 目录下的所有 dll 文件拷贝到项目目录下
  2. 配置头文件路径
  3. 配置库文件路径

示例代码为通过 FFmpeg 获得一个输入视频的相关信息:

#include <iostream>

extern "C"
{
    #include <libavformat/avformat.h>
    #include <libavcodec/avcodec.h>
}

// 判断流的类型
void print_stream_type(AVStream * stream)
{      
    // 获得流的类型
    AVMediaType type = stream->codecpar->codec_type;

    // 获得流的编码器参数,再获得编码类型
    if (type == AVMEDIA_TYPE_VIDEO)
    {
        printf("视频流的类型: %s\n", av_get_media_type_string(type));
        return;
    }

    if (type == AVMEDIA_TYPE_AUDIO)
    {
        printf("视频流的类型: %s\n", av_get_media_type_string(type));
        return;
    }

    printf("未知类型");
}


// 读取视频信息
void test()
{
    AVFormatContext* av_format = nullptr;
    const char* url = "demo.mp4";
    const AVInputFormat* fmt = nullptr;

    // 打开输入流,并读取头部信息
    // av_format 用于获得读取到的视频信息, 内存由 avformat_open_input 函数分配
    // url 读取的视频路径
    // fmt 如果非空的话,这个参数将会强制设置输入流的格式。如果为空,则自动检测视频的格式
    int ret = avformat_open_input(&av_format, url, fmt, nullptr);
    if (ret != 0)
    {   
        av_log(nullptr, AV_LOG_INFO, "视频 %s 打开失败");
        return;
    }

    // 视频封装格式
    // mov,mp4,m4a,3gp,3g2,mj2
    printf("视频封装格式: %s\n", av_format->iformat->name);
    
    // 输入视频时长
    int64_t seconds = av_format->duration / AV_TIME_BASE;
    printf("输入视频时长: %lld 秒\n", seconds);
    
    // 视频流的数量
    unsigned int number = av_format->nb_streams;
    printf("视频流的数量: %u\n", number);

    // 视频流的类型
    print_stream_type(av_format->streams[0]);
    print_stream_type(av_format->streams[1]);


    // 输入视频帧率
    AVRational frame_rate = av_format->streams[0]->avg_frame_rate;
    printf("输入视频帧率: %f fps\n", av_q2d(frame_rate));

    // 视频编码类型
    AVCodecID video_codec_type = av_format->streams[0]->codecpar->codec_id;
    // avcodec_get_name 函数根据编码类型ID返回编码类型名字
    printf("视频编码类型: %s\n", avcodec_get_name(video_codec_type));

    // 音频编码类型
    AVCodecID audio_codec_type = av_format->streams[1]->codecpar->codec_id;
    printf("音频编码类型: %s\n", avcodec_get_name(audio_codec_type));

    // 获得视频宽高
    int w = av_format->streams[0]->codecpar->width;
    int h = av_format->streams[0]->codecpar->height;
    printf("视频分辨率为: %d %d\n", w, h);

    // 获得视频码率: 视频传输时平均比特数
    // 比特率是指每秒传输的总比特数,包括视频和音频等其他数据所占用的比特数
    int64_t brate = av_format->streams[0]->codecpar->bit_rate;
    printf("输入视频码率: %lld\n", brate);

    // 关闭输入流
    avformat_close_input(&av_format);
}

int main()
{
    test();
    return 0;
}

程序输出结果:

视频封装格式: mov,mp4,m4a,3gp,3g2,mj2
输入视频时长: 64 秒
视频流的数量: 2
视频流的类型: video
视频流的类型: audio
输入视频帧率: 59.990015 fps
视频编码类型: h264
音频编码类型: aac
视频分辨率为: 2560 1440
输入视频码率: 44186059
赞(2)
未经允许不得转载:工具盒子 » FFmpeg Hello World