自动选择规则

ffmpeg在处理视频时,如果只提供了输入和输出参数,ffmpeg会自动地去选择相应的视频流和音频流来合成文件

自动选择的方式根据如下规则:

  • 视频流:选分辨率最高的,比如有两个视频,一个是1080,一个是720,会选择1080的作为默认的视频流
  • 音频流:选通道数最多的,比如两个视频,一个无声音,一个有声音,会自动选择有声音的音频流作为最终的输出,如果A视频是1080无声音,B视频是720有声音,那么最终输出的文件画面是A视频的,声音是B视频的
  • 字幕:选第一个被检索到的字幕流,如果两个视频都有字幕,那就是第一个输入的第一个字幕流,其它的忽视

为了验证上面的规则,来做个测试:

现有两个视频文件noaudio.mp4和normal.mp4

其中noaudio.mp4是720分辨率,没有声音, normal.mp4是360分辨率,有声音

执行如下命令:

ffmpeg -v quiet -i noaudio.mp4 -i normal.mp4 out.mp4

结果:out的画面是noaudio.mp4的,而声音是normal.mp4的

map指令

ffmpeg的自动选择规则,显然并不能总是符合需求,所以有了map指令

官方文档描述如下:

When -map is used, only user-mapped streams are included in that output file(只有被用户选择的流才会被用到输出文件中)

同样拿上面的两个文件,做以下测试

ffmpeg -i noaudio.mp4 -i normal.mp4 -map 1:a -acodec copy out.mp4

-map 1:a的意思是:输出文件的音频使用第二个文件的音频,这次,在out.mp4中,虽然是mp4格式文件,但是只有声音,没有画面

再做个测试

ffmpeg -i noaudio.mp4 -i normal.mp4 -map 1:a -acodec copy -vcodec copy out.mp4

这次指定了视频的编码方式,使用原视频编码方式不重新编码,然而out文件依然只有声音

再做测试

ffmpeg -i noaudio.mp4 -i normal.mp4 -map 1:a -map 0:v -acodec copy -vcodec copy out.mp4

这次用0:v来指定输出文件使用第一个文件的视频,这次out是第一个文件的画面,第二个文件的声音

那现在再考虑一个问题:如果指定使用第一个文件(noaudio.mp4)的音频会如何呢

继续测试:

ffmpeg -i noaudio.mp4 -i normal.mp4 -map 0:a -map 1:v -acodec copy -vcodec copy out.mp4 -y

执行时出错了,提示如下:

Stream map '0:a' matches no streams.
To ignore this, add a trailling '?' to the map

意思是指定的音频没有匹配到,但是可以加个问题忽略这个map,那加上"?"尝试一下:

ffmpeg -i noaudio.mp4 -i normal.mp4 -map 0:a? -map 1:v -acodec copy -vcodec copy out.mp4 -y

这次成功执行,但是out中只有画面,没有声音,说明问号的功能仅仅是忽视这个map,并不会重新选择新的音频

未命名滤镜如何处理

现在有两个文件:ftwo.mp4是720分辨率,scale.mp4是360分辨率。

overlay是水印滤镜,咱们之前的文章中已经讲过了,如果不清楚可以去看。

执行下面命令:

ffmpeg -i ftwo.mp4 -i scale.mp4 -filter_complex "overlay" out.mp4 -y

out.mp4文件中,scale.mp4覆盖到ftwo.mp4的左上角,声音用的是scale.mp4的

把两个文件的输入顺序颠倒一下试试:

ffmpeg -i scale.mp4 -i ftwo.mp4 -filter_complex "overlay" out.mp4 -y

这次是ftwo.mp4覆盖住了scale.mp4,由于scale.mp4分辨率小,所以scale.mp4被完全覆盖住,画面也只截了ftwo.mp4左上角640*360的画面,而不是1280*720。

但是声音依然用的是scale的声音,因为scale.mp4时长是是10s,而ftwo.mp4时长是17秒,在合成时ffmpeg会默认用时长较短的那个文件作为输出文件的时长,对应的音频也用这个,所以上面两个输出文件的时长都是10s,ftwo后面的视频就被截断了。

有命名的滤镜如何处理

看这个命令:

ffmpeg -i ftwo.mp4 -i three_scale.mp4 -i oness_scale.mp4 \
-filter_complex "[1:v]hue=s=0[out];overlay;aresample" \
-map '[out]' -an out1.mp4

这里有个命名的滤镜:out,它将第二个输入文件的颜色饱和度s设置为0。

还有两个未命名的滤镜:overlay、aresample

命令执行完,发现out1.mp4是ftwo.mp4的画面和声音。

为什么会这样呢?map和an指令没起作用。

根据官方文档解释,因为有两个未命名滤镜,所以ffmpeg会把这两个未命名的滤镜结果直接输出给第一个输出文件,也就是out1,这时会忽略map指令。

至于an指令,这个指令只作用于自动选择音频流时或手动指定了音频流,对于滤镜输出的流是不起作用的,所以这里也会忽视掉an。

基于以上解释,这里虽然用了out滤镜,但是其并没起作用,第二个输入文件也等于没用。

咱们改一下命令再试试:

ffmpeg -i ftwo.mp4 -i three_scale.mp4 -i oness_scale.mp4 \
-filter_complex "[1:v]hue=s=0[out];overlay;aresample" \
-map '[out]' -an out1.mp4 out2.mp4

结果out1与上面一样,out2是第一个输入文件的画面,第二个输入文件的声音。

这是因为out2前面没有map,所以触发了ffmpeg的自动选择规则,默认用第一个文件的画面,由于第二个文件的时长短,所以将第一个文件截断了,且用的第二个文件的声音。

再改一下命令,既然map和an没用,就去掉

ffmpeg -i ftwo.mp4 -i three_scale.mp4 -i oness_scale.mp4 \
-filter_complex "[1:v]hue=s=0[out];overlay;aresample" \
out1.mp4 out2.mp4

然而这次出错了:

Filter hue has an unconnected output

错误意思是:out滤镜没有指定输出文件。

这说明一旦指定了命名滤镜,就必须用上

再改下命令

ffmpeg -i ftwo.mp4 -i three_scale.mp4 -i oness_scale.mp4 \
-filter_complex "[1:v]hue=s=0[out];overlay;aresample" \
-map '[out]' -an out1.mp4 out2.mp4 \
-map '[out]' -map 0:a:0 out2.mp4

这次将滤镜用了两次,再次报错:

Output with label 'out' does not exist in any defined filter graph,or was already used elsewhere.

意思是滤镜没用过或者已经用过了,这说明一个滤镜只能使用一次,且必须使用一次

既然如此,咱们只能将滤镜分开了,修改命令如下:

ffmpeg -i ftwo.mp4 -i three_scale.mp4 -i oness_scale.mp4 \
-filter_complex "[1:v]hue=s=0,split=[out1][out2];overlay;aresample" \
-map '[out1]' -an out1.mp4 \
-map '[out2]' -map 0:a:0 out2.mp4

这次用split将同一个滤镜分成了两个,分别使用,第一个上面已经分析过,不起作用。

第二个滤镜起作用了,且根据后面的map,使用了第一个输入文件的第一个音频,所以out2是二个文件的画面,第一个文件的音频,这下怎么用清楚了吗。

ffmpeg系列文章目录

ffmpeg第1篇:日志级别控制、保存日志到指定文件、处理进度查询

ffmpeg第2篇:简单滤镜与复杂滤镜的区别

ffmpeg第3篇:为视频添加静态水印

ffmpeg第4篇:为视频添加动态水印

ffmpeg第5篇:让水印图片旋转起来

ffmpeg第6篇:滤镜语法

ffmpeg第7篇:数据流选择神器-map指令

番外篇

ffmpeg番外篇:听说这款水印曾经在某音很火?办它!

有问题请留言沟通,欢迎转载,转载请注明出处

更多精彩内容,欢迎点击个人博客地址:愉快编程

ffmpeg第7篇:数据流选择神器-map指令的更多相关文章

  1. ffmpeg第6篇:滤镜语法

    前言 哈哈,回来继续填坑了,前段时间较忙没时间写,现在继续~ 简介 滤镜是ffmpeg的一个很强大的功能,它支持许多有用的视频处理功能,常见的滤镜如:缩放.旋转.水印.裁剪等 一个比较经典的滤镜使用方 ...

  2. 第20篇-加载与存储指令之ldc与_fast_aldc指令(2)

    ldc指令将int.float.或者一个类.方法类型或方法句柄的符号引用.还可能是String型常量值从常量池中推送至栈顶. 这一篇介绍一个虚拟机规范中定义的一个字节码指令ldc,另外还有一个虚拟机内 ...

  3. 第32篇-解析interfacevirtual字节码指令

    在前面介绍invokevirtual指令时,如果判断出ConstantPoolCacheEntry中的_indices字段的_f2属性的值为空,则认为调用的目标方法没有连接,也就是没有向Constan ...

  4. 第34篇-解析invokeinterface字节码指令

    与invokevirtual指令类似,当没有对目标方法进行解析时,需要调用LinkResolver::resolve_invoke()函数进行解析,这个函数会调用其它一些函数完成方法的解析,如下图所示 ...

  5. 震惊--Nginx的map指令还能这样用

    map指令简单介绍 当然这里写的都是官方文档是已经写过的,我简单抄一下哈. map指令来自于 ngx_http_map_module 模块,提供的核心能力是 基于一个变量创建一个新变量,大概是这意思. ...

  6. 深入学习jQuery选择器系列第三篇——过滤选择器之索引选择器

    × 目录 [1]通用形式 [2]首尾索引 [3]奇偶索引[4]范围索引 前面的话 上一篇介绍了过滤选择器中的子元素选择器部分,本文开始介绍极易与之混淆的索引选择器 通用形式 $(':eq(index) ...

  7. 深入学习jQuery选择器系列第二篇——过滤选择器之子元素选择器

    × 目录 [1]通用形式 [2]反向形式 [3]首尾元素 [4]唯一元素 前面的话 在上一篇中已经介绍过基础选择器和层级选择器,本文开始介绍过滤选择器.过滤选择器是jQuery选择器中最为庞大也是最为 ...

  8. ${mapred.local.dir}选择策略--Map Task存放中间结果

    上篇说了block在DataNode配置有多个${dfs.data.dir}时的存储策略,本文主要介绍TaskTracker在配置有多个${mapred.local.dir}时的选择策略. mapre ...

  9. Java提高篇(三三)-----Map总结

    在前面LZ详细介绍了HashMap.HashTable.TreeMap的实现方法,从数据结构.实现原理.源码分析三个方面进行阐述,对这个三个类应该有了比较清晰的了解,下面LZ就Map做一个简单的总结. ...

随机推荐

  1. PHP垃圾回收机制的一些浅薄理解

    相信只要入门学习过一点开发的同学都知道,不管任何编程语言,一个变量都会保存在内存中.其实,我们这些开发者就是在来回不停地操纵内存,相应地,我们如果一直增加新的变量,内存就会一直增加,如果没有一个好的机 ...

  2. 解决IE浏览器 点击子元素重复调用执行 mouseover 与mouseout兼容性问题

    将函数配对换为下面2个就可以解决兼容性问题. mouseenter() mouseleave(0

  3. 【Azure 应用服务】App Service For Linux 部署PHP Laravel 项目,如何修改首页路径为 wwwroot\public\index.php

    问题描述 参考官方文档部署 PHP Laravel 项目到App Service for Linux环境中,但是访问应用时候遇见了500 Server Error 错误. 从部署的日志中,可以明确看出 ...

  4. FreeRTOS-06-信号量

    说明 本文仅作为学习FreeRTOS的记录文档,作为初学者肯定很多理解不对甚至错误的地方,望网友指正. FreeRTOS是一个RTOS(实时操作系统)系统,支持抢占式.合作式和时间片调度.适用于微处理 ...

  5. whistle手机抓包(以安卓手机为例)

    环境:whistle:1.14.6 whistle手机抓包 以安卓手机为例 手机跟电脑要连同一个wifi. 1.启动whistle 使用w2 start启动whistle. 退出cmd后,whistl ...

  6. CF803G-Periodic RMQ Problem【离散化,线段树,ST表】

    正题 题目链接:https://www.luogu.com.cn/problem/CF803G 题目大意 一个长度为\(n\)的序列\(a\)复制\(k\)份连接,要求支持 区间赋值 区间查询最小值 ...

  7. python爬虫抓取中国最好大学排名1 清华大学 北京 94.0 100.0 97.70% 清华大学 2 北京大学

    import requests from bs4 import BeautifulSoup import bs4.element r=requests.get("http://www.zui ...

  8. Java 将Word转为HTML的方法

    本文介绍如何在JAVA程序中将Word文档通过 Document.saveToFile() 方法转换为HTML文档.编辑代码前,参考如下环境配置,导入jar包. [程序环境] 1. IntelliJ ...

  9. 从零入门 Serverless | Knative 带来的极致 Serverless 体验

    作者 | 冬岛 阿里巴巴高级技术专家 Serverless 公众号后台回复"knative",即可免费下载<Knative 云原生应用开发指南>电子书! 导读:Serv ...

  10. 遇到括号就是栈(bushi)

    CF508E Arthur and Brackets 我在赛场上想都没想直接DP \(O(n^3)\)过了 但别人说正解是栈+贪心 讲讲DP \(bool\) \(dp[i][j]\)表示从第i对括号 ...