python实现视频抽帧与添加背景音频和字幕朗读的脚本分享

 更新时间:2023年11月03日 09:38:15   作者:玛卡`三少  
这篇文章主要为大家详细介绍了如何使用python实现视频抽帧、添加srt字幕朗读、添加背景音频等功能,感兴趣的小伙伴可以跟随小编一起学习一下

1.介绍

看完本文章,你将能学会一下内容:

  • 批量视频抽帧;
  • 添加srt字幕;
  • 添加srt配音;
  • 添加背景音乐;
  • 多视频片段合成一个新视频;

效果:

2.安装依赖

首先安装视频处理库opencv-python和moviepy,安装方式pip install xxx。

py文件顶部中导入(下文中使用到的函数将不在赘述导入过程):

from moviepy.editor import VideoFileClip, CompositeAudioClip, CompositeVideoClip, concatenate_videoclips
from cv2 import VideoCapture, VideoWriter, VideoWriter_fourcc, CAP_PROP_FRAME_COUNT

3.视频抽帧

cv2.VideoCapture:

作用:用于从视频文件或摄像头捕获视频帧。

解释:这个函数允许你创建一个视频捕获对象,以便从指定的视频源中读取视频帧。你可以传递视频文件的路径或摄像头的索引作为参数,然后使用它来逐帧读取视频。

cv2.VideoWriter:

作用:用于将视频帧写入到一个新的视频文件中。

解释:这个函数允许你创建一个视频写入对象,以便将视频帧写入到一个新的视频文件中。你可以指定输出文件的名称、视频编解码器、帧速率、分辨率等参数。这在视频编辑和保存处理后的视频时非常有用。

cv2.VideoWriter_fourcc:

作用:用于指定视频编解码器的四字符码(FourCC)。

解释:FourCC 是一个4字节的代码,用于标识视频编解码器。不同的编解码器有不同的FourCC码。通过使用这个函数,你可以选择要在输出视频中使用的编解码器。

CAP_PROP_FRAME_COUNT:

作用:用于获取视频文件中的总帧数。

解释:CAP_PROP_FRAME_COUNT 是 cv2.VideoCapture 对象的一个属性,用于获取视频文件中的总帧数。这对于确定视频的时长以及循环播放视频等操作非常有用。

完整代码块:

# 单个视频抽帧
def video_extract_frame(video_path, out_path):
  # 打开视频文件
  vc = VideoCapture(video_path)
  # 视频的总帧数
  total_frame = int(vc.get(CAP_PROP_FRAME_COUNT))
  video = VideoFileClip(video_path, audio=False)
  # # 创建一个视频写入对象。设置视频的宽度和高度、帧率、输出路径
  fourcc = VideoWriter_fourcc(*'mp4v')
  videoWriter = VideoWriter(out_path, fourcc, VIDEO_FPS, (video.w, video.h))
  if vc.isOpened():
      status, frame = vc.read()
  else:
      status = False
      print("视频没有打开成功!")
      vc.release()
      video.close()
      videoWriter.release()
      return False
  if status:
      for index in trange(total_frame, desc='抽帧进度'):
          # 读取视频帧并写入输出视频
          status, frame = vc.read()
          if index % VIDEO_FPS == 0:
              skip_frames = tool.get_unique_random_numbers(index, VIDEO_FPS)
          if index in skip_frames:
              continue
          videoWriter.write(frame)
  videoWriter.release()
  vc.release()
  video.close()

调用上面的抽帧函数:

video_extract_frame('./test.mp4', 'result.mp4')

如果有多个视频需要抽帧,只需要循环调用即可:

 for index, video_file in enumerate(['1.mp4', '2.mp4', '3.mp4']):
    //取出链接中的视频文件名称,例如1,2,3
    video_name = tool.get_file_name(video_file)
    //组装成新目录、新名字(根据自己需要)
    out_path = "{}{}.mp4".format(frame_path, video_name)
    videoTool.video_extract_frame(video_file, out_path)
    print("\n第{}条, 视频抽帧已完成: {}".format(index + 1, out_path))

4.添加srt字幕

完整示例代码:

# 字幕片段
def generate_textclip(text, width, params, start, duration) -> TextClip:
    return TextClip(
        text,
        font=params.get('font'),
        align=params.get('align'),
        fontsize=params.get('fontsize'),
        color=params.get('color', '#ffbd00'),
        size=(width, params.get('height')),
        stroke_color=params.get('stroke_color'),
        stroke_width=params.get('stroke_width')
    ).set_position((params['location']['x'], params['location']['y'])).set_duration(duration).set_start(start)
# 添加srt字幕
def add_srt(video_clip, params):
  if not (isfile(params["srt_path"]) and params["srt_path"].endswith('.srt')):
      print('字幕仅支持srt格式!')
      return []
  else:
      # 获取视频的宽度和高度
      v_width, v_height = video_clip.w, video_clip.h
      # 所有字幕剪辑
      txts = []
      content = tool.read_srt(params["srt_path"])
      sequences = tool.get_sequences(content)
      max_count = len(sequences)
      max_duration = video_clip.duration
      srt_text = params["srt_text"]
      for index, line in enumerate(sequences):
          print("字幕生成进度:{}/{}".format(index, max_count))
          if len(line) < 3:
              continue
          start = line[1].split(' --> ')[0]
          end = line[1].split(' --> ')[1]
          start = tool.str_float_time(start)
          end = tool.str_float_time(end)
          start, end = map(float, (start, end))
          if start >= max_duration:
              break
          if end >= max_duration:
              end = max_duration
          duration = end - start
          txt_srt = generate_textclip(line[2], (v_width - 20), srt_text, start, duration)
          txts.append(txt_srt)
      print("\n字幕转换已完成...")
      return txts

tool.read_srt 代码:

def read_srt(self, path):
    content = ""
    with open(path, 'r', encoding='UTF-8') as f:
        content = f.read()
        return content

tool.get_sequences 代码:

# 字幕拆分
def get_sequences(self, content):
    sequences = content.split('\n\n')
    sequences = [sequence.split('\n') for sequence in sequences]
    # 去除每一句空值
    sequences = [list(filter(None, sequence)) for sequence in sequences]
    # 去除整体空值
    return list(filter(None, sequences))

tool.str_float_time 代码:

# 字符串数字格式化成时间
def str_float_time(self, str):
    str_list = str.split(':')
    hour = int(str_list[0])
    minute = int(str_list[1])
    second = int(str_list[2].split(',')[0])
    minsecond = int(str_list[2].split(',')[1])
    allTime = hour * 60 * 60 + minute * 60 + second + minsecond / 1000
    return allTime

5.添加背景音乐、srt音频、导出

# frame_video_paths:是抽帧后的视频片段
def merge_videos_with_bgm(params, frame_video_paths, out_path):
    # 用VideoFileClip加载所有输入视频文件
    video_clips = [VideoFileClip(file) for file in frame_video_paths]
    final_clip = concatenate_videoclips(video_clips)
    bgm_music = audioTool.get_audio({
        "volume": params.get("bgm_volume", 0.1), #背景音频小声点
        "duration": final_clip.duration,
        "audio_path": params['bgm_path']
    })
    # 加载主音乐(朗读音频)
    main_music = audioTool.get_audio({
        "volume": params.get("audio_volume", 1.0),# 朗读音频大声点
        "duration": final_clip.duration,
        "audio_path": params['audio_path']
    })
    # 将音乐混合到最终视频切片
    final_clip = final_clip.set_audio(CompositeAudioClip([main_music, bgm_music]))
    video_srt = videoTextTool.add_srt(final_clip, params)
    final_clip.extend(video_srt)
    # 复合视频
    video = CompositeVideoClip(final_clip)
    output_path = path.join(out_path, "result.mp4")
    # 输出最终视频
    video.write_videofile(output_path)

到此这篇关于python实现视频抽帧与添加背景音频和字幕朗读的脚本分享的文章就介绍到这了,更多相关python视频抽帧内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python实现五子棋小游戏

    python实现五子棋小游戏

    这篇文章主要介绍了python实现五子棋小游戏,使用pygame模块编写一个五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • Python绘制箭头向量图的示例代码

    Python绘制箭头向量图的示例代码

    箭头向量图十分常见,比如天气预报在显示风场的时候,就会贴心地用箭头指明风的方向,下面就跟随小编一起学习一下如何利用Python绘制箭头向量图吧
    2023-08-08
  • 在Python中使用代理IP的方法详解

    在Python中使用代理IP的方法详解

    在网络爬虫开发中,使用代理IP是非常常见的技巧,Python作为一门强大的编程语言,也提供了很多方法来使用代理IP,下面,我将就如何在Python中使用代理IP进行详细的阐述,并举例说明,需要的朋友可以参考下
    2023-07-07
  • 深入了解和应用Python 装饰器 @decorator

    深入了解和应用Python 装饰器 @decorator

    在编程过程中,经常遇到这样的场景:登录校验,权限校验,日志记录等,这些功能代码在各个环节都可能需要,但又十分雷同,通过装饰器来抽象、剥离这部分代码可以很好解决这类场景,这篇文章主要介绍了Python的装饰器 @decorator,探讨了使用的方式,需要的朋友可以参考下
    2019-04-04
  • 详谈python中subprocess shell=False与shell=True的区别

    详谈python中subprocess shell=False与shell=True的区别

    这篇文章主要介绍了详谈python中subprocess shell=False与shell=True的区别说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • python实现局域网内实时通信代码

    python实现局域网内实时通信代码

    今天小编就为大家分享一篇python实现局域网内实时通信代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • python自动化测试之连接几组测试包实例

    python自动化测试之连接几组测试包实例

    这篇文章主要介绍了python自动化测试之连接几组测试包实例,需要的朋友可以参考下
    2014-09-09
  • python网络爬虫基本语法详解

    python网络爬虫基本语法详解

    掌握Python网络爬虫基本语法,就是打开数据世界的钥匙,在这份指南中,我们将带你深入浅出,从零开始一步步变成抓取信息的高手,准备好探索无限可能的网络数据世界了吗?让我们一起开启这段精彩旅程吧!
    2024-03-03
  • Python NumPy教程之数组的基本操作详解

    Python NumPy教程之数组的基本操作详解

    Numpy 中的数组是一个元素表(通常是数字),所有元素类型相同,由正整数元组索引。本文将通过一些示例详细讲一下NumPy中数组的一些基本操作,需要的可以参考一下
    2022-08-08
  • 用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动

    用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动

    这篇文章主要介绍了用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动,需要的朋友可以参考下
    2015-11-11

最新评论