0%

vscode 扩展开发总流程

  1. 初始化插件项目
1
2
3
4
5
6
# 安装官方cli工具
npm install -g yo generator-code

# 生成项目脚手架
yo code
# 然后根据提示进行
  1. 调试插件
    编码完成后可以进行本地调试,点击 vscode 最左侧第 4 个 debug,然后点击运行按钮,会打开一个新的 vscode 窗口并自动安装编写好的插件,可以拖一个本地的项目文件夹进去,然后就可以愉快地调试了~

  2. 发布你的 vscode 扩展
    打包插件,生成 vsix 文件:

1
2
3
4
5
6
7
8
9
# 安装vscode插件打包工具
npm i -g vsce

# 代码检查,这里最好用eslint格式化一下,避免发布时验证不通过
# 首选项 Eslint > Format: Enable 打勾。代码里右键格式化方式选用Eslint
yarn lint

# 打包生成vsix文件
vsce package

然后目录下会得到 xxx-0.0.1.vsix 的文件,.vsix 文件就是 vscode 插件标准格式。在 vscode 左侧边栏扩展中,点击更多操作,有一个“从 VSIX 安装”,可以直接安装本地的插件。

python 读取 pdf 字体列表

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
from PyPDF2 import PdfReader
import PyPDF2
from pprint import pprint

def walk(obj, fnt, emb):
'''
If there is a key called 'BaseFont', that is a font that is used in the document.
If there is a key called 'FontName' and another key in the same dictionary object
that is called 'FontFilex' (where x is null, 2, or 3), then that fontname is
embedded.

We create and add to two sets, fnt = fonts used and emb = fonts embedded.
'''
if not hasattr(obj, 'keys'):
return None, None
fontkeys = set(['/FontFile', '/FontFile2', '/FontFile3'])
if '/BaseFont' in obj:
fnt.add(obj['/BaseFont'])
if '/FontName' in obj:
if [x for x in fontkeys if x in obj]:# test to see if there is FontFile
emb.add(obj['/FontName'])

for k in obj.keys():
walk(obj[k], fnt, emb)

return fnt, emb# return the sets for each page

if __name__ == '__main__':
fname = 'liuyao.pdf'
pdf = PdfReader(fname)
fonts = set()
embedded = set()
for page in pdf.pages:
obj = page.get_object()
# updated via this answer:
# https://stackoverflow.com/questions/60876103/use-pypdf2-to-detect-non-embedded-fonts-in-pdf-file-generated-by-google-docs/60895334#60895334
# in order to handle lists inside objects. Thanks misingnoglic !
# untested code since I don't have such a PDF to play with.
if type(obj) == PyPDF2.generic.ArrayObject: # You can also do ducktyping here
for i in obj:
if hasattr(i, 'keys'):
f, e = walk(i, fonts, embedded_fonts)
fonts = fonts.union(f)
embedded = embedded.union(e)
else:
f, e = walk(obj['/Resources'], fonts, embedded)
fonts = fonts.union(f)
embedded = embedded.union(e)

unembedded = fonts - embedded
print('Font List')
pprint(sorted(list(fonts)))
if unembedded:
print('\nUnembedded Fonts')
pprint(unembedded)

常用

查看文件信息

查看视频文件的元信息,比如编码格式和比特率,可以只使用-i参数。
$ ffmpeg -i input.mp4
上面命令会输出很多冗余信息,加上-hide_banner参数,可以只显示元信息。
$ ffmpeg -i input.mp4 -hide_banner

下载 m3u8

1
2
3
4
5
6
7
8
9
10
11
12
13

# 合并ts文件,ts文件数量少、不需要key的时候可以用这种,
ffmpeg -i "1.ts|2.ts|3.ts|" -c copy xxx.mp4

# 也可以根据文件中指定的ts文件位置进行合并,不需要key
ffmpeg -i index.m3u8 -c copy xxx.mp4

# 需要key的要加上参数-allowed_extensions ALL
ffmpeg -allowed_extensions ALL -i index.m3u8 -c copy xxx.mp4


# -protocol_whitelist指定白名单协议,添加相应的协议即支持对应的文件来源
ffmpeg -allowed_extensions ALL -protocol_whitelist "file,http,https,tls,tcp,crypto" -i https://xxx/xxx/index.m3u8 -c copy xxx.mp4
  • 最后一种的参数是最全的,也是最常用的,支持本地、网络中的 m3u8 文件,支持需要 key 的、不需要 key 的

  • 文件名不一定非要是 index,文件后缀不一定非要是.m3u8,只要是文本文件,文件中包含了 ts 文件路径、所需 key 的路径的即可,路径支持相对路径、绝对路径、网络 url,相对路径是相对于当前使用的 m3u8 文件

  • 如果使用本地 m3u8(文本)文件,可以复制 index.m3u8 来改其中的 ts、key 的路径

  • 报错 Protocol ‘xxx’ not on whitelist ‘file,http,https,tls,tcp’! ,说明缺少该种协议设置,加到 whitelist 列表中即可

  • ffmpeg 合并 ts 文件快,但使用网络中的 m3u8 url 地址时,会先下载所需的 ts 文件,ffmpeg 不是专业的下载软件,下载速度慢,下载包含了大量 ts 的视频尤其慢。

  • 嫌慢的可以下载 m3u8 到本地,获取其中的 ts 路径列表、key 路径,转换为网络 url,使用迅雷任务组进行下载到本地,修改 m3u8 中的路径,使用本地 m3u8 文件进行 ts 合并。

  • 有的网站编码 ts 时使用了 key,解码 ts 进行合并时自然也需要使用 key,key 文件的路径在 m3u8 文件中。有的网站编码时没有使用 key,解码合并 ts 时自然也就不需要 key。

压缩音频文件

对于音频文件,可以通过降低比特率(使用-b:a或-ab):

1
2
ffmpeg -i audio_input.mp3 -ab 128k audio_output.mp3
ffmpeg -i audio_input.mp3 -b:a 192k audio_output.mp3

再次重申,一些常用的比特率有: 96k, 112k, 128k, 160k, 192k, 256k, 320k.值越大,文件所需要的体积就越大。

压缩视频文件

对于视频文件,选项就多了,一个简单的方法是通过降低视频比特率(通过-b:v):
ffmpeg -i video_input.mp4 -b:v 1000k -bufsize 1000k video_output.mp4
Note:视频的比特率和音频是不同的(一般要大得多)。

你也可以使用-crf参数(恒定质量因子),较小的 crf 意味着较大的码率。同时使用libx264编码器也有助于减小文件体积。这里有个例子,压缩的不错,质量也不会显著变化:
ffmpeg -i video_input.mp4 -c:v libx264 -crf 28 video_output.mp4
crf 设置为 20 到 30 是最常见的,不过您也可以尝试一些其他的值。

降低帧率在有些情况下也能有效(不过这往往让视频看起来很卡):
ffmpeg -i video_input.mp4 -r 24 video_output.mp4
-r指示了帧率(这里是 24)。

你还可以通过压缩音频来降低视频文件的体积,比如设置为立体声或者降低比特率:
ffmpeg -i video_input.mp4 -c:v libx264 -ac 2 -c:a aac -strict -2 -b:a 128k -crf 28 video_output.mp4
Note:-strict -2和-ac 2是来处理立体声部分的。

视频压缩

ffmpeg -i "raw.flv" -r 10 -b:a 32k 1.mp4
命令参数解释:
-i "raw.flv"表示输入,后面的文件名必须要用双引号;
-r 10表示 1 秒 10 帧;
-b:a 32k表示音频的码率为 32kb/s,即 4kB/s;
1.mp4表示输出保存的文件名。

视频压缩网页版

一个视频压缩网页,号称可以将视频压缩 90%,但本质上和你本地运行 ffmpeg 没什么差别的,用的命令是:
ffmpeg -i "input.mp4" -c:v libx264 -tag:v avc1 -movflags faststart -crf 30 -preset superfast "output.mp4"
https://tools.rotato.app/compress ​​​

转换媒体文件格式

ffmpeg 最让人称道常用的恐怕就是你轻而易举的在不同媒体格式之间进行自由转换了。你是要指明输入和输出文件名就行了,ffmpeg 会从后缀名猜测格式,这个方法同时适用于视频和音频文件

下面是一些例子:

1
2
3
4
ffmpeg -i video_input.mp4 video_output.avi
ffmpeg -i video_input.webm video_output.flv
ffmpeg -i audio_input.mp3 audio_output.ogg
ffmpeg -i audio_input.wav audio_output.flac

你也可以同时指定多个输出后缀,这样会同时输出多个文件.:
ffmpeg -i audio_input.wav audio_output_1.mp3 audio_output_2.ogg

想看支持的格式,可以用:
ffmpeg -formats

同样的,你可以使用-hide_banner来省略一些程序信息。

你可以在输出文件前使用-qscale 0来保留原始的视频质量:
ffmpeg -i video_input.wav -qscale 0 video_output.mp4

进一步,你可以指定编码器,使用-c:a(音频)和-c:v(视频)来指定编码器名称,或者写 copy 来使用与源文件相同的编码器:
ffmpeg -i video_input.mp4 -c:v copy -c:a libvorbis video_output.avi
Note:这样做会让文件后缀使人困惑,所以请避免这么做。

画中画,常用于在一个图片背景上面,覆盖一个视频

ffmpeg -re -i "bg.jpg" -vf "movie=sub.mp4,scale=400x400[test]; [in][test] overlay=x=main_w-500:y=main_h-500 [out]" -vcodec libx264 output.mp4

视频剪辑(抽取),保留所有参数

常用:

1
2
3
4
# 从某处到结束
ffmpeg -ss 00:12:59 -i "xxx.mp4" -c:v copy -c:a copy -copyts output.mp4
# 从某处到某处
ffmpeg -ss 00:12:59 -i "xxx.mp4" -c:v copy -c:a copy -copyts -to 00:13:59 output.mp4

参数解析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ffmpeg -i "input.mp4" -c:v copy -c:a copy -copyts -t 5100 output.mp4
## -i input 输入文件
## -c:v copy 复制视频流编码参数
## -c:a copy 复制音频流编码参数
## -c:v copy -c:a copy 无需重新编码,即可快速剪切/修剪
## -c copy (好像是a+v的copy)
## -copyts 保持时间戳不变
## -t 5100 截取从影片开始到5100秒=1h+25m
## -ss <time> 从time处开始截取
## -ss HH:MM:SS.MILLISECONDS 从time处开始截取
## -ss 01:02:03 从1小时的2分钟3秒开始截取
## -ss 40 -t 10 从第40秒开始提取10秒的视频
## -ss 40 -to 70 从第40秒到第70秒,提取30秒的视频。
## 注意:如果你同时使用 -t 和 -to,那么只有-t将被使用。
## 注意:当-ss放在-i参数前,其搜索到的时间点位置是不准确的,ffmpeg只能检索到目标时间点之前最近的某个点(上一个i帧开始的点)。当-ss参数在-i参数之后,ffmpeg会将视频重新解码,然后丢弃目标起始时间点之前的视频,这样截取的视频起始时间点才是准确的(但是前几秒可能会出现只有声音但画面卡住不动),但貌似执行速度会慢很多(可能是涉及到视频解码)
## 注意:开始时间 (-ss HH:MM:SS), 持续秒数 (-t duration), 结束时间 (-to HH:MM:SS), 和开始秒数 (-s duration)

假设我们有一个视频文件 input.mp4,我们想要将它转码成 output.mp4,并保持时间戳的一致性。我们可以使用如下命令:ffmpeg -i input.mp4 -c:v copy -c:a copy -copyts output.mp4

其中:
-i参数用于指定输入文件

-c:v copy和-c:a copy参数分别表示视频流和音频流的编码方式保持不变

-copyts参数表示复制时间戳。

最后的output.mp4是输出文件的名称。

-copyts用于将输入流的时间戳复制到输出流中,时间戳是媒体文件中每个音视频帧的时间信息,它用于确定帧的播放顺序和时长。使用-copyts参数的好处是可以确保输出文件的时间戳与输入文件保持一致,避免时间戳错乱导致播放问题,这对于一些需要保持时间顺序的操作非常重要,比如合并多个视频文件、剪辑视频等。如果不使用-copyts参数,输出文件的时间戳可能会重新计算,导致播放顺序错误。

除了在转码和处理视频时使用-copyts参数外,它还可以在直播流媒体传输中使用。在直播传输中,时间戳的准确性对于保持流畅的播放非常重要。使用-copyts参数可以保证传输过程中时间戳的准确性,避免播放卡顿或错位的问题。

FFMPEG 解决截取 MP4 视频的中间段时,截取完成后前几帧视频卡住,但是有声音的情况:

这段时间在用 FFMPEG 处理视频的时候真的是爽的飞起,直到昨晚遇到了标题的那种情况。找了半天没发现问题在哪,最后在一个 B 站的剪切视频的教学视频的评论区找到了答案,大致如下:因为 I 帧的关系,视频解码时从I帧开始的,如果你的开始时间点不是I帧,则只先解码音频,等到下一个 I 帧时间点时,开始播放视频,之前卡的那个画面也是下一个 I 帧。可以用 aegisub 看 I 帧,知道前后 I 帧的位置,决定从哪个 I 帧开始截取,或者把-ss 写在-i 前面,会自动寻找最近 I 帧开始,话说音频也有帧,所以无损截取算是应急补救之法,但此时不能用-to,只能用-t。自己玩玩看!大彻大悟!
参考地址:https://www.bilibili.com/video/BV1ts411C7sN?spm_id_from=333.337.search-card.all.click&vd_source=b1fee33b8eac09fb7c96674a0b2399bb

评论:
一心月 回复 @Jinyeons :因为 I 帧的关系,视频解码时从 I 帧开始的,如果你的开始时间点不是 I 帧,则只先解码音频,等到下一个 I 帧时间点时,开始播放视频,之前卡的那个画面也是下一个 I 帧。可以用 aegisub 看 I 帧,知道前后 I 帧的位置,决定从哪个 I 帧开始截取,或者把-ss 写在-i 前面,但此时不能用-to,只能用-t。自己玩玩看!

一心月 回复 @Jinyeons :而如果你设定的时间段中没有 I 帧的话,那就只获取到音频,没有视频!目前没有工具可以做,但是理论上可以做到只需要编码新的 I 帧,以及修改这个 GOP 段内的相关索引。

三年寝太郎 回复 @一心月 :我用 aegisub 看前一帧了啊,甚至提前两帧,截取后还是只有音频,视频卡顿延迟甚至第四帧才出,没有好的解决方案吗

一心月 回复 @三年寝太郎 :要么放弃 I 帧之前的,要么只能有损压制,另一种方法就是有损+无损的拼接,据说某个截取软件就是这么做的,但前提是获取准确的压制参数!

删去视频指定区间内容(去广告)

1
ffmpeg -i "D:\Download\****.mp4" -vf "select='not(between(t,17*60+41,18*60+59))',setpts=N/(FRAME_RATE*TB)" -af "aselect='not(between(t,17*60+41,18*60+59))',asetpts=N/(SR*TB)" -c:v libx264 -c:a aac -strict -2 "D:\Download\****_edited.mp4"

解析:
这段命令行使用了 FFmpeg 工具,用于视频编辑和处理。下面对各个选项进行解释:

1
2
3
4
5
6
7
# -i "D:\Download\****.mp4":输入文件路径,其中 **** 是被脱敏的部分,表示输入的视频文件名。
# -vf "select='not(between(t,17*60+41,18*60+59))',setpts=N/(FRAME_RATE*TB)":视频过滤器选项,其中 select 表示选择满足条件的帧,not(between(t,17*60+41,18*60+59)) 表示不选取时间在 17 分 41 秒至 18 分 59 秒之间的帧,setpts 表示修改视频帧的时间戳,N/(FRAME_RATE*TB) 表示将每个帧的时间戳除以帧率乘以时间基准得到新的时间戳。
# -af "aselect='not(between(t,17*60+41,18*60+59))',asetpts=N/(SR*TB)":音频过滤器选项,其中 aselect 表示选择满足条件的音频样本,not(between(t,17*60+41,18*60+59)) 表示不选取时间在 17 分 41 秒至 18 分 59 秒之间的音频样本,asetpts 表示修改音频样本的时间戳,N/(SR*TB) 表示将每个样本的时间戳除以采样率乘以时间基准得到新的时间戳。
# -c:v libx264:视频编码器选项,使用 libx264 编码器将视频编码为 H.264 格式。
# -c:a aac:音频编码器选项,使用 aac 编码器将音频编码为 AAC 格式。
# -strict -2:音频编码器选项,表示使用宽松的 AAC 编码器设置。
# "D:\Download\****_edited.mp4":输出文件路径,其中 **** 是被脱敏的部分,表示输出的视频文件名。

作者:有几米爱音乐
链接:https://www.jianshu.com/p/b7806b237c98
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

分割媒体文件

如何分割媒体文件呢?只需要为每个输出文件分别指定开始时间、结束或者持续时间就可以了。
ffmpeg -i video.mp4 -t 00:00:30 video_1.mp4 -ss 00:00:30 video_2.mp4
语法很简单,为第一个文件指定了-t 00:00:30作为持续时间(第一个部分是原始文件的前 30 秒内容),然后指定接下来的所有内容作为第二个文件(从第一部分的结束时间开始,也就是 00:00:30)。
你可以任意指定多少个部分,尝试一下吧,这个功能真的很厉害,同时它也适用用音频文件。

拼接媒体文件

ffmpeg 也可以进行相反的动作:把多个文件合在一起。

为了实现这一点,你得用自己顺手的编辑器来创建一个文本文件videos_to_join.txt
在文件内容中,输入您想拼接的文件的完整路径(文件会按照顺序拼合在一起),一行一个文件。确保他们拥有相同的后缀名。下面是我的例子:

1
2
3
file /home/ubuntu/Desktop/video_1.mp4
file /home/ubuntu/Desktop/video_2.mp4
file /home/ubuntu/Desktop/video_3.mp4

注意:前面要加file ,文件名不能有空格、中文。
保存这个文件,同样这个方法适用与任何音频或者视频文件。
然后使用下面的命令:
ffmpeg -f concat -i join.txt output.mp4
Note:使用的输出文件的名称是 output.mp4,因为我的输入文件都是 mp4 的。
这样,你videos_to_join.txt里的所有文件都会被拼接成一个独立的文件了。

m4a->mp3

之前用的:
ffmpeg -i "录音.m4a" -b:a 64k -acodec mp3 -ar 44100 -ac 1 "111.mp3"

视频和音频合并

1
ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a aac -strict experimental output.mp4

从视频中抽取音频

为了从视频文件中抽取音频,直接加一个-vn参数就可以了:
ffmpeg -i video.mp4 -vn audio.mp3
这会让命令复用原有文件的比特率,一般来说,使用-ab(音频比特率)来指定编码比特率是比较好的:
ffmpeg -i video.mp4 -vn -ab 128k audio.mp3

一些常见的比特率有 96k, 128k, 192k, 256k, 320k (mp3 也可以使用最高的比特率)。

其他的一些常用的参数比如-ar(采样率: 22050, 441000, 48000),-ac(声道数),-f(音频格式, 通常会自动识别的), -ab 也可以使用-b:a来替代. 比如:
ffmpeg -i video.mov -vn -ar 44100 -ac 2 -b:a 128k -f mp3 audio.mp3

之前尝试使用成功:
ffmpeg -i "录音.m4a" -b:a 64k -acodec mp3 -ar 44100 -ac 1 "111.mp3"

让视频静音

和之前的-vn抽音频类似,我们可以使用-an来获得纯视频。
ffmpeg -i video_input.mp4 -an -video_output.mp4
Note: 这个 -an 标记会让所有的音频参数无效,因为最后没有音频会产生。

从视频中提取图片

这个功能可能对很多人都挺有用,比如你可能有一些幻灯片,你想从里面提取所有的图片,那么下面这个命令就能帮你:
ffmpeg -i video.mp4 -r 1 -f image2 image-%3d.png

我们来解释一下这个命令:

-r代表了帧率(一秒内导出多少张图像,默认25),-f代表了输出格式(image2 实际上是 image2 序列的意思)。

最后一个参数(输出文件)有一个有趣的命名:它使用%3d来指示输出的图片有三位数字(000,001,等等.)。你也可以用%2d(两位数字)或者%4d(4 位数字),只要你愿意,你可以随便实验一下可以怎么写!

Note:同样也有将图片转变为视频/幻灯片的方式,下面的高级应用中会讲到。

更改视频分辨率或长宽比

对 ffmpeg 来说又是个简单的任务,你只需要使用-s参数来缩放视频就行了:
ffmpeg -i video_input.mov -s 1024x576 video_output.mp4

同时,你可能需要使用-c:a来保证音频编码是正确的:
ffmpeg -i video_input.h264 -s 640x480 -c:a video_output.mov

你也可是使用-aspect来更改长宽比:
ffmpeg -i video_input.mp4 -aspect 4:3 video_output.mp4

Note:在高级应用中还会提到更强大的方法

为视频增加字幕

另一个常见又很容易实现的要求是给视频增加字幕,比如一部外文电源,使用下面的命令:
ffmpeg -i video.mp4 -i subtitles.srt -c:v copy -c:a copy -preset veryfast -c:s mov_text -map 0 -map 1 output.mp4
当然,你可以指定自己的编码器和任何其他的音频视频参数。

20240104_我使用的双语字幕文件格式,以及如何用ffmpeg将字幕嵌入视频 _ 宝玉的分享.html中,宝玉分享的如何将字幕嵌入视频,直接用的 ffmpeg 的命令行:

1
ffmpeg -i "Steve Jobs Content vs Process.mp4" -vf ass="Steve Jobs Content vs Process.ass" "Steve Jobs Content vs Process output.mp4"

webp 转 jpg

1
2
# 命令行中输入:
for %i in (*.webp) do ffmpeg -i "%i" "%~ni.jpg"

电子书教程

电子书 FFmpeg 教程

地址:wklchris.github.io/blog/FFmpeg/
本文介绍命令行音视频处理工具 FFmpeg ,以例为主。主要内容如目录

不常用

为音频增加封面图片

有个很棒的方法把音频变成视频,全程使用一张图片(比如专辑封面)。当你想往某个网站上传音频,但那个网站又仅接受视频(比如 YouTube, Facebook 等)的情况下会非常有用。

下面是例子:
ffmpeg -loop 1 -i image.jpg -i audio.wav -c:v libx264 -c:a aac -strict experimental -b:a 192k -shortest output.mp4

只要改一下编码设置 (-c:v是视频编码,-c:a是音频编码) 和文件的名称就能用了。

Note: 如果你使用一个较新的 ffmpeg 版本(4.x),你就可以不指定 -strict experimental

将图片转变为视频

这会告诉你如何将图片变成幻灯片秀,同时也会告诉你如何加上音频。
首先我建议您将所有的图片放到一个文件夹下面,我把它们放到了my_photos里,同时图片的后缀名最好是.png或者.jpg,不管选那个,他们应该是同一个后缀名,否则 ffmpeg 可能会工作的不正常,您可以很方便的把.png转变为.jpg(或者倒过来也行)。
我们这次转换的格式-f应该被设置为image2pipe,你必须使用使用连词符–来指明输入。image2pipe 允许你使用管道(在命令间使用|)的结果而不是文件作为 ffmpeg 的输入。命令结果便是将所有图片的内容逐个输出,还要注意指明视频编码器是 copy (-c:v copy)以正确使用图片输入:
cat my_photos/* | ffmpeg -f image2pipe -i - -c:v copy video.mkv
如果你播放这个文件,你可能会觉得只有一部分图片被加入了,事实上所有的图片都在,但是 ffmpeg 播放它们的时候太快了,默认是 23fps,一秒播放了 23 张图片。
你应该指定帧率(-framerate):
cat my_photos/* | ffmpeg -framerate 1 -f image2pipe -i - -c:v copy video.mkv
在这个例子里,把帧率设置为 1,也就是每帧(每张图)会显示 1 秒。
为了加一些声音,可以使用音频文件作为输入-i audo_file并且设定 copy 音频编码-c:a copy。你可以同时为音频和视频设定编码器,在输出文件前设置就可以了。你要计算一下音频文件的长度和图片张数,已确定合适的帧率。比如我的音频文件是 22 秒,图片有 9 张,那么帧率应该是9/22大约0.4,所以我这么输入命令:
cat my_photos/* | ffmpeg -framerate 0.40 -f image2pipe -i - -i audio.wav -c copy video.mkv

录制屏幕

通过 ffmpeg 录制屏幕同样没有困难的,将格式-f设定为x11grab,他就会抓取你的XSERVER,输入的话可以这是屏幕编号(一般都是0:0). 抓取是从左上角开始计算的,可以指定屏幕分辨率-s,我的屏幕是1920×1080,注意屏幕分辨率应在输入之前指定:
ffmpeg -f x11grab -s 1920x1080 -i :0.0 output.mp4
按q或者CTRL+C以结束录制屏幕。
小技巧:你可以通过命令获得真实的分辨率而不是写死一个固定的大小:-s $(xdpyinfo | grep dimensions | awk '{print $2;}')
完整的命令这么写:
ffmpeg -f x11grab -s $(xdpyinfo | grep dimensions | awk '{print $2;}') -i :0.0 output.mp4

录制摄像头

从摄像头录制就更简单了,linux 上设备都是在/dev中的,比如 /dev/video0, /dev/video1, etc.:
ffmpeg -i /dev/video0 output.mkv
同样,q或者CTRL+C来结束录制。

录制声音

Linux 上同时是使用ALSA和pulseaudio来处理声音的。 ffmpeg 可以录制两者,不过我要特别说明 pulseaudio, 因为 Debian 系列的发行版默认用了它。命令如下:
在 pulseaudio, 你必须强制指定-f alsa然后指定 default 作为输入-i default:
ffmpeg -f alsa -i default output.mp3
Note: 在你系统音频设置里,应该能看到默认的录音设备。
我经常玩吉他,我平时使用一个专业音频设备才能录制声音,当我发现 ffmpeg 也可以很轻松的录制的时候颇为惊讶。

录制小贴士

对于录制任务来说,通常都需要指定编码器以及帧率,之前讲过的参数当然也可以用到这里来!
ffmpeg -i /dev/video0 -f alsa -i default -c:v libx264 -c:a flac -r 30 output.mkv
有时候不直接录音,而是在录屏/录像的时候给一个音频文件,那么可以这么做:
ffmpeg -f x11grab -s $(xdpyinfo | grep dimensions | awk '{print $2;}') -i :0.0 -i audio.wav -c:a copy output.mp4
Note: ffmpeg 使用片段录取,所有有时候非常短的录制可能不会保存文件。我建议录地可以稍微长一些(然后后期裁剪),以保证录制的文件成功写到磁盘上。

各种编码

HEVC(H.265)与 AVC(H.264)的区别与联系

https://www.jianshu.com/p/0845334b16dc

一、什么是 H.265?
   H.265 是相对于 H.264 的一个升级版,是在原有 H.264 标准上的一个拓展和优化。H.265 旨在在有限带宽下传输更高质量的网络视频,仅需原先的一半带宽即可播放相同质量的视频。这也意味着,我们的智能手机、平板机等移动设备将能够直接在线播放 1080P 的全高清视频。H.265 标准也同时支持 4K(4096×2160)和 8K(8192×4320)超高清视频。

为什么说 H.265 比 H.264 更高效?H.265/HEVC 视频编码与 H.264/AVC 使用相同的方法,包括画面帧预测、变换编码、量化等。但 H.265/HEVC 包括编码单元(CUS)、预测单元(PU)和变换单元(TUS)。

如果峰值信噪比和视频质量作为衡量一个视频编码机制效率的主观评价标准,那么在这种主观评价中,H.265 可提供更好的编码效率,比 H.264 比特流减少 51%~ 74%。

二、H.265 与 H.264 的关联
   H.265 与 H.264 同属于 ITU-T VCEG(国际视频解码专家组)所制定的视频编码标准,都属于目前世界上最重要的视频解码标准,广泛应用于视频储存、广播电视、网络等各类视频传输流中(在 H.265 出现之前,H.264 几乎是最著名的编解码标准 —— 所有蓝光播放器都必须能解码 H.264)。

H.265 是基于 H.264 技术加以优化后的视频编码标准,在保留 H.264 技术特性的同时,进一步改善了码流、编码质量、延时和数据算法之间的关系,性能相对更强。

在 1080P 为极致观影追求的时代,H.264 是最理想的解码方式,而随着 4K 成为行业大趋势,H.265 才是其最理想的搭档。

三、H.265 和 H.264 的区别
   1.H.265 是新的编码协议,也即是 H.264 的升级版。H.265 标准保留 H.264 原来的某些技术,同时对一些相关的技术加以改进。新技术使用先进的技术用以改善码流、编码质量、延时和算法复杂度之间的关系,达到最优化设置。

2.H.265 相比 H.264 最主要的改变是采用了块的四叉树划分结构,采用了从 64×64 ~ 8×8 像素的自适应块划分,并基于这种块划分结构采用一系列自适应的预测和变换等编码技术。

3.H.264 由于算法优化,可以低于 1Mbps 的速度实现标清数字图像传送;H.265 则可以实现利用 1~2Mbps 的传输速度传送 720P(分辨率 1280×720)普通高清音视频传送。

4.同样的画质和同样的码率,H.265 比 H2.64 占用的存储空间要少理论 50%。

5.比起 H.264/AVC,H.265/HEVC 提供了更多不同的工具来降低码率,以编码单位来说,H.264 中每个宏块(macroblock/MB)大小都是固定的 16×16 像素,而 H.265 的编码单位可以选择从最小的 8×8 到最大的 64×64。

6.在相同的图象质量下,相比于 H.264,通过 H.265 编码的视频大小将减少大约 39 ~ 44%。

四、H.265 的优势
   1.H.265/HEVC 的编码架构大致上和 H.264/AVC 的架构相似,主要也包含,帧内预测(intra prediction)、帧间预测(inter prediction)、转换(transform)、量化(quantization)、去区块滤波器(deblocking filter)、熵编码(entropy coding)等模块。

但在 HEVC 编码架构中,整体被分为了三个基本单位,分别是编码单位(coding unit, CU)、预测单位(predict unit, PU)和转换单位(transform unit, TU)。

2.比起 H.264/AVC,H.265/HEVC 提供了更多不同的工具来降低码率,以编码单位来说,H.264 中每个宏块(macroblock/MB)大小都是固定的 16x16 像素,而 H.265 的编码单位可以选择从最小的 8×8 到最大的 64×64。

3.H.265 的帧内预测模式支持 33 种方向(H.264 只支持 8 种),并且提供了更好的运动补偿处理和矢量预测方法。

4.反复的质量比较测试已经表明,在相同的图象质量下,相比于 H.264,通过 H.265 编码的视频大小将减少大约 39 ~ 44%。由于质量控制的测定方法不同,这个数据也会有相应的变化。

5.通过主观视觉测试得出的数据显示,在码率减少 51 ~ 74%的情况下,H.265 编码视频的质量还能与 H.264 编码视频近似甚至更好,其本质上说是比预期的信噪比(PSNR)要好。

linux 软链接:

1
2
3
4
5
6
7
8
9
10
ln -s 源文件的绝对路径 软连接的路径
# 删除
rm -rf ln_dir # 不能加最后的/,不然会删除源
# 或
rm ln_dir
# 错误的删除方式
rm -rf ./test_chk_ln/ #这样就会把原来test_chk下的内容删除

#修改
ln -snf 【新目标目录】 【软链接地址】

windows 上面使用:

1
2
3
4
5
6
mklink /d E:\vue D:\code\webui

命令格式:mklink /d(定义参数) \MyDocs(链接文件) \Users\User1\Documents(原文件)
/d:建立目录的符号链接(symbolic link)(可以用rmdir删除,如果用del删除,就会连原目录一起删除)
/j:建立目录的软链接(联接)(junction)
/h:建立文件的硬链接(hard link)

带前导零的循环:

1
2
3
4
for i in {01..60}
do
grep " 04:${i}" request.log | wc -l # 统计4点每分钟有多少个请求
done

同样的脚本用 nodejs 来写:

1
2
3
4
5
6
7
8
let shell = require("shelljs");
shell.cd("/db/logs/");
for (let i = 0; i < 60; i++) {
let ii = i < 10 ? `0${i}` : String(i);
let time = `04:${ii}`;
let out = shell.exec(`grep " ${time}" ALL.log | wc -l`, { silent: true });
shell.echo("-n", time.concat(": "), out.stdout);
}

docker 的常用命令

镜像相关

拉取一个镜像

docker pull image_name

发布一个镜像(注意别发布到 docker push 上去了)

docker push

查看已有镜像

docker images
等价于:docker image ls

搜索镜像列表

docker search nginx
可以在dockerHub 官网进行搜索,细化到各个镜像的版本号。

导出、导入镜像为文件(镜像打包到文件、文件恢复为镜像)

docker save -o image_name.tar
docker save -o /home/skj.tar skj:latest

导入方法一:
docker load –input /home/skj.tar

导入方法二
docker load -i /home/skj.tar

导入方法三
docker load < /home/skj.tar

删除镜像(有容器使用是删不掉的)

1
docker rmi image_name

注意:如果删除比较大的镜像,docker rmi后,镜像所占用的磁盘空间会立极恢复,不用担心占用磁盘。

从容器导出为镜像

docker commit -m “con_name” con_id image_name
或者导出容器为镜像:
docker commit ef5db5c6693b skj:latest

容器相关

查看正在运行的容器

docker ps (-a) # -a 所有

创建 docker 容器

docker create -it –name nginx_docker nginx # 使用 image 名创建
docker create -it –name nginx_docker 27a188018e18 bash # 使用 image 的 id 创建

启动一个 docker 容器

docker start 启动一个已停止的容器
docker start -i nginx_docker # name 启动
docker start -i 27a188018e18 # id 启动
docker run hello-world(image-name)

docker run 命令是 create 和 start 的结合

docker run –name=con_name images

让容器使用系统时区:-v /etc/timezone:/etc/timezone:ro -v /etc/localtime:/etc/localtime:ro

让容器跟随宿主机系统的重启而重启:在 docker run 的时候加上这个参数:--restart=always

如果容器启动时没有设置–restart 参数,则通过下面命令进行更新:

1
docker update --restart=always [容器名]

停止、重启容器

docker stop
停止的容易可以通过 docker restart 重启:
docker restart

删除容器

docker rm con_name
docker rm -f con_name (强制删除容器,若不加-f,则无法删除正在运行的容器)

拷贝文件

docker cp one.file ng:/
docker cp ng:/one.file .

物理机端口映射到虚拟机 81 上

docker run -d -p 80:81 image_name # -d 表示守护进程

查看 docker 的端口映射

docker port con_id

进入容器,相当于使用 chroot

docker attach con_name (退出 exit)
docker attach 进入容器正在执行的终端,不会启动新的进程。如果使用 exit 退出,容器会停止运行!如果想退出容器但不想容器停止,则按住 Ctrl+P+Q 退出

进入容器

docker exec nginx_docker
docker exec -it nginx_docker bash
docker exec 相当于进入容器并开启一个新的终端,可以在里面操作。如果使用 exit 退出,容器也不会停止。

动态查看容器日志

docker logs -f con_name
docker logs nginx -ft –since 1m # -t 表示显示时间戳,since 表示多久之前开始显示

查看容器 PID

docker top con_name

查看 docker 网络情况

docker network ls

还可以用 docker 创建网段路由等,详情 google

docker -it # 实现交互式容器
docker -d # debug 模式

查看 docker 容器信息

docker inspect nginx_docker

查看 docker 容器分配到的 ip

docker inspect nginx_docker | grep IPAddress
默认是 172.17 的网段 ip

如何修改容器的端口映射?

  1. 一定要 service docker stop(cerntos 用systemctl stop docker),不然会被覆盖
  2. 改文件
    每个对应容器都有 config,改了就可以了
    端口对应的 config 的两个文件是:
    /var/lib/docker/containers/con_id/hostconfig.json
    /var/lib/docker/containers/con_id/config.v2.json
    测试中只需要改第一个就好了,可能跟版本有关系

修改(注:ExposedPorts 是暴露的接口)(需要在防火墙中放开相应端口的权限):
“PortBindings”:{“8080/tcp”:[{“HostIp”:””,”HostPort”:”60000”}]}
“Ports”:{“8080/tcp”:{“HostIp”:””,”HostPort”:”60000”}} (config.v2.json 文件,这里如果 stop 了之后是空的{},也需要填上{"HostIp":"","HostPort":"60000"})

  1. 启动容器
    systemctl start docker
    docker ps -a
    docker start postgres

如何把宿主的目录挂载到 docker 容器中

使用 docker 中的
docker run -v /path2src:/path2docker …
对应的在 config 中应该也找得到配置项

正则元素

常用元字符

\w:匹配字母、数字、下划线。等价于 [A-Za-z0-9_]
\W:匹配非字母、数字、下划线。等价于 [^A-Za-z0-9_]。

\b:匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b’ 可以匹配”never” 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
\B:匹配非单词边界。’er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。

\d:匹配任意一个阿拉伯数字(0 到 9)。等价于 [0-9]
\D:匹配一个非数字字符。等价于[^0-9]。

\s:匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S:匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。

^ :匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 \n 或 \r 之后的位置。
$ :匹配输入字符串的结束位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 \n 或 \r 之后的位置。

\num:匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,’(.)\1’ 匹配两个连续的相同字符。

[\u4e00-\u9fff]:匹配中文

字符簇

[[:alpha:]] 任何字母
[[:digit:]] 任何数字
[[:alnum:]] 任何字母和数字
[[:space:]] 任何空白字符
[[:upper:]] 任何大写字母
[[:lower:]] 任何小写字母
[[:punct:]] 任何标点符号
[[:xdigit:]] 任何 16 进制的数字,相当于[0-9a-fA-F]

例如:
^[[:alpha:]]{3}$:匹配所有的 3 个字母的单词。

修饰符

修饰符 含义 描述
i ignore - 不区分大小写 将匹配设置为不区分大小写,搜索时不区分大小写: A 和 a 没有区别。
g global - 全局匹配 查找所有的匹配项。
m multi line - 多行匹配 使边界字符 ^ 和 $ 匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾。
s 特殊字符圆点.中包含换行符\n 默认情况下的圆点.是匹配除换行符\n之外的任何字符,加上s修饰符之后,.中包含换行符\n。

正则环视

正则环视
(?<=Expression)
逆序肯定环视,表示所在位置左侧能够匹配 Expression
(?<!Expression)
逆序否定环视,表示所在位置左侧不能匹配 Expression
(?=Expression)
顺序肯定环视,表示所在位置右侧能够匹配 Expression
(?!Expression)
顺序否定环视,表示所在位置右侧不能匹配 Expression

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment