赞
踩
FFmpeg 是一个强大的多媒体处理库,广泛应用于音视频编解码、转换和流媒体处理等领域。C语言作为一种底层编程语言,与FFmpeg结合使用,可以高效地处理各种音视频任务。在本篇文章中,我们将探讨如何利用C语言和FFmpeg库打开一个音视频文件,并对其进行基本的处理操作。这不仅为深入学习FFmpeg的使用打下基础,也为从事多媒体处理工作的开发者提供实用的参考。
本教程使用ffmpeg版本为7.0.1
如有函数不同请下载和我一样的版本
开始 ↓ 包含头文件和定义视频文件路径 ↓ 分配格式上下文 ↓ 打开输入文件 ↓ |----------------------| | 打开失败 | | ↓ | | 打印错误信息并返回 | |----------------------| ↓ 检查文件中的流信息 ↓ |----------------------| | 检查失败 | | ↓ | | 打印错误信息并关闭文件 | |----------------------| ↓ 打印文件格式信息 ↓ 遍历所有流 ↓ 获取流和编解码参数 ↓ 查找解码器 ↓ 打印流的基本信息 ↓ |----------------------| | 没有找到解码器 | | ↓ | | 打印不支持的编解码器 | |----------------------| ↓ 关闭输入文件并释放格式上下文 ↓ 结束
AVFormatContext *avformat_alloc_context(void);
AVFormatContext
结构体。AVFormatContext
的指针。AVFormatContext
结构体是 FFmpeg 中非常重要的一个数据结构,它包含了与多媒体文件或流相关的所有信息。以下是一些常用且重要的成员及其作用:
AVInputFormat *iformat
AVInputFormat
结构。AVOutputFormat *oformat
AVOutputFormat
结构。void *priv_data
AVIOContext *pb
unsigned int nb_streams
AVStream **streams
char filename[1024]
int64_t duration
int64_t bit_rate
unsigned int nb_programs
AVProgram **programs
AVChapter **chapters
unsigned int nb_chapters
AVDictionary *metadata
int flags
int64_t start_time
int64_t start_time_realtime
int probesize
int max_analyze_duration
AVPacketList *packet_buffer
以下示例展示如何访问 AVFormatContext
的一些成员变量:
AVFormatContext *formatContext = avformat_alloc_context();
if (avformat_open_input(&formatContext, "example.mp4", NULL, NULL) == 0) {
printf("Format: %s\n", formatContext->iformat->name);
printf("Number of streams: %u\n", formatContext->nb_streams);
printf("Duration: %" PRId64 "\n", formatContext->duration);
printf("Bit rate: %" PRId64 "\n", formatContext->bit_rate);
for (unsigned int i = 0; i < formatContext->nb_streams; i++) {
AVStream *stream = formatContext->streams[i];
printf("Stream #%u\n", i);
printf(" Codec ID: %d\n", stream->codecpar->codec_id);
printf(" Codec type: %s\n", av_get_media_type_string(stream->codecpar->codec_type));
}
avformat_close_input(&formatContext);
}
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
ps
: 指向 AVFormatContext
指针的指针。filename
: 文件名。fmt
: 指定输入格式,可以为 NULL。options
: 一些额外的选项,可以为 NULL。int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
ic
: AVFormatContext
指针。options
: 一些额外的选项,可以为 NULL。void av_dump_format(AVFormatContext *ic, int index, const char *url, int is_output);
ic
: AVFormatContext
指针。index
: 要打印的流的索引,为 0 表示打印全部流信息。url
: 文件的 URL。is_output
: 指示是输入还是输出格式,0 表示输入,1 表示输出。AVCodec *avcodec_find_decoder(enum AVCodecID id);
id
: codec 的 ID。AVCodec
的指针,如果未找到返回 NULL。const char *avcodec_get_name(enum AVCodecID id);
id
: codec 的 ID。const char *av_get_media_type_string(enum AVMediaType media_type);
media_type
: 媒体类型。void avformat_close_input(AVFormatContext **s);
s
: 指向 AVFormatContext
指针的指针。#include <stdio.h> #include "include/libavcodec/avcodec.h" #include "include/libavformat/avformat.h" #include "include/libavutil/avutil.h" int main() { const char *videoname = "/home/ubuntu/MyFFMPEG/template_c_first/test2.mp4"; //打开输入文件并读取头部信息 AVFormatContext *formatContext = avformat_alloc_context(); if(avformat_open_input(&formatContext,videoname,NULL,NULL) != 0) { printf("open err:%s\n",videoname); return -1; } // 检查文件中的流信息 if (avformat_find_stream_info(formatContext, NULL) < 0) { printf("Could not find stream information in file %s\n", videoname); avformat_close_input(&formatContext); return -1; } // 打印文件格式信息 av_dump_format(formatContext, 0, videoname, 0); // 遍历所有流并打印流信息 for (unsigned int i = 0; i < formatContext->nb_streams; i++) { AVStream *stream = formatContext->streams[i]; AVCodecParameters *codecParams = stream->codecpar; AVCodec *codec = avcodec_find_decoder(codecParams->codec_id); if (codec == NULL) { printf("Unsupported codec!\n"); continue; } printf("Stream #%u:\n", i); printf(" Codec: %s (%s)\n", codec->name, avcodec_get_name(codecParams->codec_id)); printf(" Type: %s\n", av_get_media_type_string(codecParams->codec_type)); printf(" Duration: %ld\n", stream->duration); printf(" Time base: %d/%d\n", stream->time_base.num, stream->time_base.den); } // 关闭输入文件并释放格式上下文 avformat_close_input(&formatContext); return 0; }
输出:
ubuntu@ubuntu-virtual-machine:~/MyFFMPEG/template_c_first/build$ ./ffmpeg_test Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/ubuntu/MyFFMPEG/template_c_first/test2.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf61.1.100 description : Packed by Bilibili XCoder v2.0.2 Duration: 00:00:30.07, start: 0.000000, bitrate: 3275 kb/s Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 3124 kb/s, 60 fps, 60 tbr, 16k tbn (default) Metadata: handler_name : Bento4 Video Handler vendor_id : [0][0][0][0] Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 135 kb/s (default) Metadata: handler_name : Bento4 Sound Handler vendor_id : [0][0][0][0] Stream #0: Codec: h264 (h264) Type: video Duration: 481066 Time base: 1/16000 Stream #1: Codec: aac (aac) Type: audio Duration: 1323000 Time base: 1/44100
通过本文的介绍,我们了解了如何使用C语言结合FFmpeg库来打开一个音视频文件,并对其进行基本处理。FFmpeg提供了丰富的功能和灵活的接口,能够满足各种多媒体处理需求。掌握FFmpeg的使用方法,不仅能够提升我们在多媒体领域的开发效率,还能拓宽我们的技术视野。希望本篇文章能为读者提供有益的帮助,激发进一步探索FFmpeg和多媒体处理技术的兴趣。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。