Qt的宏定义区分不同操作系统

程序中遇到需要区分操作系统时,可使用qt的宏定义:

中,定义了各个系统的宏定义

Q_OS_AIX
Defined on AIX.
Q_OS_ANDROID
Defined on Android.
Q_OS_BSD4
Defined on Any BSD 4.4 system.
Q_OS_BSDI
Defined on BSD/OS.
Q_OS_CYGWIN
Defined on Cygwin.
Q_OS_DARWIN
Defined on Darwin-based operating systems such as macOS, iOS, watchOS, and tvOS.
Q_OS_DGUX
Defined on DG/UX.
Q_OS_DYNIX
Defined on DYNIX/ptx.
Q_OS_FREEBSD
Defined on FreeBSD.
Q_OS_HPUX
Defined on HP-UX.
Q_OS_HURD
Defined on GNU Hurd.
Q_OS_IOS
Defined on iOS.
Q_OS_IRIX
Defined on SGI Irix.
Q_OS_LINUX
Defined on Linux.
Q_OS_LYNX
Defined on LynxOS.
Q_OS_MAC
Deprecated synonym for Q_OS_DARWIN. Do not use.
Q_OS_MACOS
Defined on macOS.
Q_OS_NETBSD
Defined on NetBSD.
Q_OS_OPENBSD
Defined on OpenBSD.
Q_OS_OSF
Defined on HP Tru64 UNIX.
Q_OS_OSX
Deprecated synonym for Q_OS_MACOS. Do not use.
Q_OS_QNX
Defined on QNX Neutrino.
Q_OS_RELIANT
Defined on Reliant UNIX.
Q_OS_SCO
Defined on SCO OpenServer 5.
Q_OS_SOLARIS
Defined on Sun Solaris.
Q_OS_TVOS
Defined on tvOS.
Q_OS_ULTRIX
Defined on DEC Ultrix.
Q_OS_UNIX
Defined on Any UNIX BSD/SYSV system.
Q_OS_UNIXWARE
Defined on UnixWare 7, Open UNIX 8.
Q_OS_WATCHOS
Defined on watchOS.
Q_OS_WIN32
Defined on 32-bit and 64-bit versions of Windows.
Q_OS_WIN64
Defined on 64-bit versions of Windows.
Q_OS_WIN
Defined on all supported versions of Windows. That is, if Q_OS_WIN32, Q_OS_WIN64, or Q_OS_WINRT is defined.
Q_OS_WINPHONE
Defined on Windows Phone 8.
Q_OS_WINRT
Defined for Windows Runtime (Windows Store apps) on Windows 8, Windows RT, and Windows Phone 8.

举例1:
记得需要有QObject的头文件,才可以

1
2
3
4
5
6
7
#include<QObject>

#ifdef Q_OS_WIN
#include <winsock2.h>
#endif

#include <mysql.h>

举例2:
对于标记了Q_OBJECT这个宏的类,其成员函数可以直接上面的区分操作系统的这些宏定义。

***.h文件:

1
2
3
4
5
6
7
8
9
10
11
class DetailStepInfo : public QObject
{
Q_OBJECT

public:

....................

...................

}

***.cpp文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool DetailStepInfo::**************()
{

#ifdef Q_OS_WIN

#endif

#ifdef Q_OS_LINUX
QString command = QString("chmod +rw /****************************");
QProcess proc;
proc.execute(command);
#endif

...........................

}

ACE Editor修改自动换号缩进

https://stackoverflow.com/questions/38323427/remove-word-wrap-offset-in-ace-editor

This is controlled by indentedSoftWrap setting in ace, you can turn it off by running

1
editor.setOption("indentedSoftWrap", false);

behaviours setting is completely unrelated and controls automatic insertion of closing brackets and tags.

So your code from the above would become

1
2
3
4
5
6
7
8
9
var editor = ace.edit("edittext");
editor.setOptions({
maxLines: Infinity, // this is going to be very slow on large documents
useWrapMode: true, // wrap text to view
indentedSoftWrap: false,
behavioursEnabled: false, // disable autopairing of brackets and tags
showLineNumbers: false, // hide the gutter
theme: "ace/theme/xcode"
});

Vmware ESXi 6.7常用设置备忘录

1. ESXi关闭超线程以提高安全性

在主机-配置-系统-高级系统设置-编辑;搜索参数:VMkernel.Boot.hyperthreadingMitigation,有两项配置,参数配置为true ,即为关闭超线程。

2. 虚拟机使用主机物理硬盘

如果是nvme固态硬盘可以在硬件列表中开启直通,然后在虚拟机设置中添加对应的pci设备。

如果是sata硬盘,则需要ssh登录,使用vmkfstools命令创建物理硬盘的映像:

1
vmkfstools -z /vmfs/devices/disks/<硬盘标识符> /vmfs/volumes/datastore1/<目标RDM磁盘名>.vmdk

硬盘标识符为存储、设备选项卡里面磁盘列表,点击对应磁盘,查看到的硬盘路径,类似:/vmfs/devices/disks/t10.ATA_____WDC__WUH721414ALE6L4____________________QBHB0G1T____________

3. 序列号

企业版参考序列号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HV4WC-01087-1ZJ48-031XP-9A843 

NF0F3-402E3-MZR80-083QP-3CKM2

4F6FX-2W197-8ZKZ9-Y31ZM-1C3LZ

JZ2E9-6D2DK-XZQD0-632E4-33E7Z

MZ48M-DNK56-ZZJD0-RTCE2-9321X

0Y0AJ-4P29H-LZV81-59AQ2-C291V

0A4GL-D7JD7-LZR10-M30G0-A36JF

4C02A-DP2E2-AZ041-FH9X6-922J6

4. 查看硬盘健康状况

使用系统自带命令esxcli

列出硬盘

1
esxcli storage core device list

查看硬盘smart信息

1
esxcli storage core device smart get -d <disk> 

安装Jellyfin多媒体服务器

由于 Jellyfin 的 GPL 协议和 Intel 的 media-driver (iHD) Linux 驱动(部分开源)在协议上不兼容的缘故,Jellyfin 官方的 Docker 镜像:jellyfin/jellyfin 并不包含 Intel Linux 核显驱动。但是 Intel 的 QuickSync QSV 硬件加速依赖于该驱动,并且 Intel 10 代酷睿(Comet Lake)以及更新的处理器需要该驱动才能正常使用硬件加速。另外 VPP/OpenCL 色调映射也需要该驱动才能正常运作。

1 安装

开发者提供的中国特供版镜像
Docker 镜像: docker pull nyanmisaka/jellyfin:latest

Jellyfin中国特供版+Docker镜像,含驱动,免折腾开箱即用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo docker run -d --name=Jellyfin -p 8096:8096 \  # --name=Jellyfin 将容器名定义为 Jellyfin 
-p 8920:8920 -p 7359:7359/udp -p 1900:1900/udp #这三个端口为可选项 \
-v /var/docker/jellyfin/library:/config -v /var/docker/jellyfin/cache:/cache -v /data/media:/media \
-e TZ=Asia/Shanghai -e PUID=0 -e PGID=0 \ #将容器的时区设为上海,使用窗口在运行时使用root权限
--device=/dev/dri:/dev/dri \ #直通显卡给 Docker 容器,用于硬解
--add-host=api.themoviedb.org:13.224.161.90 \ #为容器增加 host 指向,加速海报与影视元数据的搜刮
--add-host=api.themoviedb.org:13.35.8.65 \
--add-host=api.themoviedb.org:13.35.8.93 \
--add-host=api.themoviedb.org:13.35.8.6 \
--add-host=api.themoviedb.org:13.35.8.54 \
--add-host=image.tmdb.org:138.199.37.230 \
--add-host=image.tmdb.org:108.138.246.49 \
--add-host=api.thetvdb.org:13.225.89.239 \
--add-host=api.thetvdb.org:192.241.234.54 \
--restart unless-stopped \
jellyfin/jellyfin:latest

1.如果使用 linuxserver/jellyfin 镜像,就把最后一行替换为下行

1
lscr.io/linuxserver/jellyfin:latest

2.如果使用 nyanmisaka/jellyfin 镜像,最把最后一行替换为下行

1
nyanmisaka/jellyfin:latest

–add-host是指定容器中的域名解析ip,因为每个地方、不同时间ip访问稳定性不同,所以最好不在这里指定,而是用bind解析,详见 安装Bind9用于本地域名解析。已经添加了--add-host参数想删掉的话,可以进入容器配置目录,编辑hostconfig.json文件,把ExtraHosts值清空:

1
"ExtraHosts":[],

修改容器配置需要先停掉容器,容器配置目录默认位于/var/lib/docker/containers/,里面目录是容器的全id,查询容器的全ID使用命令docker inspect 容器ID |grep Id

端口说明:

端口号 用途 可选项
8096 默认http端口号 必须
8920 默认https端口号 可选
7359 让同一局域网中的客户端设备自动发现 可选
1900 DLNA的端口 可选

2 升级

拉取最新版镜像:

1
docker pull nyanmisaka/jellyfin:latest

重命名原容器名

1
docker rename Jellyfin Jellyfin-10.8.13

用最新镜像重新启动一个容器

1
docker run -d --name=Jellyfin -p 8096:8096 -p 8920:8920 -p 7359:7359/udp -p 1900:1900/udp -v /var/docker/jellyfin/library:/config -v /var/docker/jellyfin/cache:/cache -v /data/media:/media -e TZ=Asia/Shanghai -e PUID=0 -e PGID=0 --device=/dev/dri:/dev/dri --restart unless-stopped nyanmisaka/jellyfin:latest

删除原来的容器:

1
docker rm Jellyfin-10.8.13

清理冗余镜像:

1
docker image prune

ffmpeg的常用选项

map选项

默认情况下只在输入文件中的每种流里选择第一个流。

需要指定放入输出文件的流就需要使用-map选项。

用法举例:

-map 0
From input index #0 (the 1st input) select all streams.

-map 1:a
From input index #1 (the 2nd input) select all audio streams.

-map 3:s:4
From input index #3 (the 4th input) select subtitle stream index #4 (the fifth subtitle stream)。

-map 0 -map -0:s
Will select all streams from input index #0 (the 1st input) except subtitles.

改变视频帧率

有两种方法可以改变输出文件的视频流帧率:

  1. 使用 -r 选项
  2. 使用 fps滤镜。
1
2
ffmpeg -i [inputfile] -r 30 [output]
ffmpeg -i [inputfiel] -filter:v fps=30 [output]

有两种方法可以改变输出文件的视频流帧率:

改变默认音轨

使用ffmpeg修改默认的音频轨道,先取消第二音轨的默认值,在设置为第一音轨。

1
ffmpeg -i input.mkv -map 0:0 -map 0:1 -map 0:2  -c copy -disposition:a:1 0 -disposition:a:0 default -y output.mp4

改变音频采样率

-ar 48k 44.1k 96k

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k output.flac

改变音频通道数量

-ac

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -ac:0 2 -filter:0 aformat=channel_layouts=stereo output.flac
1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -ac:0 6 -filter:0 aformat=channel_layouts=5.1 output.flac

改变音频位深 bit depth

-sample_fmt

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -sample_fmt s24 -ac:0 6 -filter:0 aformat=channel_layouts=5.1 output.flac

生成空白音频

可以使用anullsrc来生成静音音频:

1
ffmpeg -f lavfi -i anullsrc=r=48000:cl=stereo -t 0.875 /Users/redtux/Movies/converted/silent-audio.aac
  • sample_rate, r
    指定采样率,默认44100。

  • channel_layout, cl
    指定通道布局,详见 libavutil/channel_layout.cchannel_layout_map 定义,常见mono stereo 5.1

  • -t
    文件时长,单位事秒,不指定就一直生成。

截取视频片段

1
ffmpeg  -i 源文件名 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 目标文件名 -y

裁剪视频文件的多个部分,并将其合并成一个新的视频

调整播放速度

调整视频文件中视频速度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//2倍速播放
ffmpeg -i test.mp4 -an -filter:v "setpts=0.5*PTS" out_test.mp4

-i test.mp4是输入文件名

-an 将音频禁掉 (可以不加)

-filter:v 对视频进行处理

"setpts=0.5PTS" 设置时间戳参数PTS为原先的一半,可接受调整范围为[0.25,4]

out_test.mp4 输出视频文件

还可以在命令中加上指定fps(-r 60),使得不会丢帧

调整视频文件中音频速度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ffmpeg -i test.mp4 -filter:a "atempo=2.0" -vn out_test.mp4
-i 后满test.mp4是输入文件名

-filter:a 对音频进行处理

"atempo=2.0" 设置播放速度是原来的2倍 , 倍率调整范围[0.5, 2.0]

-vn 将视频禁掉 (可以不加)

out_test.mp4 输出视频文件

需要调整到4倍可以采取以下方法:

ffmpeg -i test.mp4 -filter:a "atempo=2.0,atempo=2.0" -vn out_test.mp4

同时调整视频文件的视频、音频:

1
ffmpeg -i test.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]"  out_test.mp4

如果不想丢帧就同时设置 -r ,把帧率设置为原帧率的2倍。

metadata的使用

1
ffmpeg -i /Users/redtux/Movies/Becoming.Jane.2007.1080p.BluRay.x265.2Audio.mp4  -metadata title="Becoming.Jane.2007.1080p.BluRay.x265.2Audio-RARBG" -map 0:0 -c:0 copy -metadata:s:0 title='Becoming.Jane.2007.1080p.BluRay.x265-RARBG' -metadata:s:0 handler='Becoming.Jane.2007.1080p.BluRay.x265-RARBG' -map 0:1 -c:1 copy -metadata:s:1 title="国语配音" -metadata:s:1 handler="国语配音" -metadata:s:1 language="chi"  -disposition:1 default -map 0:2 -c:2 copy -metadata:s:2 title="English" -metadata:s:2 handler="English" -metadata:s:2 language="eng"  -disposition:2  0 /Users/redtux/Movies/Becoming.Jane.2007.1080p.BluRay.x265.2Audio-RARBG.mp4

ffmpeg的常用选项

基础指令

一.查看FFmpeg支持的编码器

1
ffmpeg configure -encoders

二.查看FFmpeg支持的解码器

1
ffmpeg configure -decoders

三.查看FFmpeg支持的通信协议

1
ffmpeg configure -protocols

四.查看FFmpeg所支持的音视频编码格式、文件封装格式与流媒体传输协议

1
ffmpeg configure --help

map选项

默认情况下只在输入文件中的每种流里选择第一个流。

需要指定放入输出文件的流就需要使用-map选项。

用法举例:

-map 0
From input index #0 (the 1st input) select all streams.

-map 1:a
From input index #1 (the 2nd input) select all audio streams.

-map 3:s:4
From input index #3 (the 4th input) select subtitle stream index #4 (the fifth subtitle stream)。

-map 0 -map -0:s
Will select all streams from input index #0 (the 1st input) except subtitles.

改变视频帧率

有两种方法可以改变输出文件的视频流帧率:

  1. 使用 -r 选项
  2. 使用 fps滤镜。
1
2
ffmpeg -i [inputfile] -r 30 [output]
ffmpeg -i [inputfiel] -filter:v fps=30 [output]

有两种方法可以改变输出文件的视频流帧率:

改变默认音轨

使用ffmpeg修改默认的音频轨道,先取消第二音轨的默认值,在设置为第一音轨。

1
ffmpeg -i input.mkv -map 0:0 -map 0:1 -map 0:2  -c copy -disposition:a:1 0 -disposition:a:0 default -y output.mp4

改变音频采样率

-ar 48k 44.1k 96k

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k output.flac

改变音频通道数量

-ac

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -ac:0 2 -filter:0 aformat=channel_layouts=stereo output.flac
1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -ac:0 6 -filter:0 aformat=channel_layouts=5.1 output.flac

改变音频位深 bit depth

-sample_fmt

1
ffmpeg -i input.dsf -map 0:0 -c:0 flac -ar:0 96k -sample_fmt s24 -ac:0 6 -filter:0 aformat=channel_layouts=5.1 output.flac

生成空白音频

可以使用anullsrc来生成静音音频:

1
ffmpeg -f lavfi -i anullsrc=r=48000:cl=stereo -t 0.875 /Users/redtux/Movies/converted/silent-audio.aac
  • sample_rate, r
    指定采样率,默认44100。

  • channel_layout, cl
    指定通道布局,详见 libavutil/channel_layout.cchannel_layout_map 定义,常见mono stereo 5.1

  • -t
    文件时长,单位事秒,不指定就一直生成。

截取视频片段

1
ffmpeg  -i 源文件名 -vcodec copy -acodec copy -ss 00:00:10 -to 00:00:15 目标文件名 -y

视频拼接

一.将4个视频拼接成一个很长的视频(无声音)

1
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex '[0:0][1:0] [2:0][3:0] concat=n=4:v=1 [v]' -map '[v]' output.mp4

二.将4个视频拼接成一个很长的视频(有声音)

1
ffmpeg -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex '[0:0][0:1] [1:0][1:1] [2:0][2:1] concat=n=3:v=1:a=1 [v][a]' -map '[v]' -map '[a]’  output.mp4

参数解释:

1
2
3
4
5
6
7
8
[0:0][0:1] [1:0][1:1] [2:0][2:1] 
分别表示第1个输入文件的视频、音频,第2个输入文件的视频、音频,第3个输入文件的视频、音频。

concat=n=3:v=1:a=1
表示有3个输入文件,输出一条视频流和一条音频流。

[v][a]
得到的视频流和音频流的名字,注意在 bash 等 shell 中需要用引号,防止通配符扩展。

四.竖向拼接2个视频

1
ffmpeg -i 0.mp4 -i 1.mp4 -filter_complex "[0:v]pad=iw:ih*2[a];[a][1:v]overlay=0:h" out_2.mp4

五.横向拼接3个视频

1
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -filter_complex "[0:v]pad=iw*3:ih*1[a];[a][1:v]overlay=w[b];[b][2:v]overlay=2.0*w" out_v3.mp4

六.竖向拼接3个视频

1
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -filter_complex "[0:v]pad=iw:ih*3[a];[a][1:v]overlay=0:h[b];[b][2:v]overlay=0:2.0*h" out_v4.mp4

七.4个视频2x2方式排列

1
ffmpeg -i 0.mp4 -i 1.mp4 -i 2.mp4 -i 3.mp4 -filter_complex "[0:v]pad=iw*2:ih*2[a];[a][1:v]overlay=w[b];[b][2:v]overlay=0:h[c];[c][3:v]overlay=w:h" out.mp4

视频帧操作

一.查看每帧的信息

1
ffprobe -v error -show_frames gemfield.mp4 

从pict_type=I可以看出这是个关键帧,然后key_frame=1 表示这是IDR frame,如果key_frame=0表示这是Non-IDR frame。

二.截取视频中的某一帧
把gemfield.mp4视频的第1分05秒的一帧图像截取出来。

1
2
3
4
# input seeking
ffmpeg -ss 00:1:05 -i gemfield.mp4 -frames:v 1 out.jpg
# output seeking
ffmpeg -i gemfield.mp4 -ss 00:1:05 -frames:v 1 out1.jpg

参数解释:

-frame:v 1,在video stream上截取1帧。
input seeking使用的是key frames,所以速度很快;而output seeking是逐帧decode,直到1分05秒,所以速度很慢。

重要说明:

ffmpeg截取视频帧有2种 seeking 方式,对应有2种 coding 模式:transcoding 和 stream copying(ffmpeg -c copy)。

transcoding 模式:需要 decoding + encoding 的模式,即先 decoding 再encoding。

stream copying 模式:不需要decoding + encoding的模式,由命令行选项-codec加上参数copy来指定(-c:v copy )。在这种模式下,ffmpeg在video stream上就会忽略 decoding 和 encoding步骤。

三.查看视频总帧数

1
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 gemfield.mp4

四.查看 key frame 帧数

1
ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 -skip_frame nokey gemfield.mp4

五.查看 key frame 所在的时间

1
ffprobe -v error -skip_frame nokey -select_streams v:0 -show_entries frame=pkt_pts_time -of csv=print_section=0 gemfield.mp4

六.查看 key frame 分布的情况

1
ffprobe -v error -show_frames gemfield.mp4 | grep pict_type

七.查看 key frame 所在的帧数

1
ffprobe -v error -select_streams v -show_frames -show_entries frame=pict_type -of csv gemfield.mp4 | grep -n I | cut -d ':' -f 1

八.重新设置 key frame interval

1
ffmpeg -i gemfield.mp4 -vcodec libx264 -x264-params keyint=1:scenecut=0 -acodec copy out.mp4

九.查看视频波特率

1
ffprobe -v error -select_streams v:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 gemfield.mp4

调整播放速度

调整视频文件中视频速度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//2倍速播放
ffmpeg -i test.mp4 -an -filter:v "setpts=0.5*PTS" out_test.mp4

-i test.mp4是输入文件名

-an 将音频禁掉 (可以不加)

-filter:v 对视频进行处理

"setpts=0.5PTS" 设置时间戳参数PTS为原先的一半,可接受调整范围为[0.25,4]

out_test.mp4 输出视频文件

还可以在命令中加上指定fps(-r 60),使得不会丢帧

调整视频文件中音频速度:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ffmpeg -i test.mp4 -filter:a "atempo=2.0" -vn out_test.mp4
-i 后满test.mp4是输入文件名

-filter:a 对音频进行处理

"atempo=2.0" 设置播放速度是原来的2倍 , 倍率调整范围[0.5, 2.0]

-vn 将视频禁掉 (可以不加)

out_test.mp4 输出视频文件

需要调整到4倍可以采取以下方法:

ffmpeg -i test.mp4 -filter:a "atempo=2.0,atempo=2.0" -vn out_test.mp4

同时调整视频文件的视频、音频:

1
ffmpeg -i test.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]"  out_test.mp4

如果不想丢帧就同时设置 -r ,把帧率设置为原帧率的2倍。

metadata的使用

1
ffmpeg -i /Users/redtux/Movies/Becoming.Jane.2007.1080p.BluRay.x265.2Audio.mp4  -metadata title="Becoming.Jane.2007.1080p.BluRay.x265.2Audio-RARBG" -map 0:0 -c:0 copy -metadata:s:0 title='Becoming.Jane.2007.1080p.BluRay.x265-RARBG' -metadata:s:0 handler='Becoming.Jane.2007.1080p.BluRay.x265-RARBG' -map 0:1 -c:1 copy -metadata:s:1 title="国语配音" -metadata:s:1 handler="国语配音" -metadata:s:1 language="chi"  -disposition:1 default -map 0:2 -c:2 copy -metadata:s:2 title="English" -metadata:s:2 handler="English" -metadata:s:2 language="eng"  -disposition:2  0 /Users/redtux/Movies/Becoming.Jane.2007.1080p.BluRay.x265.2Audio-RARBG.mp4

提取mp4文件中的封面

1
ffmpeg -i input.mp4 -map 0:v -map -0:V -c copy ./cover.jpg

设置mp4文件的封面

1
ffmpeg -i video.mp4 -i image.png -map 1 -map 0 -c copy -disposition:0 attached_pic out.mp4

综合实例

1
2
3
4
5
6
7
8
9
10
11
12
13
ffmpeg   -y -i  input.mp4  \
-i ~/cover.jpg \
-metadata title="[繁花].Blossoms.Shanghai.2023.S01E27.1080p.WEBRip.x265-haoduo" \
-metadata comment="[繁花].Blossoms.Shanghai.2023.S01E27.1080p.WEBRip.x265-haoduo" \
-filter_complex "[0:0]select='between(t,131.32,1106.48)+between(t,1132.92,2647.88)',setpts=N/FRAME_RATE/TB,scale=1920:-8:flags=lanczos,setsar=1:1,hqdn3d=luma_spatial=2:chroma_spatial=1.5:luma_tmp=3:chroma_tmp=2.25[v]" \
-map "[v]" -metadata:s:0 title="Blossoms.Shanghai.2023.S01E27.1080p.WEBRip.x265-haoduo" -c:0 libx265 -pix_fmt yuv420p \
-x265-params "aq-mode=3:repeat-headers=0:strong-intra-smoothing=1:bframes=4:b-adapt=2:frame-threads=0:colorprim=bt709:transfer=bt709:colormatrix=bt709:chromaloc=0" \
-crf:0 30 -preset:0 slow -tag:0 hvc1 -g 250 \
-map 0:1 -metadata:s:1 title="Mandarin" -metadata:s:1 handler="Mandarin" -metadata:s:1 language=chi \
-c:1 libfdk_aac -profile:1 aac_he -b:1 64k -af:1 "aselect='between(t,131.32,1106.48)+between(t,1132.92,2647.88)',asetpts=N/SR/TB" \
-map 1 -c:2 copy -disposition:2 attached_pic \
-movflags +faststart -map_metadata -1 -map_chapters 0 \
"/Users/redtux/Movies/Blossoms.Shanghai.2023.S01E27.1080p.WEBRip.x265-haoduo.mp4"

ffprobe命令

ffprobe是ffmpeg中一个查看多媒体文件信息的模块。此模块可以用来查看多媒体文件格式以及编码。ffprobe的命令较多,这里只简单的列举了一些比较常用的命令。

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
-L 显示协议
-h/-?/-help/--help topic 帮助可以选择话题
-version 显示版本
-buildconf 展示编译配置选项
-formats 显示支持的编码
-muxers 展示支持的封装器
-demuxers 展示支持的解封装器
-devices 展示支持的设备
-codecs 展示支持的编码
-decoders 显示支持的解码器
-encoders 显示支持的编码器
-bsfs 显示支持的比特流过滤器
-protocols 展示支持的协议
-filters 展示支持的过滤器
-pix_fmts 显示支持的像素格式
-layouts 展示支持的声道格式
-sample_fmts 显示支持的采样格式
-colors 展示支持的颜色名称
-loglevel loglevel 设置日志级别
-v loglevel 设置日志级别
-report 生成报告
-max_alloc bytes 设置单个已分配块的最大大小
-cpuflags flags 指定cpu标志
-hide_banner hide_banner 不显示程序横幅
-sources device 列出源的输出设备
-sinks device 列出输出设备的接收器
-f format 指定格式
-unit 显示显示值的单位
-prefix 对显示的值使用SI前缀
-byte_binary_prefix 对字节单位使用二进制前缀
-sexagesimal 对时间单位使用六十进制格式 HOURS:MM:SS.MICROSECONDS
-pretty 美化显示输出的值,让人可读
-print_format format 设置打印格式 (available formats are: default, compact, csv, flat, ini, json, xml)
-of format -print_format的编码
-select_streams stream_specifier 选择指定的stream
-sections 打印节结构和节信息,然后退出
-show_data 显示数据包信息
-show_data_hash 显示数据包hash值
-show_error 显示探测中的错误
-show_format 显示格式/容器信息
-show_frames 显示帧信息
-show_format_entry entry 显示格式/容器信息中的特定条目
-show_entries entry_list 显示一组指定的项
-show_log 显示log
-show_packets 显示packet信息
-show_programs 显示程序信息
-show_streams 显示stream的信息
-show_chapters 显示chapters的信息
-count_frames 每个stream中的帧数
-count_packets 每个stream中的包数量
-show_program_version ffprobe的版本
-show_library_versions 库的版本
-show_versions 程序和库的版本号
-show_pixel_formats 展示像素格式描述
-show_private_data 显示私有数据
-private 和显示私有数据一样
-bitexact 强制提取bit输出
-read_intervals read_intervals 设置读取间隔
-default 默认所有选项
-i input_file 读取指定文件
-print_filename print_file 重新显示输入的文件名
-find_stream_info 读取并解码流,用启发式方法填充缺失的信息

举个例子说明一下:

1
ffprobe -show_format test.mp4 -print_format json

输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"format": {
"filename": "test.mp4",
"nb_streams": 2,
"nb_programs": 0,
"format_name": "mov,mp4,m4a,3gp,3g2,mj2",
"format_long_name": "QuickTime / MOV",
"start_time": "0.000000",
"duration": "319.204000",
"size": "20393093",
"bit_rate": "511098",
"probe_score": 100,
"tags": {
"major_brand": "isom",
"minor_version": "512",
"compatible_brands": "isomiso2avc1mp41",
"artist": "张国荣",
"comment": "163 key(Don't modify):LxuL/bhXK+eaR4o7F6vxHKbEgEKNGLg65XxJgCCH5+sQLLnuMmlonrU27WIYQt6PVE6HRptXEzkJGEUUyqRRgCQJCfXHsb5uK0bdi2lw2dOZM6en1xhkYzGV5bS0uqXI0ZMFdk2CrlfK9x7cKCXIO7AU63YasnAy7YR4dW6boVAOaUvjIWxu5CuHaCLpAF8idLjG4VlAtUpZDj2WEXQJRcZZUFLtJWNVzfbnajHn6j7qG9e0XlNSmOu6RlE/X4MR",
"title": "追 ",
"encoder": "Lavf56.4.101"
}
}
}

Select滤镜常用场景

select滤镜的使用方法见官网

1.提取视频关键帧

1
ffmpeg  -i input.mp4 -an -vf select='eq(pict_type\,I)' -vsync 2  -c:v png  image-%03d.png

2.创建缩略图

1
ffmpeg -i input.mp4 -vf select='gt(scene\,0.4)',scale=-1:200,tile=4x10 -frames:v 1 preview.png

3.裁剪视频文件的多个部分,并将其合并成一个新的视频

使用选择滤镜

1
ffmpeg -i video -vf "select='between(t,4,6.5)+between(t,17,26)+between(t,74,91)',setpts=N/FRAME_RATE/TB" -af "aselect='between(t,4,6.5)+between(t,17,26)+between(t,74,91)',asetpts=N/SR/TB" out.mp4

select及其对应的滤波器分别应用于视频和音频,选择的分段是4到6.5秒,17到26秒,最后是74到91秒;时间戳与设置点及其对应的过滤器保持连续。

Ubuntu的SSH安全配置

查看登录日志文件:

1
sudo vim /var/log/auth.log

修改SSH的默认端口

1
iptables -A INPUT -p tcp -m tcp --dport 6022 -j ACCEPT

保存并重启iptables防火墙

1
2
service iptables save
service iptables restart

修改SSH的默认端口

1
sudo vim /etc/ssh/sshd_config

把 # Port 22 修改为 Port 6022

最好使用1024到65535之间的一个别人猜不到的端口号

重启ssh服务

1
sudo service sshd restart 

1
sudo /etc/init.d/ssh restart

可以用iptables检查端口是否开启

禁止SSH的root登录

修改 /etc/ssh/sshd_config 文件

1
PermitRootLogin no

重启ssh服务

1
sudo service sshd restart

禁用密码登陆,使用RSA私钥登录

1
2
ssh-keygen #在客户端生成密钥
ssh-copy-id myserver1 #将公钥添加至服务端

还需要配置服务端

1
2
3
sudo vim /etc/ssh/sshd_config
PasswordAuthentication no #禁止密码认证
PermitEmptyPasswords no #禁止空密码用户登录

重启ssh服务

1
sudo service sshd restart

使用 Fail2ban

Ubuntu 16.04 系统源里带有 denyhosts ,到了Ubuntu 20.04默认不再包含。DenyHosts现在几乎不再更新了,所以来使用Fail2ban

检查是否安装了特定软件包

1
2
sudo apt list --installed | grep denyhosts
sudo apt list --installed | grep fail2ban

安装fail2ban

1
sudo apt-get install fail2ban

配置fail2ban

配置文件在 /etc/fail2ban/jail.conf 。 在配置文件的[DEFAULT]区,可以在此定义所有受监控的服务的默认参数

1
2
3
4
5
6
7
8
9
10
11
12
13
[DEFAULT]
# 以空格分隔的列表,可以是 IP 地址、CIDR 前缀或者 DNS 主机名
# 用于指定哪些地址可以忽略 fail2ban 防御
ignoreip = 127.0.0.1/8 ::1

# 客户端主机被禁止的时长
bantime = 60m

# 查找失败次数的时长
findtime = 10m

# 客户端主机被禁止前允许失败的次数
maxretry = 5

根据上述配置,fail2ban会自动禁止在最近10分钟内有超过5次访问尝试失败的任意IP地址。一旦被禁,这个IP地址将会在1小时内一直被禁止访问 SSH 服务

保存配置后重启服务

1
sudo service fail2ban restart

查看fail2ban运行状态

验证fail2ban成功运行:

1
2
$ sudo fail2ban-client ping
Server replied: pong

检验fail2ban状态

1
2
3
4
$ sudo fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd

检验一个特定监狱的状态

1
sudo fail2ban-client status 

上面的命令会显示出被禁止IP地址列表

解锁特定的IP地址

1
sudo fail2ban-client set sshd unbanip 192.168.1.8

自建开源远程桌面工具Rustdesk中继服务器

Rustdesk支持Windows、macOS、Linux、iOS、Android、Web等几乎所有平台,客户端可以在官方网站下载,安装后自动分配id,立即可以使用。但是官方免费的服务器速度有点慢,官方还提供了服务器端程序,我们可以用docker来安装:

1
2
3
4
docker volume create rustdesk_server_data

docker run --name hbbs --net=host -v "rustdesk_server_data:/root" -d rustdesk/rustdesk-server:latest hbbs -r www.redtux.cn
docker run --name hbbr --net=host -v "rustdesk_server_data:/root" -d rustdesk/rustdesk-server:latest hbbr

这样自建的中继服务器就已经成功运行了,然后在自己的每个客户端设置中继服务器为自己的ip就可以了。

使用Acme.sh工具为Ubuntu安装免费ssl证书

安装acme.sh

1
curl https://get.acme.sh | sh -s email=my@example.com

或者

1
wget -O -  https://get.acme.sh | sh -s email=my@example.com

如果上面两个连接不成功,可以用下面国内的源:

1
2
3
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m my@example.com

acme会安装到~/acme.sh目录中,安装完成后重新加载Bash:

1
source ~/.bashrc

配置acme.sh

开启自动更新:

1
acme.sh --upgrade --auto-upgrade

选择默认 CA
目前 acme.sh 支持四个正式环境 CA,分别是 Let’s Encrypt、Buypass、ZeroSSL 和 SSL.com,默认使用 ZeroSSL,如果需要更换可以使用如下命令:

切换 Let’s Encrypt

1
acme.sh --set-default-ca --server letsencrypt

切换 Buypass

1
acme.sh --set-default-ca --server buypass

切换 ZeroSSL

1
acme.sh --set-default-ca --server zerossl

切换 SSL.com

1
acme.sh --set-default-ca --server ssl.com

切换 Google Public CA

1
acme.sh --set-default-ca --server google

使用 DNS 验证签发证书

家用网络都封了80端口,不能使用正常模式申请证书,只能使用DNS验证的模式申请,acme.sh 的 DNS API 模式申请证书:

1
acme.sh --issue --dns dns_cf -d example.com -d *.example.com

acme.sh 支持几十种 DNS 插件,常用的下面几种,:

阿里云 –dns dns_ali

1
2
export Ali_Key="1234"
export Ali_Secret="sADDsdasdgdsf"

Dnspod –dns dns_dp

1
2
export DP_Id="1234"
export DP_Key="sADDsdasdgdsf"

Godaddy –dns dns_gd

1
2
export GD_Key="sdfsdfsdfljlbjkljlkjsdfoiwje"
export GD_Secret="asdfsdfsfsdfsdfdfsdf"

AWS –dns dns_aws

1
2
export AWS_ACCESS_KEY_ID="sdfsdfsdfljlbjkljlkjsdfoiwje"
export AWS_SECRET_ACCESS_KEY="xxxxxxx"

Linode –dns dns_linode

1
export LINODE_API_KEY="xxxxxxxx"

证书申请完成后会提示证书位置:

1
2
3
4
[Sat Jul 29 11:51:54 AM UTC 2023] Your cert is in: /root/.acme.sh/redtux.cn/redtux.cn.cer
[Sat Jul 29 11:51:54 AM UTC 2023] Your cert key is in: /root/.acme.sh/redtux.cn/redtux.cn.key
[Sat Jul 29 11:51:54 AM UTC 2023] The intermediate CA cert is in: /root/.acme.sh/redtux.cn/ca.cer
[Sat Jul 29 11:51:54 AM UTC 2023] And the full chain certs is there: /root/.acme.sh/redtux.cn/fullchain.cer

安装证书

然后我们可以安装证书

Nginx

1
2
3
4
5
acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com.crt \
--ca-file /etc/nginx/ssl/example.com.ca.crt \
--reloadcmd "systemctl restart nginx"

对应的 Nginx 配置指定证书文件

1
2
3
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
ssl_trusted_certificate /etc/nginx/ssl/example.com.ca.crt;

Apache

1
2
3
4
5
acme.sh --install-cert -d example.com \
--key-file /etc/apache2/ssl/example.com.key \
--fullchain-file /etc/apache2/ssl/example.com.crt \
--ca-file /etc/apache2/ssl/example.com.ca.crt \
--reloadcmd "curl https://ssl-config.mozilla.org/ffdhe2048.txt >> /etc/apache2/ssl/example.com.crt && systemctl restart apache2"

对应的 Apache 配置指定证书文件

1
2
SSLCertificateFile      /etc/apache2/ssl/example.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/example.com.key

替代群晖音乐的工具:Navidrome

Linux下的安装

首先安装依赖,navidrome依赖ffmpeg:

1
2
3
sudo apt update
sudo apt upgrade
sudo apt install vim ffmpeg

然后创建navidrome工作的目录结构:

1
2
sudo install -d -o <user> -g <group> /opt/navidrome
sudo install -d -o <user> -g <group> /var/lib/navidrome

下载Navidrome

GitHub下载最新发布版本(用最新版的下载地址替换下面命令中的地址),解压到程序目录/opt/navidrome,赋予目录可执行权限。

1
2
3
wget https://github.com/navidrome/navidrome/releases/download/v0.XX.0/navidrome_0.XX.0_Linux_x86_64.tar.gz -O Navidrome.tar.gz
sudo tar -xvzf Navidrome.tar.gz -C /opt/navidrome/
sudo chown -R <user>:<group> /opt/navidrome

创建配置文件

In the working directory, /var/lib/navidrome create a new file named navidrome.toml with the following settings.

MusicFolder = “
For additional configuration options see the configuration options page.

1
2
3
4
5
6
7
8
9
10
LogLevel = 'DEBUG'
ScanSchedule = '@every 24h'
TranscodingCacheSize = '150MiB'
MusicFolder = '/mnt/music'
Port = '6019'
DefaultLanguage = 'zh-Hans'
EnableSharing = true
EnableTranscodingConfig = true
LastFM.Language = 'zh-Hans'
UIWelcomeMessage = 'Redtuxs Family Music Server'

创建系统服务配置文件

Create a new file under /etc/systemd/system/ named navidrome.service with the following data. Make sure you replace and with the user and group you want to run Navidrome under.

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
[Unit]
Description=Navidrome Music Server and Streamer compatible with Subsonic/Airsonic
After=remote-fs.target network.target
AssertPathExists=/var/lib/navidrome

[Install]
WantedBy=multi-user.target

[Service]
User=<user>
Group=<group>
Type=simple
ExecStart=/opt/navidrome/navidrome --configfile "/var/lib/navidrome/navidrome.toml"
WorkingDirectory=/var/lib/navidrome
TimeoutStopSec=20
KillMode=process
Restart=on-failure

# See https://www.freedesktop.org/software/systemd/man/systemd.exec.html
DevicePolicy=closed
NoNewPrivileges=yes
PrivateTmp=yes
PrivateUsers=yes
ProtectControlGroups=yes
ProtectKernelModules=yes
ProtectKernelTunables=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictNamespaces=yes
RestrictRealtime=yes
SystemCallFilter=~@clock @debug @module @mount @obsolete @reboot @setuid @swap
ReadWritePaths=/var/lib/navidrome

# You can uncomment the following line if you're not using the jukebox This
# will prevent navidrome from accessing any real (physical) devices
#PrivateDevices=yes

# You can change the following line to `strict` instead of `full` if you don't
# want navidrome to be able to write anything on your filesystem outside of
# /var/lib/navidrome.
ProtectSystem=full

# You can uncomment the following line if you don't have any media in /home/*.
# This will prevent navidrome from ever reading/writing anything there.
#ProtectHome=true

# You can customize some Navidrome config options by setting environment variables here. Ex:
#Environment=ND_BASEURL="/navidrome"

启动Navidrome服务

Reload the service daemon, start the newly create service, and verify it has started correctly.

1
2
3
4
sudo systemctl daemon-reload
sudo systemctl start navidrome.service
sudo systemctl status navidrome.service
sudo systemctl restart navidrome.service

如果服务成功启动,你就可以访问http://localhost:4533来访问web端.

让Navidrome随系统启动

1
sudo systemctl enable navidrome.service

用Nginx配置反向代理

反向代理配置文件

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
server {
listen 619 default_server;
listen [::]:619 default_server;

# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;

#root /var/www/start;

# Add index.php to the list if you are using PHP
#index index.html index.htm index.nginx-debian.html;

server_name www.redtux.cn;

client_max_body_size 50000M;

location / {
proxy_pass http://192.168.0.6:6019;

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Protocol $scheme;
proxy_set_header X-Forwarded-Host $http_host;
proxy_buffering off;
}
}

也可以Docker的方式安装,详见官方文档Navidrome官方网站开源音乐服务器,自建云端音乐播放器

客户端

Android手机可以从F-Droid直接安装Subtracks或者Ultrasonic,然后设置服务器地址就可以了。

PC可以使用Sonixd客户端,下载地址,下载对应系统的版本。

号外

其实还有一个自建音乐流媒体服务器koel——基于php fpm docker界面漂亮,唯一缺点就是手机客户端只能从Google play下载,国内只能用浏览器访问。