FFmpeg获取音视频流信息

简介: FFmpeg获取音视频流信息

前言

本文记录用 FFmpeg 获取视频流+音频流的信息(编码格式、分辨率、帧率、播放时长…),所用的工程基于上个博客编译成功的工程:使用FFmpeg4.3.1的SDK官方开发包编译ffmpeg.c


一、需求

我们经常需要知道一个媒体文件所包含的媒体流的信息,比如文件格式、播放时长、码率、视音频编码格式,视频分辨率,帧率,音频属性等信息。

如何使用 FFmpeg API 获取这些信息呢?

  • 媒体容器封装格式
  • 文件播放时长
  • 文件平均码率(视频+音频)
  • 视频属性(编码器名称、视频分辨率、帧率、编码码率)
  • 音频属性(编码器名称、采样率、声道数、编码码率)

二、源码

ffmepg.h 文件中添加我们自定义的结构体,我们后面会利用 ffmepg 的 API 函数将音视频流信息填充到各个字段:

typedef struct __AVGeneralMediaInfo {
    char filepath[1024];    // 文件路径
    int64_t duration;       // 时长,单位:微秒 time_base:1,000,000
    int64_t totalBitrate;   // 总码率
    int videoStreamIndex;   // 视频流索引
    int audioStreamIndex;   // 音频流索引
    char videoCodecName[256]; 
    int width;              // 视频宽
    int height;             // 视频高
    double frameRate;       // 视频帧率
    char audioCodecName[256];
    int sampleRate;         // 采样率
    int channels;           // 声道数
} AVGeneralMediaInfo;
void get_avgeneral_mediainfo(AVGeneralMediaInfo* avmi, const char* filepath);

ffmepg.c 文件中添加获取音视频流的基本信息的接口

// 封装:查找解码器
// type:[0:video, 1:audio]
void get_decoder_name(AVGeneralMediaInfo *avmi, AVFormatContext *avFmtctx, int type) 
{
    int nindex = -1;
    if (type == 0) {    // video
        nindex = avmi->videoStreamIndex;
    }
    else if (type == 1) {   // aduio
        nindex = avmi->audioStreamIndex;
    }
    if (nindex >= 0) {
        AVCodecContext* avcodecCtx = NULL;
        AVCodec *avcodec = NULL;
        avcodecCtx = avFmtctx->streams[nindex]->codec;
        avcodec = avcodec_find_decoder(avcodecCtx->codec_id);
        if (type == 0) {    // video
            strcpy(avmi->videoCodecName, avcodec->name);
            printf("videoCodecName = %s\n", avmi->videoCodecName);
        }
        else if (type == 1) {
            strcpy(avmi->audioCodecName, avcodec->long_name);
            printf("audioCodecName = %s\n", avmi->audioCodecName);
        }
    }
}
// 获取音视频流的基本信息
void get_avgeneral_mediainfo(AVGeneralMediaInfo *avmi, const char *filepath)
{
    int ret = -1;
    int i = 0;
    AVFormatContext* avFmtCtx = NULL;   // 大管家
    if (avmi == NULL || filepath == NULL) {
        return;
    }
    // 1.打开音视频文件或网络流
    ret = avformat_open_input(&avFmtCtx, filepath, NULL, NULL);
    if (ret < 0) {
        printf("error avformat_open_input:%s\n", filepath);
        return;
    }
    // 2.打印音视频流信息
    av_dump_format(avFmtCtx, 0, filepath, 0);
    // 3.继续深入,读取更多的字段
    avmi->duration = avFmtCtx->duration;        // 时长
    avmi->totalBitrate = avFmtCtx->bit_rate;    // 总码率
    printf("duration = %lld, totalBitrate = %lld\n", 
        avmi->duration, 
        avmi->totalBitrate);
    // 分别读取音视频流,更多的参数
    for (i = 0; i < avFmtCtx->nb_streams; i++) {
        AVStream* avstmp = avFmtCtx->streams[i];    // 拿到具体的一路流
        if (avstmp->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
            avmi->videoStreamIndex = i;
            avmi->width = avstmp->codec->width;
            avmi->height = avstmp->codec->height;
            // 视频帧率:avg_frame_rate
            // fps:frames per second
            if (avstmp->avg_frame_rate.num != 0 
                && avstmp->avg_frame_rate.den != 0) {
                avmi->frameRate = (double)avstmp->avg_frame_rate.num / (double)avstmp->avg_frame_rate.den;
            }
            printf("width = %d, height = %d, frameRate = %.3lf\n", 
                avmi->width,
                avmi->height,
                avmi->frameRate);
        }
        else if (avstmp->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
            avmi->audioStreamIndex = i;
            avmi->channels = avstmp->codec->channels;
            avmi->sampleRate = avstmp->codec->sample_rate;
            printf("channel = %d, sampleRate = %d\n", 
                avmi->channels, 
                avmi->sampleRate);
        }
    }
    // 读取具体的解码器
    // avcodec_find_decoder()
    // 视频解码器
    get_decoder_name(avmi, avFmtCtx, 0);
    
    // 音频解码器
    get_decoder_name(avmi, avFmtCtx, 1);
    // release
    avformat_close_input(&avFmtCtx);
}

ffmpeg431_test.cpp 文件内容如下:

#include <iostream>
extern "C"
{
#include "ffmpeg.h"
}
int main(int argc, char** argv)
{
  AVGeneralMediaInfo* avmi = new AVGeneralMediaInfo();
  if (avmi) {
    get_avgeneral_mediainfo(avmi, "SampleVideo_1280x720_20mb.mp4");
    delete avmi;
    avmi = NULL;
  }
}

三、运行结果

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'SampleVideo_1280x720_20mb.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01T00:00:00.000000Z
    encoder         : Lavf53.24.2
  Duration: 00:01:57.31, bitrate: N/A
    Stream #0:0(und): Video: h264 (avc1 / 0x31637661), none, 1280x720, 1048 kb/s, 25 fps, 25 tbr, 12800 tbn (default)
    Metadata:
      creation_time   : 1970-01-01T00:00:00.000000Z
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 48000 Hz, 6 channels, 383 kb/s (default)
    Metadata:
      creation_time   : 1970-01-01T00:00:00.000000Z
      handler_name    : SoundHandler
duration = 117312000, totalBitrate = 0
width = 1280, height = 720, frameRate = 25.000
channel = 6, sampleRate = 48000
videoCodecName = h264
audioCodecName = AAC (Advanced Audio Coding)

使用 MediaInfo 打开 SampleVideo_1280x720_20mb.mp4 可以看到与上面打印对应的参数

目录
相关文章
|
26天前
|
缓存 监控 计算机视觉
视频监控笔记(三):opencv结合ffmpeg获取rtsp摄像头相关信息
本文介绍了如何使用OpenCV结合FFmpeg获取RTSP摄像头信息,包括网络架构、视频监控系统组成、以及如何读取和显示网络摄像头视频流。
37 1
|
3月前
|
Web App开发 5G Linux
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
一年一度的毕业季来临,计算机专业的毕业设计尤为重要,不仅关乎学业评价还积累实战经验。选择紧跟5G技术趋势的音视频APP作为课题极具吸引力。这里推荐三类应用:一是融合WebRTC技术实现视频通话的即时通信APP;二是具备在线直播功能的短视频分享平台,涉及RTMP/SRT等直播技术;三是具有自定义动画特效及卡拉OK歌词字幕功能的视频剪辑工具。这些项目不仅技术含量高,也符合市场需求,是毕业设计的理想选择。
74 6
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
|
2月前
|
Android开发 计算机视觉 C++
FFmpeg开发笔记(五十一)适合学习研究的几个音视频开源框架
音视频编程对许多程序员来说是一片充满挑战的领域,但借助如OpenCV、LearnOpenGL、FFmpeg、OBS Studio及VLC media player等强大的开源工具,可以降低入门门槛。这些框架不仅覆盖了计算机视觉、图形渲染,还包括多媒体处理与直播技术,通过多种编程语言如Python、C++的应用,使得音视频开发更为便捷。例如,OpenCV支持跨平台的视觉应用开发,FFmpeg则擅长多媒体文件的处理与转换,而VLC media player则是验证音视频文件质量的有效工具。
82 0
FFmpeg开发笔记(五十一)适合学习研究的几个音视频开源框架
|
2月前
用ffmpeg提取合并音视频
用ffmpeg提取合并音视频
|
4月前
|
达摩院 语音技术 异构计算
语音识别-免费开源的语音转文本软件Whisper的本地搭建详细教程,python版本是3.805,ffmpeg是专门处理音视频的,ffmpeg的下载链接,现在要求安装python和ffmpeg
语音识别-免费开源的语音转文本软件Whisper的本地搭建详细教程,python版本是3.805,ffmpeg是专门处理音视频的,ffmpeg的下载链接,现在要求安装python和ffmpeg
|
5月前
|
存储 编解码 Linux
rodert教你学FFmpeg实战这一篇就够了 - 音视频处理入门篇
rodert教你学FFmpeg实战这一篇就够了 - 音视频处理入门篇
61 1
|
4月前
|
C#
C#进程调用FFmpeg操作音视频
因为公司需要对音视频做一些操作,比如说对系统用户的发音和背景视频进行合成,以及对多个音视频之间进行合成,还有就是在指定的源背景音频中按照对应的规则在视频的多少秒钟内插入一段客户发音等一些复杂的音视频操作。本篇文章主要讲解的是使用C#进程(Process)调用FFmpeg.exe进行视频合并、音频合并、音频与视频合并成视频这几个简单的音视频操作。
|
6月前
|
存储 缓存 调度
FFmpeg开发笔记(十九)FFmpeg开启两个线程分别解码音视频
《FFmpeg开发实战》第10章示例playsync.c在处理音频流和视频流交错的文件时能实现同步播放,但对于分开存储的格式,会出现先播放全部声音再快速播放视频的问题。为解决此问题,需改造程序,增加音频处理线程和队列,以及相关锁,先将音视频帧读入缓存,再按时间戳播放。改造包括声明新变量、初始化线程和锁、修改数据包处理方式等。代码修改后在playsync2.c中,编译运行成功,控制台显示日志,SDL窗口播放视频并同步音频,证明改造有效。
100 0
FFmpeg开发笔记(十九)FFmpeg开启两个线程分别解码音视频
|
6月前
|
编解码 安全 计算机视觉
FFMPEG常用命令 音视频合并
FFMPEG常用命令 音视频合并
134 2
|
6月前
|
存储 编解码 缓存
ffmpeg音视频同步
ffmpeg音视频同步
135 0