找回密码
 会员注册
查看: 41|回复: 0

MoviePy(Python音视频开发)

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-9-3 23:46:21 | 显示全部楼层 |阅读模式
音视频基础帧率、码率、分辨率视频格式H.264和H.265视频压缩算法Moviepy常见剪辑类VideoFlieClipImageFlieClipColorClipTextClipCompositeVideoClipAudioFlieClipCompositeAudioClip常见操作音视频的读入与导出截取音视频片段改变clip属性视频镜像翻转多视频拼接多视频叠加复合叠加视频添加字幕或水印复合叠加音频音视频基础帧率、码率、分辨率体积(Volume):一个视频的容量(文件大小),单位是B(byte)。码率影响体积,与体积成正比。如果码率为变量,则帧率也会影响体积,帧率越高,每秒钟经过的画面越多,需要的码率也越高,体积也越大。帧率(FPS):每秒钟要多少帧画面,就是在1秒钟时间里传输的图片的帧数。影响画面流畅度,与画面流畅度成正比。帧率越大,画面越流畅;帧率越小,画面越有跳动感。如我们看b站常见的1080P60帧,其中60帧就是帧率,表示每秒播放60张图片。码率(Bitrate):编码器每秒传输的数据大小(带宽),单位是kbps即千位每秒,比如800kbps代表编码器每秒产生800kb(或100KB)的数据。如b站要求up主上传的视频码率最高为6000kbps(H264/AVC编码)。分辨率(Resolution):单位英寸中所包含的横纵向像素点数(图像宽高);VGA:VideoGraphicsArray(视频图像分辨率)。影响图像大小,与图像大小成正比:分辨率越高,图像越大;分辨率越低,图像越小。在码率一定的情况下,分辨率与清晰度成反比关系:分辨率越高,图像越不清晰,分辨率越低,图像越清晰。如我们看b站常见的最大分辨率1080P,其中1080P就是分辨率,P表示(Progressivescanning,逐行扫描)。以我们常见的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,JointVideoTeam)提出的视频编解码器标准(视频压缩/编码算法)。这个标准通常被称之为H.264/AVC(或者AVC/H.264或者H.264/MPEG-4AVC或MPEG-4/H.264AVC),其中AVC(AdvancedVideoCoding,高级视频编码)。H.264主要包含:宏块细分图像、帧内压缩(intracompress)减少空间冗余、帧间预测(interprediction)减少时间冗余、转换(transform)和量化(quantization)进行残留数据压缩、去区块滤波器(deblockingfilter)、熵编码(entropycoding)等模块。H.265,通常被称为H.265/HEVC,两者都是基于块的视频编码技术,H.265的编码架构大致上和H.264的架构相似,但编码的文件大小会比H.264小50%,相同画质下更加节省带宽/流量。也主要包含:宏块细分图像、帧内压缩(intracompress)减少空间冗余、帧间预测(interprediction)减少时间冗余、转换(transform)和量化(quantization)进行残留数据压缩、去区块滤波器(deblockingfilter)、熵编码(entropycoding)等模块。但在HEVC编码架构中,整体被分为了三个基本单位,分別是:编码单位(codingunit,CU)、预测单位(predictunit,PU)和转换单位(transformunit,TU)。宏块划分:把图像划分成一个一个的小像素块(patch)。帧内压缩(intracompress):类似JPEG这种有损压缩,减少空间冗余。帧间预测(interprediction):根据关键帧和运动变化的信息,预测出中间帧,减少时间冗余。把帧分为: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)普通高清音视频传送。MoviepyMoviepy和python-ffmpeg和用subprocess调用ffmpeg有相同的效果,都可以实现:视频剪辑,视频拼接,插入、字幕水印,视频合成,自定义的高级的音视频特效等。此外,MoviePy可以读写绝大多数常见的视频格式,甚至包括GIF格式!MoviePy使用软件FFmpeg读取和导出视频和音频文件,使用ImageMagick生产文字和GIF图。中间的处理过程赖于Python强大的数学处理库,高级特效和软件加强用到了许多的Python图像处理库。FFmpeg的优点是速度快,缺点则是命令复杂。Moviepy开发起来更加简便,缺点就是相当于ffmpeg速度更慢一些,且不支持streamvideo流媒体(如直播/摄像头)!常见剪辑类Clip是所有剪辑类的基类,VideoClip和AudioClip继承自Clip,分别处理视频和音频数据。VideoClip和AudioClip又有很多派生类,用于处理不同的视频和音频内容。所有的类都可以从Moviepy.editor模块导入。Clip、VideoClip、AudioClip三个基类是非常少用的,我们接下来着重介绍他们的派生类。其中最核心的是VideoClip类的对象clips(视频片段),开发者可以对clips进行修改(剪切,调速度,调亮度…)或者和其他clip混合拼接到一起。vedioclip可以由视频文件,图像,文本或者动画来创建实例。vedioclip可以拥有一个音频轨道(audioclip)和一个叠加层的vedioclip(这是一个特殊的VedioClip,这意味着,当一个视频和其他VedioClip混合的时候,这个叠加层clip是隐藏的)VideoFlieClipImageFlieClipColorClipTextClipCompositeVideoClipAudioFlieClipCompositeAudioClip常见操作MoviePy-中文文档(一个专业的python音视频编辑库)教程音视频的读入与导出读入视频,导出视频:write_videofile#导入需要的库frommoviepy.editorimport*#从本地载入视频myHolidays.mp4,并截取00:00:50-00:00:60部分clip=VideoFileClip("Mojito.mp4").subclip(50,60)#调低音频音量(volumex0.8)clip=clip.volumex(0.8)#做一个txtclip.自定义样式,颜色.txt_clip=TextClip("MojitobyJay",fontsize=70,color='white')#文本clip在屏幕正中显示持续10秒txt_clip=txt_clip.set_pos('center').set_duration(10)#把textclip的内容覆盖videoclipvideo=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")123456789101112131415161718192021读入音频,导出音频:write_audiofile#导入需要的库frommoviepy.editorimport*#从本地载入视频myHolidays.mp4,并截取00:00:50-00:00:60部分clip=VideoFileClip("/data3/yzr/Mojito.mp4").subclip(3,10)#取clip的audio音频部分audio=clip.audio#保存为MP3audio.write_audiofile("Mojito.mp3")#保存为wavaudio.write_audiofile("Mojito.wav",codec="pcm_s32le")#保存为wmav1audio.write_audiofile("Mojito.wam",codec="wam1")1234567891011121314导出GIF动图:write_gif#导入需要的库frommoviepy.editorimport*#从本地载入视频myHolidays.mp4,并截取00:00:50-00:00:60部分clip=VideoFileClip("/data3/yzr/Mojito.mp4").subclip(3,10)#把最后生成的视频导出到文件内clip.write_gif("Mojito_edited.gif")12345678导出视频截图:save_frame#导入需要的库frommoviepy.editorimport*#从本地载入视频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)12345678910假如我们希望每个2s保存一张截图,我们应该如何实现呢:#导入需要的库frommoviepy.editorimport*#从本地载入视频myHolidays.mp4,并截取00:00:50-00:00:60部分clip=VideoFileClip("/data3/yzr/Mojito.mp4").subclip(3,10)image_dir="frames"ifnotos.path.exists(image_dir)s.mkdir(image_dir)interval=2duration=clip.durationtimes=list(range(0,int(duration),interval))fortintimes: clip.save_frame(os.path.join(image_dir,f"{t}.png"),t=t)1234567891011121314截取音视频片段使用subclip(t_start,t_end)截取videoclip的片段:#导入需要的库frommoviepy.editorimport*#从本地载入视频myHolidays.mp4clip=VideoFileClip("Mojito.mp4")#截取00:00:50-00:00:60部分clip=clip.subclip(50,60)#默认视频编解码器codec="libx264",声音解码器audio_codec="acc"clip.write_videofile("Mojito_edited.mp4",audio_codec="acc")12345678对于audio也是相同操作:#导入需要的库frommoviepy.editorimport*#从本地载入视频myHolidays.mp4clip=AudioFileClip("Mojito.mp3")#截取00:00:50-00:00:60部分clip=clip.subclip(50,60)clip.write_audiofile("Mojito_edited.mp4")1234567改变clip属性非常常见的修改clip属性的方法有:clip.subclip、clip.set_duration,clip.set_audio,clip.set_mask,clip.set_start等。例如,使用resize指定videoclip的分辨率放缩比例,使用volumex指定videoclip的音量:#导入需要的库frommoviepy.editorimport*#从本地载入视频myHolidays.mp4clip=VideoFileClip("Mojito.mp4").subclip(3,7)#使用resize指定放缩比例0.5,调低音频音量(volumex0.8)clip=clip.resize(0.5).volumex(0.8)#默认视频编解码器codec="libx264",声音解码器audio_codec="acc"clip.write_videofile("Mojito_edited.mp4",audio_codec="acc")12345678除了上述clip=clip.resize(0.5).volumex(0.8)方式来修改clip属性,我们还可以借助fx函数来统一修改音视频属性。而且应用clip.fx方法还可以实现一些高级效果,通过fx函数,分别使用vfx.resize、vfx.speedx、vfx.colorx参数调整视频的分辨率、速度、亮度。loop:让clip循环播放、timemirror:让clip倒播。这些方法位于特殊的模块moviepy.video.fx,moviepy.audio.fx,比如clip.fx(timemirror)让视频倒播。frommoviepy.editorimport*clip=(VideoFileClip("myvideo.avi").fx(vfx.resize,width=460)#尺寸变化,保持纵横比.fx(vfx.speedx,2)#2倍速.fx(vfx.colorx,0.5))#画面调暗12345为方便起见,当我们使用moviepy.editor的时候,比如我们使用resize的时候,我们经常会使用clip.resize(0.5)这样的简便的写法来代替clip.fx(vfx.resize,0.5)的写法。视频镜像翻转使用fx()函数传入vfx.mirror_x/y对videoclip进行水平或竖直翻转:frommoviepy.editorimportVideoFileClip,clips_array,vfxclip=clip1.fx(vfx.mirror_x)#x轴镜像clip.write_videofile("my_video.mp4")123多视频拼接视频拼接我们使用concatenate_videoclips函数,把视频一个接一个地拼接起来:frommoviepy.editorimportVideoFileClip,concatenate_videoclipsclip1=VideoFileClip("myvideo.mp4")clip2=VideoFileClip("myvideo2.mp4")clip3=VideoFileClip("myvideo3.mp4")finalclip=concatenate_videoclips([clip1,clip2,clip3])finalclip.write_videofile("my_concatenate.mp4")12345678会按照clip1,clip2,clip3的顺序将这三个clip播放。这些clip并不需要相同的时长或者大小,仅仅是首尾相连而已。我们还可以通过transition=my_clip这个参数来设置一下clip之间衔接的过渡动画。多视频叠加视频叠加我们使用clip_array函数,使用二维数组的形式,将多个视频叠加在一块,margin(10)指视频和视频之间的边框距离为10pixel,比如一个大的画面同时播几个视频:frommoviepy.editorimportVideoFileClip,clips_array,vfxclip1=VideoFileClip("myvideo.mp4").margin(10)clip2=clip1.fx(vfx.mirror_x)#x轴镜像clip3=clip1.fx(vfx.mirror_y)#y轴镜像clip4=clip1.resize(0.6)#尺寸等比缩放0.6final_clip=clips_array([[clip1,clip2],[clip3,clip3]])final_clip.resize(width=480).write_videofile("my_stack.mp4")123456789101112复合叠加视频CompositeVideoClip这个类提供来更加灵活的方式来排版视频,但是它可要比concatenate_videoclips和clips_array函数要复杂的多了。video=CompositeVideoClip([clip1,clip2,clip3])1现在,这3个clip是堆叠起来的,啥情况呢,就是,clip2压在clip1上,clip3压在最上面。大家可以想像成栈结构,从左往右,依次入栈这么堆叠在一块,对于一个普通的视频来说,这样堆叠实在是没办法看了。你想像一下,如果clip3的尺寸是最大的,比clip1和clip2都大,那我们只能看到clip3,clip1和clip2都被盖住了。最终要合成的clip的尺寸是默认第一个clip的尺寸,一般第一个也就是做背景用了,但是我们有时候是需要我们的clip浮在一个比较大的合成体的上方的,那这个时候我们就需要声明合成clip的尺寸。video=CompositeVideoClip([clip1,clip2,clip3],size=(720,480))1在堆叠视频中,每个clip会在通过start()函数声明的时间开始播放,我们可以像下面这样去设置。video=CompositeVideoClip([clip1,#在第0秒开始clip2.set_start(5),#在第5秒开始clip3.set_start(9)#第9秒开始])12345在下面的栗子里,可能clip2开始的时候,正好是clip1将要结束的时机,这样的情况,我们可以让clip2使用crossfadein(1)在一秒内“渐入”的特效来显示。video=CompositeVideoClip([clip1,clip2.set_start(5).crossfadein(1),clip3.set_start(9).crossfadein(1.5)])12345假如clip2和clip3都比clip1要小,那你可以通过设定位置决定clip2和clip3在画面中的位。下面的栗子就是通过set_pos((x,y))指定坐标的形式(距离左上方的像素距离),把clip2和clip3在画面中指定位置。video=CompositeVideoClip([clip1,clip2.set_start(5).crossfadein(1).set_pos((45,150)),clip3.set_start(9).crossfadein(1.5).set_pos((90,100))])12345在moviepy中我们有很多的方法定位clip的位置:clip2.set_pos((45,150))#像素坐标clip2.set_pos("center")#居中clip2.set_pos(("center","top"))#水平方向居中,但是处置方向放置在顶部clip2.set_pos(("left","center"))#水平方向放置在左边,垂直方向居中clip2.set_pos((0.4,0.7),relative=True)#0.4倍宽,0.7倍高处clip2.set_pos(lambdat'center',50+t))#水平居中,向下移动123456实现在右下角叠加一个小的窗口,现实另一个视频frommoviepy.editorasmpclip1=VideoFileClip("myvideo.mp4")clip2=VideoFileClip("myvideo.mp4").resize(0.2)video=CompositeVideoClip([clip1set_pos(("center")),clip2.set_pos(("right","bottom"))])123456789添加字幕或水印Moviepy加字需要依赖ImageMagick软件。使用TextClip创建文字类(可以用set_pos和set_duration设置字幕的位置和持续时间),使用CompositeVideoClip将其与视频叠加在一起:#导入需要的库frommoviepy.editorimport*#从本地载入视频myHolidays.mp4,并截取00:00:50-00:00:60部分clip=VideoFileClip("Mojito.mp4").subclip(50,60)#做一个txtclip.自定义样式,颜色.txt_clip=TextClip("MojitobyJay",fontsize=70,color='white',font=".苹方-简-常规体")#文本clip在屏幕正中显示持续10秒txt_clip=txt_clip.set_pos((50,50)).set_duration(10)#把textclip的内容覆盖videoclipvideo=CompositeVideoClip([clip,txt_clip])#把最后生成的视频导出到文件内video.write_videofile("Mojito_edited.mp4")#默认编解码器codec="libx264"123456789101112131415使用ImageClip创建图片类(可以用set_pos和set_duration设置logo图片的位置和持续时间),使用CompositeVideoClip将其与视频叠加在一起:#导入需要的库frommoviepy.editorimport*#从本地载入视频myHolidays.mp4,并截取00:00:50-00:00:60部分clip=VideoFileClip("Mojito.mp4").subclip(50,60)logo=ImageClip("logo.png").resize(width=100,height=100).set_pos((50,50))..set_duration(10)video=CompositeVideoClip([clip,logo])#把最后生成的视频导出到文件内video.write_videofile("Mojito_edited.mp4")#默认编解码器codec="libx264"123456789101112复合叠加音频如果你有一些特殊的的定制合成音频的需求,应该使用CompositeAudioClip和concatenate_audioclips这俩类。frommoviepy.editorimports*concat=concatenate_audioclips([clip1,clip2,clip3])compo=CompositeAudioClip([aclip1.volumex(1.2),aclip2.set_start(5),#startatt=5saclip3.set_start(9)])12345678
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-13 06:04 , Processed in 0.508971 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表