音视频学习-音视频基础

`

文章目录


一、 音视频录制原理

二、音视频播放原理

三、图像基础概念

◼ 像素:像素是一个图片的基本单位,pix是英语单词picture的简写,加上英语单词"元素element",就得到了"pixel",简称px,所以"像素"有"图像元素"之意。

◼ 分辨率:是指图像的大小或尺寸。比如1920x1080。

◼ 位深:是指在记录数字图像的颜色时,计算机实际上是用每个像素需要的位深来表示的。比如红色分量用8bit。

◼ 帧率:在1秒钟时间里传输的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次。比如25fps表示一秒有25张图片。

◼ 码率:视频文件在单位时间内使用的数据流量。比如1Mbps。

◼ Stride:指在内存中每行像素所占的空间。为了实现内存对齐每行像素在内存中所占的空间并不一定是图像的宽度。

1.像素

像素是一个图片的基本单位,pix是英语单词picture的简写,加上英语单词"元素element",就得到了"pixel",简称px,所以"像素"有"图像元素"之意。

例如2500×2000的照片就是指横向有2500个像素点,竖向有2000个像素点,总共是500万个像素,也俗称500万像素照片。

2.分辨率

图像(或视频)的分辨率是指图像的大小或尺寸。我们通常用像素表示图像的尺寸。例如2500×2000的照片就是指横向(宽)有2500个像素点,竖向(高)有2000个像素点。

常见的分辨率:

360P(640x360)、720P(1280x720)、1080P(1920x1080)、4K(3840x2160)、8K(7680x4320)

不同分辨率之间的区别:

常说的 1080 和 720 其实是指垂直像素数,分辨率除去垂直像素,还需要考虑到水平像素数。按照 16:9 (宽 : 高) 的比例计算,720p 的水平像素数为 720 ÷ 9 × 16 = 1280,总计像素为921600像素即大约为 92 万像素。1080p 具有 1920 个水平像素,总计2073600像素即约 200 万像素,是 720p 的两倍多。

像素越多视频就越清晰,所以 1080p 比 720p 的视频更加清晰。图像的分辨率越高,图像就越清晰。

3.位深

我们看到的彩色图片,都有三个通道,分别为红®、绿(G)、蓝(B)通道。(如果需要透明度则还有alpha分量)

通常每个通道用8bit表示,8bit能表示256种颜色,所以可以组成256256 256=16,777,216 = 1677万种颜色。

这里的8bit就是我们讲的位深。

每个通道的位深越大,能够表示的颜色值就越大,比如现在高端电视说的10bit色彩,即是每个通道用10bit表示,每个通道有1024种颜色。10241024 1024约为10,7374万色=10亿色, 是8bit的64倍。

常见的颜色还是8bit居多。

4.帧率

帧率即 FPS(每秒有多少帧画面),经常玩游戏的应该会对这个词很熟悉。我们玩游戏时,FPS 帧率越高就代表游戏画面越流畅,越低则越卡顿。视频也是如此。由于视觉图像在视网膜的暂时停留,一般图像帧率能达到24帧,我们就认为图像是连续动态的。

电影帧率一般是 24fps(帧每秒);

电视剧一般是25fps;

监控行业常用 25fps;

音视频通话常用15fps;

帧率越高,画面越流畅,需要的设备性能也越高。

5.码率

◼ 视频文件在单位时间内使用的数据流量。比如1Mbps。

◼ 大多数情况下码率越高 分辨率越高,也就越清晰。但模糊的视频文件大小(码率)也可以很大,分辨率小的视频文件可能也比分辨率大的视频文件清晰。

◼ 对于同一个原始图像源的时候,同样的编码算法,则码率越高,图像的失真就会越小,视频画面就会越清晰

6.Stride跨距

◼ Stride :指在内存中每行像素所占的空间。为了实现内存对齐每行像素在内存中所占的空间并不一定是图像的宽度。

◼ Stride 就是这些扩展内容的名称,Stride 也被称作 Pitch,如果图像的每一行像素末尾拥有扩展内容,Stride 的值一定大于图像的宽度值,就像下图所示:

◼ 比如分辨率638x480的RGB24图像,我们在内存处理的时候如果要以16字节对齐,则6383/16=119.625不能整除,因此不能16字节对齐,我们需要在每行尾部填充6个字节。就是(638+2->640), 640 3/16=120。此时该图片的stride为1920字节。

四、RGB、YUV

◼ RGB:红R、绿G、蓝B三基色。

◼ YUV:"Y"表示明亮度(Luminance或Luma),也就是灰阶值,"U"和"V"表示的则是色度(Chrominance或Chroma)。

1.RGB

通常我们采用RGB模型来表示颜色,RGB模型中,每种颜色需要3个数字分别表示R、G、B,每个数字占用1个bit字节,这样总共需要24bits

如果添加透明度,则总共需要32bits

2.YUV

◼ 与我们熟知RGB类似,YUV也是一种颜色编码方法,它是指将亮度参量(Y:Luminance

或Luma)和色度参量(UV:Chrominance或Chroma)分开进行表示的像素编码格式。

◼ 这样分开的好处就是不但可以避免相互干扰,没有UV信息一样可以显示完整的图像,

因而解决了彩色电视与黑白电视的兼容问题;还可以降低色度的采样率而不会对图像

质量影响太大,降低了视屏信号传输时对频宽(带宽)的要求。

◼ Y Y共用一组UV分量

◼ YUV是一个比较笼统地说法,针对它的具体排列方式,可以分为很多种具体的格式:

◼ 打包(packed)格式:将每个像素点的Y、U、V分量交叉排列并以像素点为单元连续的存放

在同一数组中,通常几个相邻的像素组成一个宏像素(macro-pixel)

◼ 平面(planar)格式:使用三个数组分开连续的存放Y、U、V三个分量,即Y、U、V分别存放在各自的数组中。

◼ YUV采用A:B:C表示法来描述Y,U,V采样频率比例,下图中黑点表示采样像素点Y分量,

空心圆表示采样像素点的UV分量。主要分为 YUV 4:4:4、YUV 4:2:2、YUV 4:2:0 这几种

常用的类型

◼ 4:4:4 表示色度频道没有下采样,即一个Y分量对应着一个U分量和一个V分量。

◼ 4:2:2 表示 2:1 的水平下采样,没有垂直下采样,即每两个Y分量共用一个U分量和一个V分量。

◼ 4:2:0 表示 2:1 的水平下采样,2:1 的垂直下采样,即每四个Y分量共用一个U分量和一个V分量。

◼ 下面以每个分量数据存储在一个char(或byte)中为例描述YUV的数据存储方式。

1. 4:4:4格式

◼ 比如I444(YUV444P)格式, 对应Ffmpeg像素表示AV_PIX_FMT_YUV444P, ///< planar YUV

4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)

2. 4:2:2格式

◼ 对应Ffmpeg像素表示AV_PIX_FMT_YUV422P, ///< planar YUV 4:2:2, 16bpp, (1 Cr& Cb sample per 2x1 Y samples)

◼ 该类型为planar格式

3. 4:2:0格式

◼ I420(YUV420P)格式

◼ 对应Ffmpeg像素表示AV_PIX_FMT_YUV420P, ///< planar YUV 4:2:0, 12bpp, (1 Cr& Cb sample per 2x2 Y samples)

◼ 该类型为planar格式

◼ (4+1+1)/4 = 1.5字节

◼ NV12格式

◼ 对应Ffmpeg像素表示AV_PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane

for Y and 1 plane for the UV components, which are interleaved (first byte U and

the following byte V)

4. 4:2:0数据格式对比

◼ YUV420p:

YV12:YYYYYYYY VV UU

I420: YYYYYYYY UU VV

◼ YUV420sp:

NV12:YYYYYYYY UV UV

NV21:YYYYYYYY VU VU

3.RGB和YUV的转换

◼ 通常情况下RGB和YUV直接的相互转换都是调用接口实现,比如Ffmpeg的swscale或者libyuv等库。

◼ 主要转换标准是 BT601 和 BT709。

8bit位深的情况下

◼ TV range是16-235(Y)、16-240(UV) , 也叫Limited Range

◼ PC range是0-255,也叫Full Range

◼ 而RGB没有range之分,全是0-255

◼ BT601 TV Range转换公式

YUV(256 级别) 可以从8位 RGB 直接计算:
Y = 0.299*R + 0.587*G + 0.114*B;
U = -0.169*R - 0.331*G + 0.5 *B ;
V = 0.5 *R - 0.419*G - 0.081*B;
反过来,RGB 也可以直接从YUV (256级别) 计算:
R = Y + 1.402 (Y-128)
G = Y - 0.34414 (U-128) - 0.71414 (U-128)
B = Y + 1.772 (V-128)

◼ 从YUV 转到 RGB 如果值小于0要取0,如果大于255要取255

RGB和YUV的转换-为什么解码出错显示绿屏?

因为解码失败时YUV分量都填为0值,然后根据公式:

R = 1.402 * (-128) = -126.598

G = -0.34414*(-128) - 0.71414*(-128) = 44.04992 + 91.40992 = 135.45984

B = 1.772 * (-128) = -126.228

RGB 值范围为[0,255], 所以最终的值为:

R = 0

G = 135.45984

B = 0

此时只有G分量有值所以为绿色。

YUV -> RGB

4.YUV Stride对齐问题

比如分辨率638x480的YUV420P图像,我们在内存处理的时候如果要以16字节对齐,则638不能被16整除,我们需要在每行尾部填充2个字节。就是640。此时该图片的Y stride为640字节。

五、视频的主要概念

1.基本概念

视频码率:kb/s,是指视频文件在单位时间内使用的数据流量,也叫码流率。码率越大,说明单位时间内取样率越大,数据流精度就越高。

视频帧率:fps,通常说一个视频的25帧,指的就是这个视频帧率,即1秒中会显示25帧。帧率越高,给人的视觉就越流畅。

视频分辨率:分辨率就是我们常说的640x480分辨率、1920x1080分辨率,分辨率影响视频图像的大小。

2.I P B帧

  1. I 帧(Intra coded frames):

    I帧不需要参考其他画面而生成,解码时仅靠自己就重构完整图像;

     I帧图像采用帧内编码方式;
     I帧所占数据的信息量比较大;
     I帧图像是周期性出现在图像序列中的,出现频率可由编码器选择;
     I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);
     I帧是帧组GOP的基础帧(第一帧),在一组中只有一个I帧;
     I帧不需要考虑运动矢量;
    
  2. P 帧(Predicted frames):

    根据本帧与相邻的前一帧(I帧或P帧)的不同点来压缩本帧数据,同时利用了空间和时间上的相关性。

    P帧属于前向预测的帧间编码。它需要参考前面最靠近它的I帧或P帧来解码。

  3. B 帧(Bi-directional predicted frames):

    B 帧图像采用双向时间预测,可以大大提高压缩倍数。需要参考前面的I帧和它后面的帧就行预测。

3.视频文件封装格式

封装格式(也叫容器),就是将已经编码压缩好的视频轨和音频轨按照一定的格式放到一个文件中,也就是说仅仅是一个外壳,或者大家把它当成一个放视频轨和音频轨的文件夹也可以。说得通俗点,视频轨相当于饭,而音频轨相当于菜,封装格式就是一个碗,或者一个锅,用来盛放饭菜的容器。 下面是几种常用的 视频文件后缀类型 与其相对应的 封装格式

视频文件格式 视频封装格式
.avi AVI(Audio Video Interleaved)
.wmv、.asf WMV(Windows Media Video)
.mpg、.mpeg、.vob、.dat、.3gp、.mp4 MPEG(Moving Picture Experts Group)
.mkv Matroska
.rm、.rmvb Real Video
.mov QuickTime File Format
.flv Flash Video

4.音视频编码方式

  1. 视频编码方式
    视频编码的作用:将视频像素数据(RGB,YUV 等)压缩成视频码流,从而降低视频的数据量。
名称 推出机构 推出时间 目前使用领域
HEVC(H.265) MPEG/ITU-T 2013 研发中
H.264 MPEG/ITU-T 2003 各个领域
MPEG4 MPEG 2001 不温不火
MPEG2 MPEG 1994 数字电视
VP9 Google 2013 研发中
VP8 Google 2008 不普及
VC-1 Microsoft Inc. 2006 微软平台
视频文件格式 视频封装格式 释义
.avi AVI(Audio Video Interleave) 图像质量好,但体积过于庞大,压缩标准不统一,存在高低版本兼容问题。
.wmv WMV(Windows Media Video) 可边下载边播放,很适合网上播放和传输
.mpg .mpeg .mpe .dat .vob .asf .3gp .mp4 MPEG(Moving Picture Experts Group) 由运动图像专家组制定的视频格式,有三个压缩标准,分别是 MPEG-1、MPEG-2、和 MPEG-4,它为了播放流式媒体的高质量视频而专门设计的,以求使用最少的数据获得最佳的图像质量。
.mkv Matroska 一种新的视频封装格式,它可将多种不同编码的视频及 16 条以上不同格式的音频和不同语言的字幕流封装到一个 Matroska Media 文件当中。
.rm、.rmvb Real Video Real Networks 公司所制定的音频视频压缩规范称为 Real Media。用户可以使用 RealPlayer 根据不同的网络传输速率制定出不同的压缩比率,从而实现在低速率的网络上进行影像数据实时传送和播放。
.mov QuickTime File Format Apple 公司开发的一种视频格式,默认的播放器是苹果的 QuickTime。这种封装格式具有较高的压缩比率和较完美的视频清晰度等特点,并可以保存 alpha 通道。
.flv Flash Video 由 Adobe Flash 延伸出来的一种网络视频封装格式。这种格式被很多视频网站所采用。
  1. 音频编码方式
    音频编码的作用: 将音频采样数据(PCM 等)压缩成音频码流,从而降低音频的数据量。 常用的音频编码方式有以下几种:
名称 推出机构 推出时间 目前使用领域
AAC MPEG 1997 各个领域(新)
MP3 MPEG 1993 各个领域(旧)
WMV Microsoft Inc. 1999 微软平台
AC-3 Dolby Inc. 1992 电影

六、音频基础

1.声音的物理性质

  1. 振动

    声音是一种由物体振动引发的物理现象,如小提琴的弦声等。物体的振动使其四周空气的压强产生变化,这种忽强忽弱变化以波的形式向四周传播,当被人耳所接收时,我们就听见了声音。

  2. 波形

    声音是由物体的振动产生的,这种振动引起了周围空气压强的振荡,我们称这种振荡的函数表现形式为波形.

  3. 频率

    声音的频率是周期的倒数,它表示的是声音在1秒钟内的周期数,单位是赫兹(Hz)。千赫(kHz),即1000Hz,表示每秒振动1000次。声音按频率可作如下划分:

      次声		                 0~20Hz
      人耳能听见的声音 	20Hz~20KHz
      超声					    20KHz~1GHz
      特超声					1GHz~10THz 
    
  4. 振幅

    声音有振幅,振幅的主观感觉是声音的大小。声音的振幅大小取决于空气压力波距平均值(也称平衡态)的最大偏移量。

2.数字音频

计算机并不直接使用连续平滑的波形来表示声音,它是每隔固定的时间对波形的幅值进行采样,用得到的一系列数字量来表示声音。下方右图 是经过数字采样的波形示意图。

PCM脉冲编码调制

PCM(Pulse Code Modulation),脉冲编码调制。人耳听到的是模拟信号,PCM是把声音从模拟信号转化为数字信号的技术。

  1. 采样频率

    根据Nyguist采样定律,要从采样中完全恢复原始信号波形,采样频率必须至少是信号中最高频率的两倍。

    前面提到人耳能听到的频率范围是[20H~20kHz],所以采样频率一般为44.1Khz,这样就能保证声音到达20Khz也能被数字化,从而使得经过数字化处理之后,人耳听到的声音质量不会被降低。

    采样频率:每秒钟采样的点的个数。常用的采样频率有:

采样频率 应用领域
22000(22kHz) 无线广播
44100(44.1kHz) CD音质
48000(48kHz) 数字电视,DVD
96000(96kHz) 蓝光,高清DVD
192000(192kHz) 蓝光,高清DVD
  1. 采样量化
    采样是在离散的时间点上进行的,而采样值本身在计算机中也是离散的。
    采样值的精度取决于它用多少位来表示,这就是量化。例如8位量化可以表示256个不同值,而CD质量的16位量化可以表示65 536个值,范围为[-32768, 32767]。

下图是一个3位量化的示意图,可以看出3位量化只能表示8个值:0.75,0.5,0.25,0,─0.25,─0.5,─0.75和 ─1,因而量化位数越少,波形就越难辨认,还原后的声音质量也就越差(可能除了一片嗡嗡声之外什么都没有)

3.音频常见名词

采样频率:每秒钟采样的点的个数。

采样精度 (采样深度):每个"样本点"的大小,

常用的大小为8bit, 16bit,24bit。

通道数:单声道,双声道,四声道,5.1声道。

比特率 :每秒传输的bit数,单位为:bps(Bit Per Second)

间接衡量声音质量的一个标准。

没有压缩的音频数据的比特率 = 采样频率 * 采样精度 * 通道数。

码率 : 压缩后的音频数据的比特率。常见的码率:

96kbps: FM质量

128-160kbps:一般质量音频。

192kbps: CD质量。

256-320Kbps:高质量音频

码率越大,压缩效率越低,音质越好,压缩后数据越大。

码率 = 音频文件大小/时长。

例如:

采样频率44100,采样精度16bit,2通道(声道),采集4分钟的数据
大小:44100*16*2*4*60= ‭338688000‬bit
‭338688000‬/8/1024/1024 = 40M字节
比特率:采样频率 * 采样精度 * 通道数 = 44100*16*2= 1411200bit/s

:每次编码的采样单元数,比如MP3通常是1152个采样点作为一个编码单元,AAC通常是1024个采样点作为一个编码单元。

帧长 :可以指每帧播放持续的时间:每帧持续时间(秒) = 每帧采样点数 / 采样频率(HZ)

比如:MP3 48k, 1152个采样点,每帧则为 24毫秒

1152/48000= 0.024 秒 = 24毫秒;

也可以指压缩后每帧的数据长度。

交错模式 :数字音频信号存储的方式。数据以连续帧的方式存放,即首先记录帧1的左声道样本和右声道样本,再开始帧2的记录...

非交错模式 :首先记录的是一个周期内所有帧的左声道样本,再记录所有右声道样本

4.音频编码原理简介

数字音频信号如果不加压缩地直接进行传送,将会占用极大的带宽。例如,一套双声道数字音频若取样频率为44.1KHz,每样值按16bit量化,则其码率为:
2*44.1kHz*16bit=1.411Mbit/s

如此大的带宽将给信号的传输和处理都带来许多困难和成本(阿里云服务器带宽大于5M后,每M价格是100元/月),

因此必须采取音频压缩技术对音频数据进行处理,才能有效地传输音频数据。

数字音频压缩编码在保证信号在听觉方面不产生失真的前提下,对音频数据信号进行尽可能大的压缩,降低数据量。数字音频压缩编码采取去除声音信号中冗余成分的方法来实现。所谓冗余成分指的是音频中不能被人耳感知到的信号,它们对确定声音的音色,音调等信息没有任何的帮助。

冗余信号包含人耳听觉范围外的音频信号以及被掩蔽掉的音频信号等。例如,人耳所能察觉的声音信号的频率范围为20Hz~20KHz,除此之外的其它频率人耳无法察觉,都可视为冗余信号。

此外,根据人耳听觉的生理和心理声学现象,当一个强音信号与一个弱音信号同时存在时,弱音信号将被强音信号所掩蔽而听不见,这样弱音信号就可以视为冗余信号而不用传送。这就是人耳听觉的掩蔽效应,主要表现在频谱掩蔽效应和时域掩蔽效应。

  1. 音频编码-频谱掩蔽效应

    一个频率的声音能量小于某个阈值之后,人耳就会听不到。当有另外能量较大的声音出现的时候,该声音频率附近的阈值会提高很多,即所谓的掩蔽效应。如下图所示:

    由图中我们可以看出人耳对2KHz~5KHz的声音最敏感,而对频率太低或太高的声音信号都很迟钝,当有一个频率为0.2KHz、强度为60dB的声音出现时,其附近的阈值提高了很多。由图中我们可以看出在0.1KHz以下、1KHz以上的部分,由于离0.2KHz强信号较远,不受0.2KHz强信号影响,阈值不受影响;而在0.1KHz~1KHz范围,由于0.2KHz强音的出现,阈值有较大的提升,人耳在此范围所能感觉到的最小声音强度大幅提升。如果0.1KHz~1KHz范围内的声音信号的强度在被提升的阈值曲线之下,由于它被0.2KHz强音信号所掩蔽,那么此时我们人耳只能听到0.2KHz的强音信号而根本听不见其它弱信号,这些与0.2KHz强音信号同时存在的弱音信号就可视为冗余信号而不必传送。

  2. 音频编码-时域掩蔽效应

    当强音信号和弱音信号同时出现时,还存在时域掩蔽效应。即两者发生时间很接近的时候,也会发生掩蔽效应。时域掩蔽过程曲线如图所示,分为前掩蔽、同时掩蔽和后掩蔽三部分。

    时域掩蔽效应可以分成三种:前掩蔽,同时掩蔽,后掩蔽
    前掩蔽 是指人耳在听到强信号之前的短暂时间内,已经存在的弱信号会被掩蔽而听不到。
    同时掩蔽 是指当强信号与弱信号同时存在时,弱信号会被强信号所掩蔽而听不到。
    后掩蔽是指当强信号消失后,需经过较长的一段时间才能重新听见弱信号,称为后掩蔽。这些被掩蔽的弱信号即可视为冗余信号。

  3. 音频编码-压缩编码方法

    当前数字音频编码领域存在着不同的编码方案和实现方式, 但基本的编码思路大同小异, 如图所示。

    对每一个音频声道中的音频采样信号:

    1)将它们映射到频域中,这种时域到频域的映射可通过子带滤波器实现。每个声道中的音频采样块首先要根据心理声学模型来计算掩蔽门限值;

    2)由计算出的掩蔽门限值决定从公共比特池中分配给该声道的不同频率域中多少比特数,接着进行量化以及编码工作;

    3)将控制参数及辅助数据加入数据之中,产生编码后的数据流。

5.音视频同步

DTS(Decoding Time Stamp) :即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。
PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。

音视频同步方式:
Audio Master :同步视频到音频
Video Master :同步音频到视频
External Clock Master :同步音频和视频到外部时钟。

一般情况下 Audio Master > External Clock Master > Video Master

6.常用的音频编码

  • AAC,英文全称 Advanced Audio Coding,是由 Fraunhofer IIS、杜比实验室、AT&T、Sony等公司共同开发,在 1997 年推出的基于 MPEG-2 的音频编码技术。2000 年,MPEG-4 标准出现后,AAC 重新集成了其特性,加入了 SBR 技术和 PS 技术,为了区别于传统的 MPEG-2 AAC 又称为 MPEG-4 AAC。
  • MP3,英文全称 MPEG-1 or MPEG-2 Audio Layer III,是当曾经非常流行的一种数字音频编码和有损压缩格式,它被设计来大幅降低音频数据量。它是在 1991 年,由位于德国埃尔朗根的研究组织 Fraunhofer-Gesellschaft 的一组工程师发明和标准化的。MP3 的普及,曾对音乐产业造成极大的冲击与影响。
  • WMA,英文全称 Windows Media Audio,由微软公司开发的一种数字音频压缩格式,本身包括有损和无损压缩格式。

总结

相关推荐
攸攸太上10 分钟前
JMeter学习
java·后端·学习·jmeter·微服务
speop21 分钟前
【笔记】I/O总结王道强化视频笔记
笔记·音视频
Ljubim.te39 分钟前
Linux基于CentOS学习【进程状态】【进程优先级】【调度与切换】【进程挂起】【进程饥饿】
linux·学习·centos
yngsqq1 小时前
031集——文本文件按空格分行——C#学习笔记
笔记·学习·c#
zengy51 小时前
Effective C++中文版学习记录(三)
数据结构·c++·学习·stl
cyt涛2 小时前
MyBatis 学习总结
数据库·sql·学习·mysql·mybatis·jdbc·lombok
Willliam_william2 小时前
SystemC学习(1)— SystemC安装与HelloWorld
学习
sealaugh322 小时前
aws(学习笔记第一课) AWS CLI,创建ec2 server以及drawio进行aws画图
笔记·学习·aws
布丁不叮早起枣祈2 小时前
10.5学习
学习
向上的车轮2 小时前
Django学习笔记五:templates使用详解
笔记·学习·django