FFmpeg 官方文档翻译

FFmpeg [global_options] {[input_file_options] -i input_url} ... {[output_file_options] output_url} ...

FFmpeg [全局选项] {[输入文件选项] -i 输入文件路径} ... {[输出文件选项] 输出文件地址} ...

其中,-i 表示 input[] 括起来表示可选项,{} 括起来表示一个或多个必输入项,括号外的全部必输入。

描述

FFmpeg 是一个非常快的音频、视频转换器,他也可以从直播音频、视频源进行抓取。他可以飞快地在各种不同的采样率之间进行转换、调整视频大小、使用高质量多相滤镜。

FFmpeg 读取一个或多个输入文件(可以是普通文件、管道文件、网络视频流、抓取设备等等)(这些输入文件被 -i 选项指定),然后写到一个或多个输出文件(被一段文本路径指定)。在一行命令中任何不能被识别为选项的内容都会被当成输出路径对待。

每个输入或输出路径可以,原则上,包含许多个不同种类的“流”(视频流、音频流、字幕流、附件流、数据流)。允许包含多少个流,受文件封装格式限制。可以自动或用 -map 选项(参阅“流选择”章节)手动选择哪个文件的哪个流写到哪个输出文件。

在选项中涉及输入文件时,你必须使用它们的索引号(从 0 开始的序号)。例如,第一个输入文件是 0,第二个文件是 1,以此类推。同样地,涉及一个文件内的流时也是使用这样的索引。例如,2:3(注意这里是英文冒号)表示第三个输入文件中的第四个流。(参阅“流选择”章节)。

作为总的原则,选项 总是只作用在它 之后 的那个文件上。因此,顺序很重要,你可以在一行命令中使用同一个选项多次。每次使用这个选项,都只作用在后面那个文件上。有一种例外,就是全局选项(例如啰嗦提示级别)(应当被首先指示出)。

不要混淆输入和输出文件,输入文件是先标出,输出文件是后标出。也不要混淆本该属于不同类型文件的选项。所有选项只对它后面那个文件起作用一次,然后就会被恢复默认值。

*设置输出视频的码率为64Kbps:
FFmpeg -i input.avi -b:v 64k -bufsize 64k output.avi

*强制输出视频帧率为24fps:
FFmpeg -i input.avi -r 24 output.avi

*强制输入文件帧率为1fps,同时输出视频为24fps:
FFmpeg -r 1 -i input.m2v -r 24 output.avi

处理的输入文件为原始数据(raw input file)时,可能需要一些格式选项。

详细描述

FFmpeg 对输出文件的转码过程可用下图简述:

_______              ______________
|       |            |              |
| input |  demuxer   | encoded data |   decoder
| file  | ---------> | packets      | -----+
|_______|            |______________|      |
                                           v
                                       _________
                                      |         |
                                      | decoded |
                                      | frames  |
                                      |_________|
 ________             ______________       |
|        |           |              |      |
| output | <-------- | encoded data | <----+
| file   |   muxer   | packets      |   encoder
|________|           |______________|
```
```

FFmpeg 先调用包含分流器(demuxer)的 libavformat 库读取输入文件,得到数据包(内含被编码后的数据)。当存在多个输入文件时,FFmpeg 将通过跟踪最小的时间戳来尝试同步所有活跃的输入流。

编码数据包然后被传递到解码器(除非复制流被选择用于流,详见后面进一步的说明),解码器产生的未压缩的帧(原始视频/PCM 音频/…),后者可以进一步被滤镜处理(见下一节)。通过滤镜处理后,这些帧被传递到编码器,编码器将其编码,并输出编码后的数据包。最后,这些数据包被传递给混合器,以将编码数据写入到输出文件。

滤镜

在使原始数据编码之前,FFmpeg 可以使用 libavfilter 库中的滤镜处理原始音频和视频帧。几个连接的滤镜可以形成一个滤镜组(filtergraphs)。 FFmpeg 有两种 filtergraphs:简单和复合。

简单 filtergraphs

简单 filtergraphs 是那些恰好只有一个输入和输出、并且输入输出都是相同类型的滤镜组。在下图中,它们可以被表示为,简单地在解码和编码之间插入一个附加步骤:

_________                        ______________
|         |                      |              |
| decoded |                      | encoded data |
| frames  |\                   _ | packets      |
|_________| \                  /||______________|
             \   __________   /
  simple     _\||          | /  encoder
  filtergraph   | filtered |/
                | frames   |
                |__________|
```
```

简单 filtergraphs 由对每个流的滤镜选项(-vf 和 -af 分别表示针对视频和音频的滤镜)配置。一个针对视频的简单 FilterGraph 可以看下这个例子:

_______        _____________        _______        ________
|       |      |             |      |       |      |        |
| input | ---> | deinterlace | ---> | scale | ---> | output |
|_______|      |_____________|      |_______|      |________|

需知晓的是一些滤镜只改变帧的属性而不触及帧的内容。例如在上例中,fps 滤镜只改变帧的数量,不改变帧的内容。又如 setpts 滤镜,仅设置时间戳而保持帧不变。

复合 filtergraphs

复合 filtergraphs 是那些不能被描述为简单的线性处理链的滤镜组。例如,当滤镜组具有多个输入和(或)输出,或当输入和输出流是不同的类型。它们可以被表示为以下图:

_________
|         |
| input 0 |\                    __________
|_________| \                  |          |
             \   _________    /| output 0 |
              \ |         |  / |__________|
 _________     \| complex | /
|         |     |         |/
| input 1 |---->| filter  |\
|_________|     |         | \   __________
               /| graph   |  \ |          |
              / |         |   \| output 1 |
 _________   /  |_________|    |__________|
|         | /
| input 2 |/
|_________|

复合 filtergraphs 可使用 -filter_complex 选项指配。注意,此选项是全局性的,因为复合 FilterGraph,就其本质,不能只与单个流、单个文件相关联。

-lavfi 选项相当于 -filter_complex 选项。

一个复合 FilterGraph 的简单的例子是 overlay 滤镜,它具有两个视频输入和一个视频输出,内有一个视频叠加在另一个视频上面。其对应功能的音频滤镜是 amix 滤镜。

复制流

复制流是通过添加 copy 选项到 -codec 选项完成的。它使 FFmpeg 对指定的流忽略解码和编码步骤,所以它只能混合和拆包(例如从一个 mkv 文件拆包提取出视频流,放到一个 mp4 输出文件内打包,就仅仅是把视频流复制了,达到了无损转格式)。它对于改变所述容器的格式或修改容器级的元数据是有用的。在这种情况下,可以简化为这样:

_______              ______________            ________
|       |            |              |          |        |
| input |  demuxer   | encoded data |  muxer   | output |
| file  | ---------> | packets      | -------> | file   |
|_______|            |______________|          |________|

由于不存在解码或编码,复制流非常快(几乎等于复制粘贴的速度),没有画质或音质损失。然而因为许多因素,某些情况下可能无法使用。应用滤镜显然也是不可能的,因为滤镜仅能作用在未压缩的数据上(而拆包后的数据流都还是被编码了的、压缩了的数据)。

流的选择

FFmpeg 提供 -map 选项来手动控制每个输出文件中流的选择。用户可以跳过 -map 选项,让 FFmpeg 执行自动流选择(规则在下面提到)。不管是手动映射(map)还是自动选择,使用 -vn / -an / -sn / -dn 选项分别可以跳过输出文件对视频流、音频流、字幕流、数据流的选择(不过对那些复合 filtergraphs 输出的流不起作用)。

描述

接下来的小节叙述了涉及到流的选择的各种规则。后面会有例子帮你理解。

虽然,为了能够精确的反映程序的行为,文档作者们付出了很多努力来完善这个文档,但是 FFmpeg 是在被持续开发和完善的,自从写下这个文档,有些代码就可能已经改变了。

自动流选择

对于某一个输出文件,在映射(map)选项缺失的情况下,FFmpeg 会检查输出文件格式,看哪些种类的流可以被打包进去,例如视频流、音频流、字幕流。对于每个可以打包进去的种类,FFmpeg 会从所有可用的输入文件中选择一个流。

FFmpeg 会基于以下原则选择流:

在相同种类的几个流的参数同样高时,选择索引号最低的那个流。

数据流或附件流不会被自动选择,他们只能被 -map 选项选择。

手动流选择

当 -map 选项被使用时,除了下面会提到的 filtergraph 输出流,只有用户映射的(user-mapped)流会被包含在那个输出文件。

复合 filtergraph

当有一些复合 filtergraph 输出流带着未标记的 pads 时,这些输出流会被加到第一个输出文件。当这个流不被输出文件的格式支持时,就会导致严重错误。当没有 -map 选项时,这些复合 filtergraph 输出流的包含,会导致它们类型的流的自动选择被跳过。当有 -map 选项时,除了被手动映射的流,这些复合 filtergraph 输出流也会被额外囊括进去。

流处理

流处理是独立于流选择之外的(除了下面会讲到的字幕是例外)。流处理是通过-codec 选项来设定的,作用于指定输出文件内的流。尤其是,FFmpeg 是在流选择过程之后才实施流处理过程的,所以流处理过程不会影响流选择。如果对某个流没有指定 -codec 选项,FFmpeg 会根据输出文件的混合器(muxer)选择默认注册的编码器(encoder)。

对于字幕存在例外。如果一个输出文件的字幕编码器被指定,第一个被找到的字幕流(不管是文字、还是图像类型)都会被打包进去。FFmpeg 不检查指定的编码器是否能转换选择的流,也不检查转换后的流是否能被输出文件的格式兼容。这条规则是通用的:当用户手动设定一个编码器时,流选择过程无法检查被编码过的流可以被混合到输出文件中。如果不能,FFmpeg 会放弃所有输出文件,然后处理过程失败。

范例

接下来的例子会阐释 FFmpeg 流选择方法的行为、难点和限制。

假设有下列三个输入文件:

input file 'A.avi'
  stream 0: video 640x360
  stream 1: audio 2 channels

input file 'B.mp4'
  stream 0: video 1920x1080
  stream 1: audio 2 channels
  stream 2: subtitles (text)
  stream 3: audio 5.1 channels
  stream 4: subtitles (text)

input file 'C.mkv'
  stream 0: video 1280x720
  stream 1: audio 2 channels
  stream 2: subtitles (image)

自动流选择

FFmpeg -i A.avi -i B.mp4 out1.mkv out2.wav -map 1:a -c:a copy out3.mov

这里指定了三个输出文件,对于前两个,没有设定 -map 选项,所以 FFmpeg 会为这两个文件自动选择流。

out1.mkv 是一个 Mastroska 容器的文件,可以存放视频、音频、字幕流,所以 FFmpeg 会每个种类选一个流。

out2.wav 只接受音频流,所以只有 B.mp4 中的 stream 3 会被选择。

对于 out3.mov,因为有了 -map 选项,就不会发生流的自动选择了。-map 1:a 选项会选择第二个输入文件 B.mp4 中的所有音频流,不会有任何其它流被打包到这个输出文件。

自动字幕选择

FFmpeg -i C.mkv out1.mkv -c:s dvdsub -an out2.mkv

尽管 out1.mkv 是一个能够容纳字幕流的 Matroska 容器文件,但这个例子里只有视频和音频流会被选择。C.mkv 里的字幕是基于图像的,而 Mastroska 的默认字幕编码器是基于文字的,所以转码会失败,因而字幕流不会被选择。不过,out2.mkv 里,我们在命令里手动指定了一个字母编码器,所以,除了视频流,字幕流也会被选择加进 out2.mkv。-an 选项禁止了 out2.mkv 的音频流选择。

未写标签的 filtergraph 输出

FFmpeg -i A.avi -i C.mkv -i B.mp4 -filter_complex "overlay" out1.mp4 out2.srt

这里我们通过-filter_complex 选项设置了一个 filtergraph ,后者包含一个视频滤镜。overlay 滤镜要求正好两个视频输入,因为没有指定哪两个,所以会默认使用前两个可用的视频,也就是 A.avi 和 C.mkv 。由于这样,本来会选择 B.mp4 里面的流的自动视频流选择过程也就被跳过了。在 B.mp4 的 stream 3 里的音频流由最多的声道,会被自动选择上。然而不会有字幕流会被选择上,因为 mp4 格式没有默认注册的字幕编码器,而且用户也没有指定一个字母编码器。

对于第二个输出文件,out2.srt,只接受基于文字的字幕流。所以尽管第一个可用字幕流(那个属于 C.mkv 的)存在,但由于它是基于图像的所以会被跳过。被选择的流,B.mp4 中的 stream 2 ,是第一个基于文本的字幕流。

写了标签的 filtergraph 输出

(下述命令中,末尾的 / 在终端里表示换一行显示,继续写命令,执行的时候是把那几行命令当一行执行的)

FFmpeg -i A.avi -i B.mp4 -i C.mkv -filter_complex "[1:v]hue=s=0[outv];overlay;aresample" \
   -map '[outv]' -an        out1.mp4 \
out2.mkv \
   -map '[outv]' -map 1:a:0 out3.mkv

上述命令会失败,因为带有[outv] 标签的输出板被映射了两次。所有输出文件都不会被处理。

FFmpeg -i A.avi -i B.mp4 -i C.mkv -filter_complex
 "[1:v]hue=s=0[outv];overlay;aresample" \
   -an        out1.mp4 \
  out2.mkv \
   -map 1:a:0 out3.mkv

上述这个命令也会失败,因为带有[outv] 标签的 hue 滤镜的输出,没有被映射到任何一个输出文件。

这个命令应该像这样修改:

FFmpeg -i A.avi -i B.mp4 -i C.mkv -filter_complex "[1:v]hue=s=0,split=2[outv1][outv2];overlay;aresample" \
-map '[outv1]' -an        out1.mp4 \
  out2.mkv \
-map '[outv2]' -map 1:a:0 out3.mkv

B.mp4 中的视频流被送到 hue 滤镜,后者的输出结果被 split 滤镜克隆了一份,两份输出分别被映射到第一个和第三个输出文件。

overlay 滤镜,要求两个视频输入,会使用前两个未被使用的视频流,也就是 A.avi 和 C.mkv 中的视频流。overlay 滤镜的输出没有被写标签,所以它会被发到第一个输出文件 out1.mp4 ( -map 选项对它不起作用)。

第一个未被使用的音频流,也就是 A.avi 的音频流,被送到 aresample 滤镜处理。因为这个滤镜的输出也是没有写标签的,所以也会被自动映射到第一个输出文件。-an 选项只抑制音频流的自动流选择、手动流选择,不会抑制 filtergraphs 送来的音频流。在 out1.mp4 中,这两个滤镜送出的流会排在映射的流的前面。

哪些音频、视频、字幕流被映射到 out2.mkv 完全取决于自动流选择。

out3.mkv 包含有 hue 滤镜输出的克隆流和来自 B.mp4 的第一个音频流。

选项

所有的数字选项,如果没有明确指名,接受由字符串表示的数字作为输入,后可接一个 SI 单位后缀,例如:K、M、G。

如果“i”被接到了 SI 单位后缀后,整个后缀会被当成二进制倍数后缀,也就是用 1024 为底的指数,而不是 1000 为底的指数。SI 单位后缀后接上“B”,会把其值乘以 8。这就可以用,例如:KB、MiB、G、B 作为数字后缀。(很好理解,bit 表示比特,Byte 表示字节,1 字节等于 8 比特)

没有后续参数的选项都是布尔选项,会将该选项设为启用。也可以通过加一个前缀“no”把这个选项关闭。例如“-nofoo”会把名字是“foo”的布尔选项关闭。

流标识符(Stream specifiers)

有些选项可能是应用到具体一个流上的,例如比特率、编码器。流标识符就是用来精确指明一个选项是属于哪个流的。

流标识符通常被连接到选项名字的后面,用冒号隔开。例如“-codec🅰️1 ac3”包含了“a:1”流标识符,匹配第二个音频流(audio 首字母是 a)。因此,对第二个音频流会使用 ac3 作为编码器(codec)。

一个流标识符可以匹配多个流,此时这个选项会应用到所有匹配到的流上。例如“-b:a 128k”会匹配所有的音频流。

没有标识符会匹配所有流,例如,-codec copy 或 -codec: copy 会让所有的流进行流复制(而不进行重新编码)。

流标识符可用的格式有:

匹配这个索引号下的流,例如 -threads:1 会设置第二个流的线程设为 4。如果流索引号是作为附加标识符(见下面)的,那它就会选取匹配的所有流下的第索引号个流。流的序号是由 libavformat 检测流的顺序决定的,除了当程序 ID 被指定时。这时,序号是基于程序中的顺序决定的。

流类型是下列字母之一:v 或 V 表示视频(video),a 为声音(audio),s 为字幕(subtitle),d 为数据(data),t 为附件(attatchments)。“v” 匹配所有的视频流,“V”只会匹配没有附加图片、缩略图、封面的视频。如果额外流标识符添加上了,那就只会匹配符合指定类型、并且匹配额外流标识符的流。否则,它就只会匹配所有符合指定类型的流

匹配拥有指定 id 的程序内的流。如果额外流标识符添加上了,那就只会匹配在拥有指定 id 的程序内的、并且匹配额外流标识符的流。

用流 id 匹配流(例如 MPEG-TS 容器内的 PID)。

匹配元数据(metadata)中拥有指定标签项值的流。如果没有指定项值(value),就只匹配所有包含指定标签项的流。

匹配哪些拥有可用调整项的流,编码器必须被指定,并且关键信息(例如视频维度或音频采样率)必须被呈现。

应当知道,在 FFmpeg 中,通过元数据匹配只对输入文件有效。

通用选项

这些选项在 ff* 工具中通用

AVOptions(音视频选项)

这些选项是由 libavformat、libavdevice 和 libavcodec 库直接提供的,若要查看可用的 AVOptions 的列表,使用 -help 选项。它们被分成两类:

Generic(通用)

这些选项可以用于各种容器、编码器、设备。对于容器/设备的通用选项被列在 AVFormatContext 选项下,对于编码器的通用选项被列在 AVCodecContext 选项下。

Private(私有)

这些选项只能用于特定容器、编码器、设备。私有选项被列在对应的容器、编码器、设备下。

例如要写一个 ID3v2.3 头到一个 mp3 文件,而不是写 ID3v2.4 头,要使用 MP3 混流器 id3v2_version 的私有选项:

FFmpeg -i input.flac -id3v2_version 3 out.mp3

所有的编码器音视频选项都是针对“流”的,所以应当在选项后面加上流标识符:

FFmpeg -i multichannel.mxf -map 0:v:0 -map 0:a:0 -map 0:a:0 -c:a:0 ac3 -b:a:0 640k -ac:a:1 2 -c:a:1 aac -b:2 128k out.mp4

在上述的示例命令中,一个多声道的音频流被两次映射到输出(也就是输出文件被映射了两个音频流,两个音频流的内容一样)。对第一个音频流使用了 ac3 编码器、码率值 640k。对第二个音频流使用了混合成双声道、码率值 128k(这里我们的流标识符使用了数字索引值,2 即代表第三个流)。

提醒:之前提到的 -nooption 语法不能被用于布尔 AVOptions ,应使用 -option 0 / -option 1 才行。

提醒:有一个没有提到的、老旧的、用于给 AVOptions 指定流的方法是在这些选项前加上 v/a/s ,但是这个方法已经过时,并且即将在后续版本中被删去了,所以别再用了!

主要选项

视频选项

高级视频选项

音频选项

高级音频选项

字幕选项

高级字幕选项

高级选项

预设文件(Preset files)

预设文件包含一系列“option=value 对”,一行一个,表示一系列用命令行输起来很麻烦的选项。一行以”#“开头会被忽略,用于做注释。你可以查看 FFmpeg 源目录的 presets 文件夹查看例子。

总共有两种预设文件:ffpreset 和 avpreet 文件。

ffpreset 文件

ffpreset 文件由 vpre、apre、spre、fpre 选项组成。fpre 选项用预设文件名作为输入(而不是用预设名),并且可以被用于所有编码器。至于 vpre、apre、spre 选项,预设文件只用于当前选择的与预设选项相同类型的编码器。

传递给 vpre、apre、spre 预设的参数选项依据以下原则决定这个预设被如何用:

首先 FFmpeg 在按以下顺序在以下路径内搜索名为“arg.ffpreset”的文件:

$FFmpeg_DATADIR
 $HOME/.FFmpeg

数据文件夹(在配置时指定的,通常时是 PREFIX/share/FFmpeg)或 win32 可执行程序内的 ffpresets 文件夹
例如,若参数是 libvpx-1080p,那就会找一个叫 libvpx-1080p.ffpreset 的文件。

如果找不到这样一个文件,然后 FFmpeg 会在上述文件夹中查找一个叫 codec_name-arg.ffpreset 的文件(这里 codec_name 表示该预设将作用于的编码器的名字)。例如,如果你选择 -vcodec libvpx 编码器,并使用 -vpre 1080p 预设,那就会寻找名叫“libvpx-1080p.ffpreset”的文件。

avpreset 文件

avpreset 文件由 pre 选项定义。它们和 ffpreset 文件的原理类似,不过后者有针对编码器的选项。所以,一个“option=value pair”表示无法使用编码器。(好绕口,我把原文留下)
(avpreset files are specified with the pre option. They work similar to ffpreset files, but they only allow encoder- specific options. Therefore, an option=value pair specifying an encoder cannot be used.)

当 pre 选项被定义上,FFmpeg 会按以下顺序在以下文件夹寻找带有“.avpreset”后缀的文件:

$AVCONV_DATADIR
$HOME/.avconv

数据文件夹(在配置时指定的,通常时是 PREFIX/share/FFmpeg)

首先,FFmpeg 在上述文件夹找到一个叫 “codec_name-arg.avpreset”的文件(这里 codec_name 表示该预设将作用于的编码器的名字)。例如,你用“-vcodec libvpx”选择了视频编码器,使用了“-pre 1080p”,那它就会寻找一个叫“libvpx-1080p.avpreset”的文件。

如果没有找到这个文件,那 FFmpeg 就会在同样的文件夹内找一个叫“arg.avpreset”的文件。

范例

音视频抓取

如果你指定了输入格式和设备,接着 FFmpeg 就可以直接抓取音频和视频了:

FFmpeg -f oss -i /dev/dsp -f video4linux2 -i /dev/video0 /tmp/out.mpg

或者不用 OSS,而用 ALSA 音频源 (mono input, card id 1) :

FFmpeg -f alsa -ac 1 -i hw:1 -f video4linux2 -i /dev/video0 /tmp/out.mpg

提醒下,在带着任何 TV 播放器(例如 Gerd Knorr 写的 xawtv)启动 FFmpeg 时,确保激活了正确的视频源和声道。你还需要用一个标准混音器正确地设置音频录制 level 。

X11 抓取

用 FFmpeg 抓取 X11 的显示内容:

FFmpeg -f x11grab -video_size cif -framerate 25 -i :0.0 /tmp/out.mpg

0.0 是你的 X11 服务器的显示屏的序号,和 DISPLAY 环境变量相同。

FFmpeg -f x11grab -video_size cif -framerate 25 -i :0.0+10,20 /tmp/out.mpg

0.0 是你的 X11 服务器的显示屏的序号,和 DISPLAY 环境变量相同。10 是 x 方向偏移,20 是 y 方向偏移。

视频和音频格式转换

任何支持的文件格式和协议都可以当作 FFmpeg 的输入。

例如:

更多参考

更多的内容,请参阅 http://FFmpeg.org/ 的下列文档:

FFmpeg-all, ffplay, ffprobe, FFmpeg-utils, FFmpeg-scaler, FFmpeg-resampler, FFmpeg-codecs, FFmpeg-bitstream-filters, FFmpeg-formats, FFmpeg-devices, FFmpeg-protocols, FFmpeg-filters

作者

原英文文档作者为 FFmpeg 的开发者们。本文由淳帅二代翻译。

若要查看关于作者权的详情信息,请通过在 FFmpeg 的源文件夹输入“Git log”命令,或进入 http://source.FFmpeg.org 访问在线库,来参阅这个项目(git://source.FFmpeg.org/FFmpeg)的 Git 历史。

源代码树的“MAINTAINERS”文件中列出了所有特定组件的维护者。

该文档的英文原版生成于 2020 年 2 月 16 号。译于 2020 年 2 月 16 号

补充

如果您帧率模式选择的是 VFR,您可能会遇到视频和音频同步问题。 在这种情况下,您必须使用 “Motion JPEG” 和 “PCM” 编码器。 如果您使用 “Motion JPEG” 和 “PCM” 编码器还有同步问题,则必须降低录制目标的视频分辨率。

  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    19 引用 • 29 回帖 • 3 关注
  • 文档
    54 引用 • 1238 回帖 • 1 关注
  • 翻译
    47 引用 • 79 回帖
1 操作
HaujetZhao 在 2020-07-28 18:41:56 更新了该帖

赞助商 我要投放

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...