【问题标题】:Adding subtitles to video with python使用python为视频添加字幕
【发布时间】:2021-07-04 15:30:13
【问题描述】:

我有一段人们谈话的视频。我也有成绩单。我将单词分块成句子,这样我就可以在屏幕上一次显示一个句子,就像电影中的普通字幕一样。为此,我创建了一个 csv,其中每一帧都有一行,每一行都包含该句子时间块中的完整句子。这样,我遍历所有帧并将该句子的文本放在该句子中的每个帧上。我在 OpenCV 中做。

样本记录 csv:

frame     sentence
0           hello
1           hello
2           how are you
3           how are you
4           how are you
5           how are you
6           how are you
7           how are you 
8           fine
...

csv 的长度与视频中的帧数相同。要绘制字幕,我这样做:

import cv2
import pandas as pd

df = pd.read_csv('data.csv')
video = cv2.VideoCapture('vid.mp4')
num_frames = video.get(cv2.CAP_PROP_FRAME_COUNT)

assert len(df) == num_frames

for i in list(range(0, num_frames)):
    ret, frame = video.read()
    cv2.putText(frame, str(df.sentence), (0,50),cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 3, cv2.LINE_AA, True)

    # additional standard cv2 code below...

这可行,但现在我没有任何音频。我了解 OpenCV 不适用于任何音频,但还有其他解决方法吗?这种方法在我的管道中运行良好,因此我希望能够将这些帧写入新视频,但在保留音频的同时尽可能少地使用额外的库。

编辑

使用建议的moviepy解决方案后,我得到一个没有音频的字幕视频,并且出现以下错误:

Moviepy - Building video vidout.mp4.
MoviePy - Writing audio in vidoutTEMP_MPY_wvf_snd.mp3
MoviePy - Done.                                                                                      
Moviepy - Writing video vidout.mp4

t: 100%|████████████████████████████████████████████▉| 23069/23084 [07:26<00:00, 66.35it/s, now=None]Traceback (most recent call last):
  File "/Users/asi/anaconda3/lib/python3.7/site-packages/moviepy/Clip.py", line 472, in iter_frames
    frame = self.get_frame(t)
  File "<decorator-gen-11>", line 2, in get_frame
  File "/Users/asi/anaconda3/lib/python3.7/site-packages/moviepy/decorators.py", line 89, in wrapper
    return f(*new_a, **new_kw)
  File "/Users/asi/anaconda3/lib/python3.7/site-packages/moviepy/Clip.py", line 93, in get_frame
    return self.make_frame(t)
  File "/Users/asi/anaconda3/lib/python3.7/site-packages/moviepy/Clip.py", line 136, in <lambda>
    newclip = self.set_make_frame(lambda t: fun(self.get_frame, t))
  File "/Users/asi/anaconda3/lib/python3.7/site-packages/moviepy/video/VideoClip.py", line 490, in <lambda>
    return self.fl(lambda gf, t: image_func(gf(t)), apply_to)
  File "make_demo.py", line 65, in pipeline
    cv2.putText(frame, str(next(dfi)[1].word), (0, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 3, cv2.LINE_AA, True)
StopIteration

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "make_demo.py", line 72, in <module>
    out_video.write_videofile("vidout.mp4", audio=True)
  File "<decorator-gen-55>", line 2, in write_videofile
  File "/Users/asi/anaconda3/lib/python3.7/site-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "<decorator-gen-54>", line 2, in write_videofile
  File "/Users/asi/anaconda3/lib/python3.7/site-packages/moviepy/decorators.py", line 135, in use_clip_fps_by_default
    return f(clip, *new_a, **new_kw)
  File "<decorator-gen-53>", line 2, in write_videofile
  File "/Users/asi/anaconda3/lib/python3.7/site-packages/moviepy/decorators.py", line 22, in convert_masks_to_RGB
    return f(clip, *a, **k)
  File "/Users/asi/anaconda3/lib/python3.7/site-packages/moviepy/video/VideoClip.py", line 307, in write_videofile
    logger=logger)
  File "/Users/asi/anaconda3/lib/python3.7/site-packages/moviepy/video/io/ffmpeg_writer.py", line 221, in ffmpeg_write_video
    fps=fps, dtype="uint8"):
RuntimeError: generator raised StopIteration

【问题讨论】:

    标签: python opencv video video-processing opencv-python


    【解决方案1】:

    如果另外一个库没问题,您可以使用支持音频的moviepy

    import cv2
    import pandas as pd
    from moviepy.editor import VideoFileClip
    
    def pipeline(frame):
        try:
            cv2.putText(frame, str(next(dfi)[1].sentence), (0, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 3, cv2.LINE_AA, True)
        except StopIteration:
            pass
        # additional frame manipulation
        return frame
    
    dfi = pd.read_csv('data.csv').iterrows()
    video = VideoFileClip("vid.mp4")
    out_video = video.fl_image(pipeline)
    out_video.write_videofile("vidout.mp4", audio=True)
    

    【讨论】:

    • 嗨@Simon Nobel,你有一个csv文件结构的例子吗?谢谢
    • 视频编写和字幕工作,但音频不工作。我现在有一个没有音频的 mp4。我确实将音频文件创建为 mp3,但它们不同步。编辑的 OP 中的错误。
    • 看起来 fl_image() 调用管道函数的频率高于视频中的帧数,导致生成器耗尽项目,因此 next() 引发 StopIteration 异常。一个 try/except 块将至少确保视频将被正确写入,即使可能存在不精确。我已经相应地采用了代码。
    • @SimonNobel 你说得对,管道函数调用的频率高于视频中的帧数。这导致帧操作(即字幕)比音频移动得更快。另外,当我打开moviepy创建的视频时,帧是蓝色的。有什么想法吗?
    猜你喜欢
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多