- 音视频基础
- 帧率、码率、分辨率
- 视频格式
- H.264和H.265视频压缩算法
- Moviepy
- 常见剪辑类
- VideoFlieClip
- ImageFlieClip
- ColorClip
- TextClip
- CompositeVideoClip
- AudioFlieClip
- CompositeAudioClip
- 常见操作
- 音视频的读入与导出
- 截取音视频
音视频基础
帧率、码率、分辨率
-
体积(Volume):一个视频的容量(文件大小),单位是B(byte)。码率影响体积,与体积成正比。如果码率为变量,则帧率也会影响体积,帧率越高,每秒钟经过的画面越多,需要的码率也越高,体积也越大。
-
帧率(FPS):每秒钟要多少帧画面,就是在1秒钟时间里传输的图片的帧数。影响画面流畅度,与画面流畅度成正比。帧率越大,画面越流畅;帧率越小,画面越有跳动感。如我们看b站常见的
1080P 60帧
,其中60帧就是帧率,表示每秒播放60张图片。 -
码率(Bitrate):编码器每秒传输的数据大小(带宽),单位是kbps 即千位每秒,比如800kbps代表编码器每秒产生800kb(或100KB)的数据。如b站要求up主上传的视频码率最高为6000kbps(H264/AVC编码)。
-
分辨率(Resolution):单位英寸中所包含的横纵向像素点数(图像宽高); VGA:Video Graphics Array(视频图像分辨率)。影响图像大小,与图像大小成正比:分辨率越高,图像越大;分辨率越低,图像越小。在码率一定的情况下,分辨率与清晰度成反比关系:分辨率越高,图像越不清晰,分辨率越低,图像越清晰。如我们看b站常见的最大分辨率
1080P
,其中1080P就是分辨率,P表示(Progressive scanning,逐行扫描)。以我们常见的16:9的屏幕举例(注意,一定要强调屏幕的宽高比例),1080表示1920 * 1080
个像素(其实我们可以说,1080P每一行有接近1K的像素点),2K则是2560 * 1440
,4K则是3840 * 2160
。
好的画质是分辨率、帧率和码率三者之间的平衡:
码率不是越大越好,如果不做码率大小上的限制,那么分辨率越高,画质越细腻;帧率越高,视频也越流畅,但相应的码率也会很大,因为每秒钟需要用更多的数据来承载较高的清晰度和流畅度。
如果限定一个码率,比如800kbps,那么帧率越高,编码器就必须加大对单帧画面的压缩比,也就是通过降低画质来承载足够多的帧数。
视频格式
一个音视频文件实际上分为3层:基础数据,编码,封装。
编码
使用不同的编码格式
,对视频数据进行压缩;封装
使用不同的封装格式
,将视频数据封装成不同的文件。
-
封装格式:封装格式只是视频的一层皮,只是对 文件信息 和 压缩好的音视频数据,按照一定的规则进行编排,不限制视频数据的帧率、分辨率、码率等参数,因此封装格式不会影响视频的清晰度。如MP4(兼容性强)、FLV(在线播放nb)、HLS(长视频nb)、AVI、MKV(支持外接字幕)、PCM、ACC、MOV等。
-
编码格式:编码格式才是音视频流编码的内在组织形式,对原始的音视频数据进行压缩。如H.264、H.265等。
H.264和H.265视频压缩算法
H.264,同时也是MPEG-4的第十部分,被称作,是由联合视频组(JVT,Joint Video Team)提出的视频编解码器标准(视频压缩/编码算法)。这个标准通常被称之为H.264/AVC
(或者AVC/H.264
或者H.264/MPEG-4AVC
或MPEG-4/H.264 AVC
),其中AVC(Advanced Video Coding,高级视频编码)。H.264主要包含:宏块细分图像、帧内压缩(intra compress)减少空间冗余、帧间预测(inter prediction)减少时间冗余、转换(transform) 和 量化(quantization)进行残留数据压缩、去区块滤波器(deblocking filter)、熵编码(entropy coding) 等模块。
H.265,通常被称为 H.265/HEVC
,两者都是基于块的视频编码技术,H.265的编码架构大致上和H.264的架构相似,但编码的文件大小会比H.264小50%,相同画质下更加节省带宽/流量。也主要包含:宏块细分图像、帧内压缩(intra compress)减少空间冗余、帧间预测(inter prediction)减少时间冗余、转换(transform) 和 量化(quantization)进行残留数据压缩、去区块滤波器(deblocking filter)、熵编码(entropy coding) 等模块。但在HEVC编码架构中,整体被分为了三个基本单位,分別是:编码单位(coding unit,CU)
、预测单位(predict unit,PU)
和转换单位(transform unit,TU)
。
-
宏块划分:把图像划分成一个一个的小像素块(patch)。
-
帧内压缩(intra compress):类似JPEG这种有损压缩,减少空间冗余。
-
帧间预测(inter prediction):根据关键帧和运动变化的信息,预测出中间帧,减少时间冗余。把帧分为:I帧(关键帧)、P帧(根据前一个I或P帧预测出来的帧)、B帧(根据前后两个I或P帧预测出来的帧)。
I帧(关键帧)预测 P帧(下一帧):对于没有变化的宏块,P帧直接复制I帧。对于变化的宏块,编码的时候,记录变化的信息
,解码的时候,再预测回去。
B帧(双向预测帧):利用前后两帧来预测出的帧。
GPO的概念:I帧的间隔长度。录播视频GOP一般为帧率的4-5倍,直播视频GOP一般为帧率的1-2倍。如果太大,I帧间隔太远,会产生花屏问题,P帧和B帧预测不到位。
-
H264的编解码性能要求更低,更加普及;如H264由于算法优化,可以低于1Mbps的速度(码率)实现标清数字图像传送;
-
H265的压缩率更,因此带宽和容量的要求更低,但对编解码性能要求更高。如H265则可以实现利用1~2Mbps的传输速度(码率)传送720P(分辨率1280*720)普通高清音视频传送。
Moviepy
Moviepy 和 python-ffmpeg 和 用subprocess调用ffmpeg 有相同的效果,都可以实现:视频剪辑,视频拼接,插入标题、字幕水印,视频合成,自定义的高级的音视频特效等。此外,MoviePy 可以读写绝大多数常见的视频格式,甚至包括 GIF 格式!
MoviePy 使用软件 FFmpeg 读取和导出视频和音频文件,使用 ImageMagick 生产文字和 GIF 图。中间的处理过程赖于 Python 强大的数学处理库,高级特效和软件加强用到了许多的 Python 图像处理库。
- FFmpeg的优点是速度快,缺点则是命令复杂。
- Moviepy开发起来更加简便,缺点就是相当于ffmpeg速度更慢一些,且不支持stream video流媒体(如直播/摄像头)!
常见剪辑类
Clip
是所有剪辑类的基类,VideoClip
和AudioClip
继承自Clip,分别处理视频和音频数据。VideoClip
和AudioClip
又有很多派生类,用于处理 不同的视频和音频内容。所有的类都可以从Moviepy.editor
模块导入。Clip、VideoClip、AudioClip三个基类是非常少用的,我们接下来着重介绍他们的派生类。
其中最核心的是VideoClip类的对象 clips(视频片段)
,开发者可以对 clips 进行修改(剪切,调速度,调亮度…)或者和其他 clip 混合拼接到一起。vedio clip 可以由视频文件,图像,文本或者动画来创建实例。vedio clip 可以拥有一个音频轨道(audio clip) 和一个叠加层的 vedio clip(这是一个特殊的 VedioClip,这意味着,当一个视频和其他 VedioClip 混合的时候,这个叠加层 clip 是隐藏的)
VideoFlieClip
ImageFlieClip
ColorClip
TextClip
CompositeVideoClip
AudioFlieClip
CompositeAudioClip
常见操作
https://www.bilibili.com/video/BV1Qp421d7yz/?spm_id_from=333.788&vd_source=b2549fdee562c700f2b1f3f49065201b
https://xie.infoq.cn/article/23e694841b8526b2ba9d5fb7c
音视频的读入与导出
读入视频,导出视频:write_videofile
# 导入需要的库
from moviepy.editor import *
# 从本地载入视频myHolidays.mp4,并截取00:00:50 - 00:00:60部分
clip = VideoFileClip("Mojito.mp4").subclip(50,60)
# 调低音频音量 (volume x 0.8)
clip = clip.volumex(0.8)
# 做一个txt clip. 自定义样式,颜色.
txt_clip = TextClip("Mojito by Jay",fontsize=70,color='white')
# 文本clip在屏幕正中显示持续10秒
txt_clip = txt_clip.set_pos('center').set_duration(10)
# 把 text clip 的内容覆盖 video clip
video = CompositeVideoClip([clip, txt_clip])
# 把最后生成的视频导出到文件内
video.write_videofile("Mojito_edited.mp4") # 默认编解码器codec="libx264"
video.write_videofile("Mojito_edited.mp4", codec="mpeg4") # MP4也可以指定编解码器为"mpeg4"
video.write_videofile("Mojito_edited.avi", codec="rawvideo")
video.write_videofile("Mojito_edited.webm") # 默认编解码器codec="libx264"
video.write_videofile("Mojito_edited.flv", codec="flv")
读入音频,导出音频:write_audiofile
# 导入需要的库
from moviepy.editor import *
# 从本地载入视频myHolidays.mp4,并截取00:00:50 - 00:00:60部分
clip = VideoFileClip("/data3/yzr/Mojito.mp4").subclip(3,10)
# 取clip的audio音频部分
audio = clip.audio
# 保存为MP3
audio.write_audiofile("Mojito.mp3")
# 保存为wav
audio.write_audiofile("Mojito.wav", codec="pcm_s32le")
# 保存为wmav1
audio.write_audiofile("Mojito.wam", codec="wam1")
导出GIF动图:write_gif
# 导入需要的库
from moviepy.editor import *
# 从本地载入视频myHolidays.mp4,并截取00:00:50 - 00:00:60部分
clip = VideoFileClip("/data3/yzr/Mojito.mp4").subclip(3,10)
# 把最后生成的视频导出到文件内
clip.write_gif("Mojito_edited.gif")
导出视频截图:save_frame
# 导入需要的库
from moviepy.editor import *
# 从本地载入视频myHolidays.mp4,并截取00:00:50 - 00:00:60部分
clip = VideoFileClip("/data3/yzr/Mojito.mp4").subclip(3,10)
# 保存clip起始帧
clip.save_frame("frame.png")
# 保存视频第10秒截图
clip.save_frame("frame.png", t=10)