ffmpeg 中 -f <format> 字段的意义

ffmpeg 中 -f <format> 字段的意义
----------------------------------------
author: hjjdebug
date: 2022年 10月 23日 星期日
----------------------------------------

我见到过的-f force format
-f mpegts
-f decklink
-f x11grab
-f alsa
-f hls

当然还有很多...

这里有三个常见问题,
1. 这些format 到底是什么意思? 答: 是文件格式的意思.
2. 我怎么知道有多少种formats?  答: ffmpeg -formats 可以列出所有的formats, 它就是muxer,demuxer支持的格式总和.
3. 这些参数能省略吗?             答: 能.

对于输入,如果不指定-f, ffmpeg 会根据输入数据(来自于输入文件,或输入设备或其它协议)来判断数据的封装格式.

对于输出,如果不指定-f, ffmpeg 也可以通过输出文件名进行推导.

如果指定了-f 选项, 则-f 后跟的参数会被存储到
struct OptionsContext
{
    ...
    const char *format;
    ...
}

以输入为例,该format 字符串, 打开文件的时候如果其不为空,会被用来查找对应的格式.
    if (o->format) {
        if (!(file_iformat = av_find_input_format(o->format))) {   
            av_log(NULL, AV_LOG_FATAL, "Unknown input format: '%s'\n", o->format);
            exit_program(1);
        }
    }

查找对应格式之法: 也是判定格式字符串是否合法之法为枚举.
AVInputFormat *av_find_input_format(const char *short_name)
{
    const AVInputFormat *fmt = NULL;
    void *i = 0;
    while ((fmt = av_demuxer_iterate(&i))) // 在所有的demuxer中枚举
        if (av_match_name(short_name, fmt->name)) // 匹配上名字就可以了.
            return (AVInputFormat*)fmt;
    return NULL;
}


正确的format会返回一个file_iformat,这是一个AVInputFormat 结构,该指针会被传递给avformat_open_input,


输入文件格式file_iformat 会在avformat_open_input 时进一步判断,当发现还没有确定,会进行探测.
如果没有 -f 项, 则 avformat_open_input 的 file_iformat=0

err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
    如果输入文件格式为空,需要探测文件格式
    if(!format_opts)
        file_iformat = av_probe_input_format2(&pd, 0, &score))
    探测之法为枚举:

    while ((fmt1 = av_demuxer_iterate(&i))) {    // 在所有的demuxer 中枚举
        score = 0;
        if (fmt1->read_probe) {                    // 根据数据进行探测, 这需要下一层具体的fmt 根据实际数据判断
            score = fmt1->read_probe(&lpd);

            if (score)
                av_log(NULL, AV_LOG_TRACE, "Probing %s score:%d size:%d\n", fmt1->name, score, lpd.buf_size);

        }
    }    
    这里保留下最高的得分即为探测到的格式.

所以,不管是判定格式字符串是否合法,还是根据数据自动查找格式,用到的方法都是枚举!

### 如何在 FFmpeg 中处理元数据 #### 使用命令行操作元数据 FFmpeg 提供了强大的命令行工具来读取、修改和删除媒体文件中的元数据。可以通过 `-metadata` 参数指定新的元数据键值对,或者使用 `map_metadata` 来复制或移动元数据[^1]。 以下是设置元数据的一个简单例子: ```bash ffmpeg -i input.mp4 -metadata title="New Title" -metadata artist="Artist Name" output.mp4 ``` 如果需要清除所有的现有元数据,则可以使用 `-map_metadata -1` 参数: ```bash ffmpeg -i input.mp4 -c copy -map_metadata -1 output.mp4 ``` #### 编程接口访问元数据 除了命令行外,在编程环境中也可以通过 FFmpeg 的 API 访问和操作元数据。这通常涉及初始化 `AVFormatContext` 和遍历其内部的字典结构以获取或更新元数据字段[^5]。 下面是一个简单的 C 代码片段展示如何打印输入文件的元数据: ```c #include <libavformat/avformat.h> int main(int argc, char *argv[]) { AVFormatContext *fmt_ctx = NULL; if (argc != 2) { printf("Usage: %s <input_file>\n", argv[0]); return -1; } if (avformat_open_input(&fmt_ctx, argv[1], NULL, NULL) != 0) { fprintf(stderr, "Could not open file '%s'\n", argv[1]); return -1; } av_dump_format(fmt_ctx, 0, argv[1], 0); // 遍历并打印元数据 AVDictionaryEntry *tag = NULL; while ((tag = av_dict_get(fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { printf("Metadata key='%s' value='%s'\n", tag->key, tag->value); } avformat_close_input(&fmt_ctx); return 0; } ``` 上述程序会打开一个多媒体文件,并将其顶层容器级元数据显示出来。注意这里使用的 `AVFormatContext` 是 FFmpeg 处理 I/O 文件的核心上下文对象之一。 对于更复杂的场景比如帧级别的自定义标签存储,可能还需要结合 `AVStream` 或者其他特定的数据结构以及回调机制完成进一步开发需求[^3]。 #### 关于编码过程中的元数据传递 当涉及到重新编码时,某些情况下默认不会自动继承源文件的所有属性到目标文件上,因此需要显式声明保留哪些部分的信息。例如调用 `avcodec_send_frame()` 后紧接着接收包的过程中也可能附带一些额外描述性的参数被写入最终产物里去[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值