ffmpeg的函数调用知识点

av_dump_format 打印的内容是什么意思?

av_dump_format 会打印出AVFormatContext的内容,打印的内容是什么意思?

我们使用av_dump_format打印出如下信息:

go 复制代码
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'https://demo.com/BigBuckBunny.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isomavc1mp42
    creation_time   : 2010-01-10T08:29:06.000000Z
  Duration: 00:09:56.47, start: 0.000000, bitrate: 2119 kb/s
    Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
    Metadata:
      creation_time   : 2010-01-10T08:29:06.000000Z
      handler_name    : (C) 2007 Google Inc. v08.13.2007.
    Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1991 kb/s, 24 fps, 24 tbr, 24k tbn, 48 tbc (default)
    Metadata:
      creation_time   : 2010-01-10T08:29:06.000000Z
      handler_name    : (C) 2007 Google Inc. v08.13.2007.

什么是文件的容器格式?

"mov,mp4,m4a,3gp,3g2,mj2" 表示输入文件的容器格式(Container Format)支持的扩展名。

在多媒体文件中,容器格式用于组织和存储多个音视频流以及其他相关数据。不同的容器格式支持不同的文件扩展名。这些扩展名用于指示文件的格式和类型。

在示例输出中,"mov,mp4,m4a,3gp,3g2,mj2" 表示输入文件是支持这些扩展名的容器格式。具体含义如下:

  • "mov":QuickTime Movie 文件,通常用于 macOS 平台。

  • "mp4":MPEG-4 Part 14 文件,是一种常见的多媒体容器格式,广泛用于存储音视频数据。

  • "m4a":MPEG-4 Audio 文件,用于存储音频数据。

  • "3gp":3rd Generation Partnership Project 文件,用于在移动设备上播放音视频。

  • "3g2":3rd Generation Partnership Project 2 文件,是 3GP 的增强版本。

  • "mj2":Motion JPEG 2000 文件,用于存储基于 JPEG 2000 压缩的视频。

因此,"mov,mp4,m4a,3gp,3g2,mj2" 表示输入文件是支持这些容器格式的文件,可以根据文件扩展名来推断文件的类型和格式。

多媒体文件格式说法比较笼统,准确说应该是被分为两种格式,编码格式 + 容器格式。

这就相当于我们会用盘子盛菜,也能用盘子盛米饭。

我们可以使用不同的容器格式盛放不同的编码格式。(当然这里也是有一些规定的,某个容器格式允许盛放哪些编码格式都是有明确要求的)

这个容器格式也就是我们日常看到的文件后缀。

在这里的输出中,我们有多个容器格式,说明我们是允许这个网络url下载的内容存放在mov/mp4/m4a等文件格式中的。

Metadata 有哪些信息?

av_dump_format() 输出的信息中,"Metadata" 部分包含了一些元数据信息,用于描述媒体文件的特定属性和相关数据。下面是对每个字段的解释:

  • major_brand:表示文件的主要品牌标识。它表示"最好"基于哪种格式来解析当前的文件。在示例中,"mp42" 表示该文件的主要品牌为 "mp42"。这是一种标识符,用于标识所使用的容器格式或编码器。

  • minor_version:表示文件的次要版本号。在示例中,"0" 表示该文件的次要版本为 0。

  • compatible_brands:表示文件与哪些兼容的品牌标识符兼容。在示例中,"isomavc1mp42" 表示该文件兼容 "isom"、"avc1" 和 "mp42" 这些品牌标识符。

  • creation_time:表示文件的创建时间。在示例中,"2010-01-10T08:29:06.000000Z" 表示该文件的创建时间为 2010 年 1 月 10 日 08:29:06(UTC 时间)。

这些元数据信息提供了关于媒体文件的额外信息,如文件的品牌标识、版本号、兼容性和创建时间。这些信息可以用于判断文件的属性、兼容性和制作信息。

Duration有哪些信息?

Duration: 00:09:56.47, start: 0.000000, bitrate: 2119 kb/s

这个信息比较好理解,视频文件有9分56秒,播放比特率是2119kb/s

视频的比特率(bitrate)是指在单位时间内传输或处理的比特数,通常以每秒的比特数(bps,bits per second)为单位。它表示视频数据的传输速率或处理速度。

比特率直接影响视频的数据量和质量,较高的比特率意味着更多的数据被分配给每个时间单位,从而提供更高的视频质量和更精细的细节。较低的比特率则表示视频数据被压缩得更多,可以减小文件大小或降低传输带宽要求,但可能会导致视频质量的损失和细节的丢失。

音频流有哪些信息?

go 复制代码
Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
    Metadata:
      creation_time   : 2010-01-10T08:29:06.000000Z
      handler_name    : (C) 2007 Google Inc. v08.13.2007.

"Stream #0:0(und)" 表示第一个流(Stream)的信息。下面是对每个字段的解释:

  • Audio:表示该流是音频流。

  • aac (LC):表示音频编解码器为 AAC(Advanced Audio Coding)的低复杂度(Low Complexity)模式。

  • mp4a / 0x6134706D:表示音频编码器的标识符为 "mp4a",对应的十六进制值为 "0x6134706D"。

  • 44100 Hz:表示音频采样率为 44,100 Hz,即每秒采集和播放的音频样本数。

  • stereo:表示音频通道模式为立体声,即左右两个声道。

  • fltp:表示音频采样格式为浮点型(floating point)。

  • 125 kb/s:表示音频的比特率为 125 kb/s,即每秒传输或处理的音频数据量为 125 kb。

  • (default):表示该流是默认的流。

  • handler_name: 表示是由 Google 公司开发的某个版本的处理程序生成或处理的。

视频流有哪些信息?

"Stream #0:1(und)" 表示第二个流(Stream)的信息,即视频流。下面是对每个字段的解释:

  • Video:表示该流是视频流。

  • h264 (High):表示视频编解码器为 H.264(高级)。

  • avc1 / 0x31637661:表示视频编码器的标识符为 "avc1",对应的十六进制值为 "0x31637661"。

  • yuv420p:表示视频采样格式为 YUV420P,即色彩空间为 YUV,亮度和色度分量的采样比例为 4:2:0。

  • 1280x720:表示视频分辨率为 1280x720 像素。

  • [SAR 1:1 DAR 16:9]:表示视频的样本宽高比(Sample Aspect Ratio)为 1:1,显示宽高比(Display Aspect Ratio)为 16:9。

  • 1991 kb/s:表示视频的比特率为 1991 kb/s,即每秒传输或处理的视频数据量为 1991 kb。

  • 24 fps:表示视频的帧率为 24 帧每秒。

  • 24 tbr, 24k tbn, 48 tbc:表示视频的时间基准信息。

  • (default):表示该流是默认的流。

  • handler_name: 表示是由 Google 公司开发的某个版本的处理程序生成或处理的。

AVStream结构有哪些元素?

AVStream 结构是 FFmpeg 中表示媒体流的数据结构,它包含了媒体流的各种属性和信息。下面是 AVStream 结构中一些常用的成员变量:

  • index:表示流的索引号。

  • id:表示流的唯一标识符。

  • codecpar:指向 AVCodecParameters 结构的指针,包含了与该流关联的编解码器参数。

  • time_base:表示流的时间基准,用于将时间单位转换为实际时间。

  • start_time:表示流的起始时间。

  • duration:表示流的时长。

  • nb_frames:表示流中的帧数。

  • disposition:表示流的布局或位置相关的标志。

  • avg_frame_rate:表示流的平均帧率。

  • r_frame_rate:表示流的参考帧率。

  • metadata:指向 AVDictionary 结构的指针,包含了流的元数据。

要使用 AVStream 结构,可以先通过 AVFormatContext 结构中的 streams 数组获取特定的 AVStream 结构,然后使用相应的成员变量获取所需的信息。例如,要获取流的索引号可以使用 avStream->index,获取流的时间基准可以使用 avStream->time_base,获取流的元数据可以使用 avStream->metadata

ffmpeg如何读取视频流?

ffmpeg需要先定位mp4中的视频流,从视频流stream中读取每一帧,将每一帧再转换为yuv格式。

go 复制代码
// 解码器
    AVCodec* codec = nullptr;
    AVCodecContext* codecContext = avcodec_alloc_context3(codec);

  // 寻找到视频流
    int videoStreamIndex = av_find_best_stream(inputContext, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0);
    if (videoStreamIndex < 0) {
        // 没有找到视频流
        return -1;
    }

    // 获取视频流
    AVStream* stream = inputContext->streams[videoStreamIndex];
           
    if (avcodec_parameters_to_context(codecContext, stream->codecpar) < 0) {
        // 获取解码器上下文失败
        return -1;
    }
    if (avcodec_open2(codecContext, codec, nullptr) < 0) {
        // 打开解码器失败
        return -1;
    }

    // 分配视频帧和 YUV 帧
    AVFrame* frame = av_frame_alloc();
    AVFrame* frameYUV = av_frame_alloc();
    int frameBufferSize = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, codecContext->width, codecContext->height, 1);
    uint8_t* frameBuffer = (uint8_t*)av_malloc(frameBufferSize * sizeof(uint8_t));
    av_image_fill_arrays(frameYUV->data, frameYUV->linesize, frameBuffer, AV_PIX_FMT_YUV420P, codecContext->width, codecContext->height, 1);

    // 初始化图像转换上下文
    struct SwsContext* swsContext = sws_getContext(codecContext->width, codecContext->height, codecContext->pix_fmt, codecContext->width, codecContext->height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, nullptr, nullptr, nullptr);
    // 读取视频帧并转换为 YUV 格式
    AVPacket packet;
    while (av_read_frame(inputContext, &packet) >= 0) {
        if (packet.stream_index == videoStreamIndex) {
            // 解码视频帧
            avcodec_send_packet(codecContext, &packet);
            avcodec_receive_frame(codecContext, frame);

            // 转换为 YUV 格式
            sws_scale(swsContext, frame->data, frame->linesize, 0, codecContext->height, frameYUV->data, frameYUV->linesize);

            // 在这里可以对 YUV 数据进行处理

            // 释放帧的引用
            av_frame_unref(frame);
        }

        av_packet_unref(&packet);
    }

ffmpeg如何定位到某个流的第几秒开始播放?

使用 av_seek_frame 函数:可以使用 av_seek_frame 函数在特定的时间点进行定位。这个函数可以用于音频和视频流。以下是一个示例代码片段,展示了如何使用 av_seek_frame 定位到指定的时间点:

go 复制代码
int64_t timestamp = desired_time * AV_TIME_BASE;  // 将秒转换为时间戳
int stream_index = 0;  // 假设我们要定位到第一个流

AVStream* stream = formatContext->streams[stream_index];
int64_t seek_target = av_rescale_q(timestamp, AV_TIME_BASE_Q, stream->time_base);

// 定位到指定时间点
av_seek_frame(formatContext, stream_index, seek_target, AVSEEK_FLAG_BACKWARD);

参考

5分钟入门MP4文件格式

相关推荐
问道飞鱼7 小时前
【工具介绍】Ffmpeg工具介绍与简单使用
ffmpeg·视频工具
l***775211 小时前
从MySQL5.7平滑升级到MySQL8.0的最佳实践分享
ffmpeg
ZouZou老师17 小时前
FFmpeg性能优化经典案例
性能优化·ffmpeg
aqi0020 小时前
FFmpeg开发笔记(九十)采用FFmpeg套壳的音视频转码百宝箱FFBox
ffmpeg·音视频·直播·流媒体
齐齐大魔王1 天前
FFmpeg
ffmpeg
你好音视频1 天前
FFmpeg RTSP拉流流程深度解析
ffmpeg
IFTICing1 天前
【环境配置】ffmpeg下载、安装、配置(Windows环境)
windows·ffmpeg
haiy20111 天前
FFmpeg 编译
ffmpeg
aqi002 天前
FFmpeg开发笔记(八十九)基于FFmpeg的直播视频录制工具StreamCap
ffmpeg·音视频·直播·流媒体
八月的雨季 最後的冰吻2 天前
FFmepg--28- 滤镜处理 YUV 视频帧:实现上下镜像效果
ffmpeg·音视频