小言_互联网的博客

为了帮助剪辑小姐姐少熬夜,我用 Python 硬肝了一次短视频音频创作

483人阅读  评论(0)

点击上方“AirPython”,选择“加为星标”

第一时间关注 Python 原创干货!

1. 前言

最近一个小姐姐在后台给我留言,说自己的工作是短视频剪辑,经常需要熬夜剪片子,其中,音频处理费时费力,问我能不能利用自动化减轻她的工作

前面很多文章都使用了一款非常强大的依赖库,即:moviepy,它能非常快捷地完成视频剪辑

装逼篇 | 抖音超火的九宫格视频是如何生成的,Python 告诉你答案

短视频篇 | Python  带你进行短视频二次创作

视频剪辑什么鬼?Python 带你高效创作短视频

10万+的短视频被批量生产了,Python表示不服

本篇文章推荐另外一个超级强大的音频处理库:pydub

2. 介绍

pydub 是一款简单、方便且强大的 Python 音频处理库

项目地址:

https://github.com/jiaaro/pydub

日常音频剪辑处理工具,都可以使用它来完成,比如:提取音频、音频切断、音效处理、响度控制、声道配置、音频合成等

首先,安装依赖包


   
  1. # 安装依赖
  2. pip3 install pydub

3. 常见操作

接下来,我们来聊聊 pydub 常见的操作

3-1  AudioSegment 对象

pudub 最重要的一个类是:AudioSegment

它是一个不可变的对象,代表一个音频段对象

首先,我们实例化一个 AudioSegment 对象,它内置有多种实现方式

比如,我们从本地加载一个 wav 的音频文件


   
  1. from pydub  import AudioSegment
  2. # 音频路径
  3. audio_path =  "./raw/1.wav"
  4. # 指定音频格式,这里以wav音频为例
  5. format= 'wav'
  6. # 实例化一个AudioSegment对象
  7. audio_segment = AudioSegment.from_file(audio_path, format)

3-2  裁剪某段音频

针对 AudioSegment 对象,使用中括号指定开始时间和结束时间,即可以快速提取某一段音频

PS:时间以毫秒为单位


   
  1. # 某一段音频文件
  2. # 指定开始时间、结束时间
  3. # 时间以毫秒为单位
  4. audio_part = audio_segment[start_time:end_time]

3-3  合并音频

使用 pydub 合并多段音频非常便捷,只需要使用符号 +,将三段音频的 AudioSegment 对象加起来即可


   
  1. def sound_compound(one_audio_segment, *other):
  2.      "" "
  3.     合并两段音频
  4.     :param one_audio_segment:
  5.     :param other_audio_segment:
  6.     :return:
  7.     " ""
  8.     result = one_audio_segment
  9.     # 使用符号+,一段一段合并
  10.      for segment in other:
  11.         result += segment
  12.      return result
  13. # 合并 3段音频
  14. audio_segment1 = AudioSegment.from_file( './1.wav''wav')
  15. audio_segment2 = AudioSegment.from_file( './2.wav''wav')
  16. audio_segment3 = AudioSegment.from_file( './3.wav''wav')
  17. # 合并 3段音频文件
  18. audio_segment_result = sound_compound(audio_segment1, audio_segment2, audio_segment3)

3-4  音频常见属性

音频比较常见的属性包含:

  • 时长

  • 响度

  • 声道数

  • 帧速率

  • 原始数据

对于音频的时长,有 2 种获取方式,即:


   
  1. # 音频常见属性
  2. # 实例化AudioSegment对象
  3. as = AudioSegment.from_file( "sound1.wav")
  4. # duration_seconds:在内部调用了 len() ,单位为秒
  5. # 方式一,duration_seconds,以秒为单位
  6. as_duration1 = as.duration_seconds
  7. # 方式二: len(as),以毫秒为单位
  8. as_duration2 = ( len(as) /  1000.0)

其他原始数据都可以从 AudioSegment 对象相应的属性中获取 :


   
  1. # 音频常见属性
  2. # 实例化AudioSegment对象
  3. as = AudioSegment.from_file( "sound1.wav")
  4. 2、音频响度
  5. as_loudness = as.dBFS
  6. 3、声道数
  7. as_channel_num = as.channels
  8. 4、帧速率
  9. # 一般值为  44100 (CD),  48000 (DVD),  220502400012000 和  11025
  10. as_frame_rate = sound.frame_rate
  11. 5、音频的原始数据
  12. as_raw_data = sound.raw_data

3-5  单条音频淡入淡出

视频剪辑中,经常需要对音频做淡入淡出处理,使音效播放更加自然

比如:针对单个音频,在开头使用淡入,结束使用淡出,并指定淡入和淡出的时间

PS:单位以毫秒为单位


   
  1. def sound_fade_in_and_out(one_audio_segment, fade_in= 0, fade_out= 0):
  2.      "" "
  3.     单段音频设置开头淡入、结尾淡出
  4.     可以把许多运算符连成一串使用,因为运算符都会返回一个AudioSegment对象
  5.     :param one_audio_segment:
  6.     :param fade_in:淡入时间(毫秒)
  7.     :param fade_out:淡出时间(毫秒)
  8.     :return:
  9.     " ""
  10.      return one_audio_segment.fade_in(fade_in).fade_out(fade_out)
  11. audio_segment = AudioSegment.from_file( "./raw/1.wav", format= 'wav')
  12. # 单条视频开头淡入,结束淡出
  13. sound_fade_in_and_out(audio_segment, 2000, 2000)

需要指出的是,AudioSegment 对象内置的 fade() 函数,可以更加灵活地实现淡入淡出效果


   
  1. sound = AudioSegment.from_file( "./sound.wav")
  2. # fade实现淡入/淡出效果
  3. 1、从 1s开始,持续 2s,执行淡化效果,并从 0dB逐渐增加到 3dB
  4. sound_fade1 = sound.fade(to_gain=+ 3.0, start= 1000, duration= 2000)
  5. 2、从 1s开始,一直到 4s,中间 1s的时间内执行淡化效果,从 0db逐渐降低 -2dB
  6. sound_fade2 = sound1.fade(to_gain= -2, start= 1000, end= 4000)

3-6  调整音频播放速度

视频剪辑中,音频速度的调整很常见

比如:在视频结尾,调整最后的画面帧为慢动作,同样需要同步调慢音频的播放速度


   
  1. def speed_change(sound, speed= 1.0):
  2.      "" "
  3.     改变音频的速度
  4.     :param sound:
  5.     :param speed:
  6.     :return:
  7.     " ""
  8.     sound_with_altered_frame_rate = sound._spawn(sound.raw_data, overrides={
  9.          "frame_rate"int(sound.frame_rate * speed)
  10.     })
  11.      return sound_with_altered_frame_rate.set_frame_rate(sound.frame_rate)
  12. # 改变音频的播放速度
  13. # 比如: 0.8调整为之前速度的 0.8
  14. audio_new = speed_change(self.audio_segment,  0.8)

3-7  播放音频

AudioSegment 对象使用 pydub 内置的 play() 方法,可以播放音频,在调试代码的时候非常方便

   
  1. from pydub.playback  import play
  2. sound1 = AudioSegment.from_file( "./1.wav")
  3. # 播放音频
  4. play(sound1)
3-8  音量增益及降低
要调整一段音频的音量,可以直接对 AudioSegment 实例加、减对应的分贝数目即可

   
  1. def sound_gain(audio_segment, db_value):
  2.      "" "
  3.     声音增益
  4.     :param audio_segment:
  5.     :param db_value 分贝
  6.     :return:
  7.     " ""
  8.      return audio_segment + db_value
  9. def sound_reduce(audio_segment, db_value):
  10.      "" "
  11.     降低音量
  12.     :param audio_segment:
  13.     :param db_value 分贝
  14.     :return:
  15.     " ""
  16.      return audio_segment - db_value
  17. # 降低音量, -10分贝
  18. audio_segment_temp = sound_reduce(audio_segment,  10)
  19. # 增加音量,+ 10分贝
  20. audio_segment_temp1 = sound_gain(audio_segment,  10)

3-9  交叉淡化效果

使用 append() 方法,可以将多段音频对象进行合并,并添加交叉淡化的效果
PS:使用 crossfade 参数指定交叉淡化的持续时间,单位为毫秒

   
  1. def sound_overlap_effect(one_audio_segment, other_audio_segment, overlap_during):
  2.      "" "
  3.     两段音频合并的同时,使用交叉淡化的效果
  4.     :param one_audio_segment:第一段
  5.     :param other_audio_segment:第二段
  6.     :param overlap_during:单位毫秒
  7.     :return:
  8.     " ""
  9.      return one_audio_segment. append(other_audio_segment, crossfade=overlap_during)
  10. # 两段音频
  11. audio_segment1 = AudioSegment.from_file( './1.wav''wav')
  12. audio_segment2 = AudioSegment.from_file( './2.wav''wav')
  13. # 合并两段音频,并添加效果
  14. # 持续时间: 2000毫秒
  15. result = sound_overlap_effect(audio_segment1, audio_segment2,  2000)

3-10  多声道音频

利用 from_mono_audiosegments() 函数,可以一个轨道上创建多声道音频


   
  1. def create_multichannel_as(self):
  2.      "" "
  3.     创建多声道音频(支持2个或者多个)
  4.     :return:
  5.     " ""
  6.     # PS:每个单声道音频段都应该有相同的时长以及帧速率
  7.     one_as = AudioSegment.from_wav( "./1.wav")
  8.     other_as = AudioSegment.from_wav( "./2.wav")
  9.     # 合成多声道音频
  10.      return AudioSegment.from_mono_audiosegments(one_as, other_as)

3-11  提取音频及导出音频

在 3-1 中实例化 AudioSegment 方式,方法同样适用于视频,即:我们可以从视频中提取 AudioSegment 音频对象

使用 AudioSegment 对象的 export(filename,format) 方法,就可以将音频保存到本地了


   
  1. 1、从视频中提取一个AudioSegment音频对象
  2. audio_segment = AudioSegment.from_file(video)
  3. def save_audio(audio_segment, filename, format):
  4.      "" "
  5.     保存音频文件到本地
  6.     :param audio_segment:
  7.     :param filename:
  8.     :param format:
  9.     :return:
  10.     " ""
  11.     audio_segment.export(filename, format=format)
  12. 2、导出音频到本地
  13. save_audio(result,  './result.wav''wav')

4. 实战一下

对搞笑类短视频,经常会采用这种剪辑手法,即:将视频尾部,对最后一段对话降低速度并重新播放一次

准备一段视频素材,下面通过 pydub 来实现它


   
  1. video_path =  './raw.mp4'
  2. # 注意:加载视频不需要指定format
  3. audio_sgement = AudioSegment.from_file(video_path)
  4. # 截取尾部内容
  5. audio_end = audio_sgement[ 70 *  1000: 70 *  1000 +  3000]
  6. # 变慢速度,具体根据视频速度去调整
  7. audio_end2 = speed_change(audio_end,  0.55)
  8. # 合并两段音频
  9. audio_result = audio_end + audio_end2
  10. # 尾部淡出处理
  11. audio_result.fade_out( 1000)
  12. # 视频导出
  13. audio_result.export( "result.wav", format= 'wav')

最后生成的音频内容如下:

5. 最后

文中仅仅对 pydub 常用的操作进行了讲解,更多骚操作可以阅读官方文档去解锁

音视频的一些常见操作都可以做成自动化,让自己从重复的剪辑工作中抽离出来

我已经将文中完整源码文件传到后台,关注公众号,后台回复「 210106 」即可获得

如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!

留言送书

本周赠书:《Python 图解机器学习

内容简介:本书覆盖了机器学习领域的监督学习、半监督学习、无监督学习、增强学习和机器学习新算法等内容,构成了机器学习从经典到现代的体系框架,每章也可独立阅读。限于篇幅,书中没有讲解 Python 语言的基础知识,如果读者没有 Python 语言的基础,建议先学习 Python 语言入门知识,这样可以更好地学习本书内容

PS:中奖名单将在交流群公布,可以扫描下方二维码,备注【交流群】,加入技术交流群!


转载:https://blog.csdn.net/hsh881025/article/details/112300929
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场