使用moviepy为电影添加字幕

11

我尝试跟随这个例子来给电影剪辑添加字幕:

from moviepy.video.tools.subtitles import SubtitlesClip
from moviepy.video.io.VideoFileClip import VideoFileClip
subs = [((0, 3), 'sub1'),
        ((3, 7), 'sub2'),
        ((9, 11), 'sub3'),
        ((11, 16), 'sub4')]
subtitles = SubtitlesClip(subs)
clip = VideoFileClip(video_fname)
video = movedit.CompositeVideoClip([clip, subtitles])
video.to_videofile(output_video_name)
但是输出的电影没有字幕。我做错了什么吗? 顺便说一句,subtitles.py 在 Python 3 上不起作用,这行代码
subtitles = [(map(cvsecs, tt),txt) for tt, txt in subtitles]

需要进行更改

subtitles = [(list(map(cvsecs, tt),txt)) for tt, txt in subtitles]

编辑

最终我用了更困难的方法创建了字幕:

from moviepy import editor
import os.path as op

def annotate(clip, txt, txt_color='red', fontsize=50, font='Xolonium-Bold'):
    """ Writes a text at the bottom of the clip. """
    txtclip = editor.TextClip(txt, fontsize=fontsize, font=font, color=txt_color)
    cvc = editor.CompositeVideoClip([clip, txtclip.set_pos(('center', 'bottom'))])
    return cvc.set_duration(clip.duration)

video = editor.VideoFileClip(op.join(movie_fol, movie_name))
subs = [((0, 4), 'subs1'),
        ((4, 9), 'subs2'),
        ((9, 12), 'subs3'),
        ((12, 16), 'subs4')]
annotated_clips = [annotate(video.subclip(from_t, to_t), txt) for (from_t, to_t), txt in subs]
final_clip = editor.concatenate_videoclips(annotated_clips)
final_clip.write_videofile(op.join(movie_fol, out_movie_name))

虽然它还不完美,仍有改进的空间,比如支持没有字幕的时间范围,但它解决了我的问题。


我收到一个错误,上面写着NameError: op not defined。op是什么? - Swapnil B.
抱歉,您需要添加此导入: import os.path as op - Noam Peled
3个回答

11
这也适用于python3:
from moviepy.editor import *
from moviepy.video.tools.subtitles import SubtitlesClip

generator = lambda txt: TextClip(txt, font='Arial', fontsize=24, color='white')
subs = [((0, 4), 'subs1'),
        ((4, 9), 'subs2'),
        ((9, 12), 'subs3'),
        ((12, 16), 'subs4')]

subtitles = SubtitlesClip(subs, generator)

video = VideoFileClip("input.mp4")
result = CompositeVideoClip([video, subtitles.set_pos(('center','bottom'))])

result.write_videofile("output.mp4", fps=video.fps, temp_audiofile="temp-audio.m4a", remove_temp=True, codec="libx264", audio_codec="aac")

1

之前的解决方案在 Mac 芯片 M1 和 Python 3.9.5 上无法工作。

对于给定的环境,SubtitlesClip API 只接受 SRT 文件。以下是可行的脚本:

from moviepy.editor import *
from moviepy.video.tools.subtitles import SubtitlesClip

generator = lambda txt: TextClip(txt, font='Arial', fontsize=24, color='white')
subs = SubtitlesClip('subtitles.srt', generator)
subtitles = SubtitlesClip(subs, generator)

video = VideoFileClip("input.mp4")
result = CompositeVideoClip([video, subtitles.set_pos(('center','bottom'))])

result.write_videofile("output.mp4")


subtitles.srt: 
1
00:00:00,000 --> 00:00:12,00
A customer review is
an evaluation of a
product or service
made by someone who
has purchased and
used, or had
experience with, a
product or service.

2
00:00:14,000 --> 00:00:27,00
Customer reviews
are a form of
customer feedback
on electronic
commerce and online
shopping sites.

3
00:00:14,000 --> 00:00:27,00

很重要添加空的第三个条目,否则第二行不会包含在视频中。

requirements.txt

absl-py==1.3.0 anyio==3.4.0 appnope==0.1.2 argon2-cffi==21.3.0 argon2-cffi-bindings==21.2.0 asgiref==3.6.0 astunparse==1.6.3 attrs==21.2.0 Babel==2.9.1 backcall==0.2.0 bidict==0.22.0 bleach==4.1.0 cachetools==5.2.0 certifi==2020.12.5 cffi==1.15.0 chardet==4.0.0 click==7.1.2 cycler==0.11.0 cymem==2.0.7 debugpy==1.5.0 decorator==4.4.2 defusedxml==0.7.1 Django==4.1.6 dnspython==2.2.1 entrypoints==0.3 eventlet==0.33.2 expiringdict==1.2.2 fastapi==0.63.0 fasteners==0.16.3 filelock==3.9.0 Flask==2.0.2 Flask-SocketIO==5.1.1 flatbuffers==22.12.6 fonttools==4.28.5 fuzzywuzzy==0.18.0 gast==0.4.0 google-auth==2.15.0 google-auth-oauthlib==0.4.6 google-pasta==0.2.0 greenlet==2.0.1 grpcio==1.51.1 h11==0.12.0 h5py==3.7.0 huggingface-hub==0.12.0 idna==2.10 imageio==2.25.0 imageio-ffmpeg==0.4.8 importlib-metadata==5.1.0 ipykernel==6.6.1 ipython==7.31.0 ipython-genutils==0.2.0 ipywidgets==7.6.5 itsdangerous==2.1.2 jedi==0.18.1 Jinja2==3.0.1 joblib==1.2.0 json5==0.9.6 jsonschema==3.2.0 jupyter==1.0.0 jupyter-client==7.1.0 jupyter-console==6.4.0 jupyter-core==4.7.1 jupyter-server==1.13.1 jupyterlab==3.2.8 jupyterlab-pygments==0.1.2 jupyterlab-server==2.10.3 jupyterlab-widgets==1.0.2 keras==2.11.0 kiwisolver==1.3.2 Levenshtein==0.20.9 libclang==14.0.6 Markdown==3.4.1 MarkupSafe==2.0.1 matplotlib==3.5.1 matplotlib-inline==0.1.3 mistune==0.8.4 moviepy==1.0.3 nbclassic==0.3.4 nbclient==0.5.9 nbconvert==6.4.0 nbformat==5.1.3 nest-asyncio==1.5.4 networkx==2.5.1 nltk==3.8.1 notebook==6.4.7 numpy==1.24.2 oauthlib==3.2.2 opt-einsum==3.3.0 packaging==22.0 pandas==1.3.5 pandocfilters==1.5.0 parso==0.8.3 pd==0.0.4 pexpect==4.8.0 pickleshare==0.7.5 Pillow==9.1.0 proglog==0.1.10 prometheus-client==0.12.0 prompt-toolkit==3.0.24 protobuf==3.19.6 psutil==5.8.0 ptyprocess==0.7.0 pyasn1==0.4.8 pyasn1-modules==0.2.8 pybind11==2.10.3 pycparser==2.21 pydantic==1.8.1 pydot==1.4.2 pydotplus==2.0.2 Pygments==2.9.0 pymongo==4.0.1 pyparsing==2.4.7 pyrsistent==0.17.3 python-dateutil==2.8.1 python-engineio==4.3.4 python-Levenshtein==0.20.9 python-socketio==5.7.2 python-version==0.0.2 pytz==2021.1 PyYAML==5.4.1 pyzmq==22.1.0 qtconsole==5.2.2 QtPy==2.0.0 rapidfuzz==2.13.7 regex==2022.10.31 requests==2.25.1 requests-oauthlib==1.3.1 rsa==4.9 scikit-learn==1.2.1 scipy==1.7.3 Send2Trash==1.8.0 sentence-transformers==2.2.2 sentencepiece==0.1.97 six==1.15.0 sklearn==0.0 sniffio==1.2.0 sos==0.22.5 sqlparse==0.4.3 starlette==0.13.6 tensorboard==2.11.0 tensorboard-data-server==0.6.1 tensorboard-plugin-wit==1.8.1 tensorflow-estimator==2.11.0 tensorflow-macos==2.11.0 termcolor==2.1.1 terminado==0.12.1 testpath==0.5.0 threadpoolctl==3.1.0 tokenizers==0.13.2 torch==1.13.1 torchvision==0.14.1 tornado==6.1 tqdm==4.61.1 traitlets==5.1.0 transformers==4.26.0 typer==0.7.0 typing_extensions==4.4.0 tzlocal==2.1 urllib3==1.26.3 uvicorn==0.13.4 wasabi==1.1.1 wcwidth==0.2.5 webencodings==0.5.1 websocket-client==1.2.3 websockets==10.1 Werkzeug==2.0.2 widgetsnbextension==3.5.2 wrapt==1.14.1 xxhash==2.0.2 zipp==3.11.0


我遇到了一个错误 " self.duration = max([tb for ((ta,tb), txt) in self.subtitles]) ^^^^^^^ TypeError: cannot unpack non-iterable NoneType object" - MMM
我已经放置了 requirements.txt 文件,请检查是否有用。 - Leonardo V
@MMM 那个错误是因为 *.srt 文件没有从顶部开始。 - undefined

0

桑迪潘给出的答案对我来说原本不起作用,但在几个步骤后可以运行。你需要确保安装了ImageMagick。对于Linux用户还需要进行一些修改。按照提供的步骤,我成功让代码运行起来这里。(注意:我使用的是Python 3.10)

在最终让这段代码工作之前,我在网上搜索了很多信息。所以我想分享这个,因为它可以节省我数小时的时间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接