流的操作(一)视频转音频引发的血案

转发自白狼栈:查看原文

有些小伙伴看文章非常细心,对于上一节课不经意提到的一些边缘细节都比较在意,比如 -acodec、-vcodec、流复制等。其实这些都离不开我们今天要讲的重点——流。

说起流,可能有很多小伙伴第一反应是流媒体,但是我们今天要说的是容器内流的类型。通过前面的介绍,相信你对容器内的音频(audio, a)和视频(video, v)都有了一些印象。除此之外,容器内流的类型还有字幕(subtitle, s)、附加数据(attachment, t)和普通数据(data, d)。我们重点介绍一下音频流、视频流和字幕流。

流的操作,指的是我们可以从输入文件中选择不同的流进行操作,然后输出我们想要的结果。

举个例子,家里有小孩的都应该比较清楚,学校现在有很多英语的配音比赛,大屏幕播放一段视频,学生在舞台上配音,非常形象。

在这个场景中,大屏幕上播放的视频,其实就是无声视频。无声视频并不是把声音调到最小,它指的是没有音频的视频,这样播放的视频只有画面。比方说对于前文案例一的素材视频可以通过 -an 的命令去除音频流,只保留视频流即只有画面(没有下载的可以点击这里下载)。

ffmpeg -i r1ori.mp4 -an -y r1-silent.mp4

来看下结果视频r1-silent.mp4的信息,没有了 Stream #0:1(und): Audio 的信息。

» ffmpeg -i r1-silent.mp4 -hide_banner 
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1-silent.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512 compatible_brands: isomiso2avc1mp41
    encoder         : Lavf58.20.100 Duration: 00:00:58.53, start: 0.000000, bitrate: 1687 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 544x960, 1684 kb/s, 29.83 fps, 29.83 tbr, 11456 tbn, 59.67 tbc (default)
    Metadata:
      handler_name    : VideoHandler
At least one output file must be specified

现在即使你把音响抱过来,声音加到最大播放这个视频,也不会听到任何声音。

-an 即 -acodec none。a指的是audio,codec指的是解码器,-acodec就是音频解码器,合起来就是不指定音频解码器,回顾下我们在ffmpeg是怎么转码的一文介绍的转码流程就很容易理解了。

你应该已经猜到了,类似的我们还可以去除视频流、字幕流等。

  1. -an 去除音频流
  2. -vn 去除视频流
  3. -sn 去除字幕流
  4. -dn 去除数据流

有同学可能注意到了,我们的原视频的时长是59秒,还不到一分钟,但是 -an 的一条命令要花上十几秒的处理时间,太慢了,有没有办法优化下?

你仔细思考下,那么慢,时间花在哪里了?对,就是重新编码。

这里我们只是去除音频流,有必要重新编码吗?没有,所以如果我们可以把视频流复制出来是不是就好了?

优化后的命令如下

ffmpeg -i r1ori.mp4 -an -vcodec copy -y r1-silent.mp4

这条命令瞬间就输出结果了。我们添加了一个参数 -vcodec copy。-vcodec指的是视频解码器,v是视频video,codec是解码器,后跟解码器名称,copy复制输入的视频流,不作解码处理。

同样,如果我们想提取视频中的音频,或者说把视频转成音频,是不是可以用下面这条命令?

ffmpeg -i r1ori.mp4 -vn -c:a copy -y r1-silent.mp3

执行该命令后发现报错了

Invalid audio stream. Exactly one MP3 audio stream is required. 
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument

提示我们音频流无效,原因是codec的参数错误。我们看下原视频的信息

» ffmpeg -i r1ori.mp4 -hide_banner 
...... 
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 129 kb/s (default) 
......

注意音频流这行信息,我们发现音频流是aac格式的,而我们要输出的是mp3格式的,-c:a copy 参数意味着我们想要把aac格式的音频流装进mp3容器,这是不可行的。aac 音频流需要一个专用的 aac 容器,mp3 音频流需要专用的 mp3 容器。

注:aac 和 mp3 都是有损压缩音频编码格式。

找到原因就好办了,我们把输出的mp3格式修改成aac格式

ffmpeg -i r1ori.mp4 -vn -c:a copy -y r1-silent.aac

虽然mp4容器内的音频流大多数都是aac格式,但是,试想一下如果我们写好程序,要针对用户上传的视频提取音频并做存储,偏偏用户上传的原视频内的音频是mp3呢?

为了满足这一场景,我们制作一个含mp3格式的视频,然后再执行上面的命令试试。

1、把r1ori.mp4视频内的音频流转成mp3

ffmpeg -i r1ori.mp4 -c:a libmp3lame -c:v copy -y r2.mp4

注:由于ffmpeg没有原生的mp3编码器,所有我们指定了外部的libmp3lame编码库(虽然 -c:a libmp3lame 你也可以把libmp3lame改为mp3,实际上使用的还是libmp3lame)。如果你执行上面的命令报了一个类似这样的错误 ERROR: libmp3lame >= 3.98.3 not found,说明你本地的ffmpeg没有添加--enable-libmp3lame编译参数,可以参考这篇文章选择对应的方式重新安装ffmpeg;

2、提取该视频的音频

ffmpeg -i r2.mp4 -vn -c:a copy -y r1-silent.aac 
报错:Only AAC streams can be muxed by the ADTS muxer 
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument

所以,-c:a copy 不是万能的,也就是说如果我们想让视频转音频,最好指定一种编码器,用aac还是libmp3lame?就音质质量而言,我们更推荐libmp3lame,尽管ffmpeg自带的最好音频编码器是aac。

综上,如果你需要输出mp3格式的音频,你可以使用

ffmpeg -i r1ori.mp4 -vn -c:a libmp3lame -y r1-silent.mp3

如果你想输出aac格式的音频,你可以使用

ffmpeg -i r1ori.mp4 -vn -c:a aac -y r1-silent.aac

注:新版本的ffmpeg是支持原生aac编码的,所以可以直接使用 -c:a aac,低版本的ffmpeg像2.x的版本原生aac编码器是不完全支持的,必须同时指定 -strict -2 才可以使用。

以上,我们介绍了手动指定音频解码器,成功的将视频转换成了音频。

既然ffmpeg那么厉害,那如果我们不手动指定,它能自动帮我们选择合适的解码器处理吗?

非常可以。

以mp3为例,我们试下

ffmpeg -i r1ori.mp4 -y r1-silent.mp3 
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'r1ori.mp4': 
...... 
Stream mapping: Stream #0:1 -> #0:0 (aac (native) -> mp3 (libmp3lame)) 
......

注意看输出的过程代码中包含 Stream mapping 以及其下一行代码,可以看出ffmpeg的确自动为我们选择了libmp3lame解码器。

如果原视频有多路音频流,又该如何操作呢?我们下节课再说。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容