ffmpeg 随笔
浅谈ffmpeg
为什么要分享这个玩意
One day, 我在Mac上下载了一部电影,然后想拷贝到U盘中,然后再连接电视上的接口。这时候呢,正当我要拷贝电影的时候,遇到了我的知识盲区了,为啥我的U盘能检测到,但是电脑上的文件没法往U盘里头送,但是U盘里面东西又可以往外面传呢?我尝试了下面几种方法:
- 翻箱倒柜,找出其他的U盘,一个个的试 ✖
- 给电脑加一个hub,然后把U盘插到hub上 ✖
- 尝试不同的Mac ✖
没法子了,只能Google一下了,其实就是格式的问题,U盘和移动硬盘一般都是NTFS格式的,而Mac是不支持这个格式磁盘的写入的,所以在Mac上无法拷贝文件到U盘。所以,要么就是格式化U盘,然后再重新刷U盘。
算了要不我直接在Mac上看吧,Mac上的唯一的播放器只有QuickTimer
, 但是此播放器能支持的格式又是有限了,下载的电影格式一般都是mkv
格式为主,所以QuickTime自然也就不支持的咯。这时候,解决办法想了两个。要么下载一个可以支持其他格式的播放器,要么就是转格式。我选择了后者,作为新生代农民工的我呢还是想要用自己的手艺来解决这个问题,那就是写代码搞定,其实是没有找到比较好的工具。
开始Google,how to convert mkv to mp4 in java
,
how to convert mkv to mp4 in python
,
~ in golang
从每个搜索结果中都能发现一个相同的工具ffmpeg, 很好奇这个是干嘛的的东西,大家就接着往下看吧
ffmpeg是什么
FFmpeg是一个免费的开源软件项目,由一套处理视频、音频和其他多媒体文件和流的库和程序组成。ffmpeg主要是被当做命令行工具来使用,ffmpeg主要用于处理视频和音频文件。它被广泛用于格式转换、基本编辑(修剪和拼接)、视频缩放、视频后期制作效果
FFmpeg除了本身的工具之外,实际上是被分成了是三个工具
ffmpeg
,ffprobe
以及ffplay
。ffprobe主要用于分析流媒体数据,提取流媒体中的音视频信息,ffplay是ffmpeg开发的minimal的视频播放器,但是这三类工具都是命令行工具,对于不太了解计算机的同学来说不是特别的友好。ffmpeg整体都是基于
C++
开发的一套框架,因为是开源项目,所以有很大的DIY空间。于此同时,对于不太熟悉C++
的同学来说,如果想用ffmpeg来做一些二次开发,现在也有很多其他语言的wrapper包,以下这几个是star数比较多,而且提了issue作者会给回答的项目:
这里还有一个小提醒给大家,ffmpeg这么好用,其实很多的播放器都是基于了ffmpeg做了二次开发,那么对于使用ffmpeg的开发者来说,就有一条不成文的规则,如果你使用了这个框架,你就需要开源你的项目,否则你可能会被钉在ffmpeg的Hall of Shame(耻辱柱)
下面给大家顺带说一下,ffmpeg中使用的一些高频率的library
- libavcodec, 提供了一个通用的编码/解码框架,包含音频、视频和字幕流的多个解码器和编码器
- libavformat, 为音频、视频和字幕流的多路复用和解复用(muxing和demuxing)提供了一个通用框架
- libavfilter,音视频流的处理,包括视频的比特率修改,音频的频率的修改,以及多个视频的合并等等操作
- libavdevice,提供了一个通用框架,用于从许多常见的多媒体输入/输出设备抓取和呈现,并支持多种输入和输出设备,例如Video4Linux2、VfW、DShow和ALSA
ffmpeg的一些基础用法
安装
- 大家可以根据自己的平台下载对应的安装包,在ffmpeg官网可以直接下载
- 在Mac电脑上还可以使用
brew
直接安装,运行以下命令:brew install ffmpeg
使用
ffplay
ffplay使用方式非常简单,这里给大家介绍一些简单的命令
ffplay <input source path>
这样就是以ffplay提供的默认设置播放视频ffplay -x -y <input source path>
这样就可以指定视频播放窗口的大小ffplay -fs <input source path>
视频开始以全屏模式播放
除此之外,ffplay还很多其他的option,大家如果有兴趣可以参照官网的说明尝试
ffprobe
ffprobe主要就是用于分析流媒体中的信息,比如说,你想知道,该视频中有几个视频流,有几个音频流,以及各自的编码方式是什么,等等诸如此类的东西,再给大家分享一些简单的命令
ffprobe -v error <input source path> -show_format
, 用这个命令你就可以看到你这个容器中的流媒体的一些基本数据,如果你觉得用默认格式输出不好看的话,还可以添加一个参数,-print_format json
,其中的参数v
代表的是verbose- json文件中展现了container的信息,其中包括了container的文件名称,bitrate等等
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20{
"format": {
"filename": "bullfinch.mov",
"nb_streams": 2,
"nb_programs": 0,
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
"format_long_name": "QuickTime / MOV",
"start_time": "0.000000",
"duration": "5.022000",
"size": "143724856",
"bit_rate": "228952379",
"probe_score": 100,
"tags": {
"major_brand": "qt ",
"minor_version": "512",
"compatible_brands": "qt ",
"encoder": "Lavf58.45.100"
}
}
}
- json文件中展现了container的信息,其中包括了container的文件名称,bitrate等等
ffprobe -v error <input source path> -show_streams
这里会展示出所有的stream的信息,所以使用参数-select_streams
来选择某一种流媒体,再在后面添加一个v
或者a
。前者代表是video,后者是audio- 视频流的数据,这里会列出当前流媒体中视频流中的编码方式等等数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63{
"streams": [
{
"index": 0,
"codec_name": "prores",
"codec_long_name": "Apple ProRes (iCodec Pro)",
"profile": "HQ",
"codec_type": "video",
"codec_tag_string": "apch",
"codec_tag": "0x68637061",
"width": 1920,
"height": 1080,
"coded_width": 1920,
"coded_height": 1080,
"closed_captions": 0,
"film_grain": 0,
"has_b_frames": 0,
"sample_aspect_ratio": "1:1",
"display_aspect_ratio": "16:9",
"pix_fmt": "yuv422p10le",
"level": -99,
"color_range": "tv",
"field_order": "progressive",
"refs": 1,
"id": "0x1",
"r_frame_rate": "30000/1001",
"avg_frame_rate": "30000/1001",
"time_base": "1/30000",
"start_pts": 0,
"start_time": "0.000000",
"duration_ts": 150150,
"duration": "5.005000",
"bit_rate": "229589904",
"bits_per_raw_sample": "10",
"nb_frames": "150",
"disposition": {
"default": 1,
"dub": 0,
"original": 0,
"comment": 0,
"lyrics": 0,
"karaoke": 0,
"forced": 0,
"hearing_impaired": 0,
"visual_impaired": 0,
"clean_effects": 0,
"attached_pic": 0,
"timed_thumbnails": 0,
"captions": 0,
"descriptions": 0,
"metadata": 0,
"dependent": 0,
"still_image": 0
},
"tags": {
"language": "eng",
"handler_name": "VideoHandler",
"vendor_id": "FFMP",
"encoder": "Lavc58.91.100 prores_ks"
}
}
]
} - 如果我们想过滤一些只有我们关心的数据,可以使用
-show_entries stream=codec_name,codec_type,duration
,来选择我们想要的数据,这样返回的数据就会比较简洁1
2
3
4
5
6
7
8
9
10
11
12{
"programs": [
],
"streams": [
{
"codec_name": "prores",
"codec_type": "video",
"duration": "5.005000"
}
]
}
- 视频流的数据,这里会列出当前流媒体中视频流中的编码方式等等数据
ffmpeg
ffmpeg应该来说是这个里面BOSS了,能干的事情简直是太多了,比如说转换格式,剪辑视频,合并视频,添加视频的overlay,替换流媒体的音频,操作音频(合并声道,修改声道),生成playback文件等等
- 转换格式就是ffmpeg非常基础的技能了,
ffmpeg -v error -y -i <input source path> <output file name>.mp4
。以下的场景是我们在网络上下载了一段视频,扩展名是mkv
。这个显然是无法在Mac直接播放的我们来使用ffmpeg的转换技能,把1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29{
"programs": [
],
"streams": [
{
"codec_name": "h264",
"codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"
}
],
"format": {
"filename": "test.mkv",
"nb_streams": 2,
"nb_programs": 0,
"format_name": "matroska,webm",
"format_long_name": "Matroska / WebM",
"start_time": "0.000000",
"duration": "5.016000",
"size": "1941253",
"bit_rate": "3096097",
"probe_score": 100,
"tags": {
"COMPATIBLE_BRANDS": "qt ",
"MAJOR_BRAND": "qt ",
"MINOR_VERSION": "512",
"ENCODER": "Lavf59.16.100"
}
}
}mkv
格式的文件转换成mov
,ffmpeg -v error -y -i test.mkv test.mov
,这里不用指定流的编码方式,因为在转换的过程中会设定默认的合适的codec方法,等上一会,视频就是转好了。当我点击的时候给我来了个这个,打开是能打开,但是看不了视频,只闻其声不见其人。我用ffprobe分析了一下stream的数据,发现codec的方式h264,quicktime是不支持的。
这时我添加了一个参数ffmpeg -v error -y -i test.mkv -vcodec prores test.mov
。这波操作,OK了,可以打开了
这时又有细心的朋友发现了些啥,为啥同样视频只是经过了一次转换,大小相差这么大。具体原因是啥呢,我再用ffprobe分析一波。原来是因为
bitrate
相差了很多哦,这玩意就是用来决定视频的清晰度的。查了一下文档,原来ffmpeg在不设定bitrate的时候,为了加快转换速度自己又自作主张的加了点戏,减少了一些bitrate。那如果我想保持原来的大小该怎么办呢?这里我们可以使用`two-pass`的方式来设置想要转换的视频的bitrate的大小
1
2ffmpeg -v error -y -i test.mkv -vcodec prores -b:v 4M -pass 1 -f null /dev/null
&& ffmpeg -v error -y -i test.mkv -vcodec prores -b:v 4M -pass 2 test.mov
心得
故事讲到这里,算是已经都讲完了,也实现了在Mac上直接播放的愿望。其实在学习ffmpeg的过程中还是了解到了很多图像相关的概念的,在这里我只是介绍了ffmpeg冰山一角的能力。当然在学习的过程中也越遇到一些自己一知半解的问题,如果大家有相关经验可以一块交流啊。
最后预祝大家新年快乐 !!!
- Title: ffmpeg 随笔
- Author: Xiao Qiang
- Created at : 2023-03-05 11:57:25
- Updated at : 2025-03-08 10:49:30
- Link: http://fdslk.github.io/tech/video/ffmpeg/2023/03/05/ffmpeg-simple-convert/
- License: This work is licensed under CC BY-NC-SA 4.0.