import os
from moviepy.editor import VideoFileClip, AudioFileClip, CompositeVideoClip, TextClip
from vosk import Model, KaldiRecognizer
import json
from pydub import AudioSegment
import moviepy.config as mpy_config
mpy_config.IMAGEMAGICK_BINARY = r"D:\ImageMagick-7.1.1-Q16-HDRI\magick.exe" # 替换为你的路径
video_path = r"D:\down\Media\英文演讲:人工智能\AI.mp4" # 替换为你的输入视频路径
output_path = "video_with_subs.mp4" # 输出视频路径
model_path = r"D:\vosk-model-small-en-us-0.15" # 替换为你的Vosk模型路径
temp_audio_path = "temp_audio.wav"
srt_path = "subtitles.srt"
# 1. 提取音频
video = VideoFileClip(video_path)
video.audio.write_audiofile(temp_audio_path, codec='pcm_s16le')
# 2. 使用Vosk识别
model = Model(model_path)
audio = AudioSegment.from_wav(temp_audio_path)
audio = audio.set_frame_rate(16000).set_channels(1)
recognizer = KaldiRecognizer(model, 16000)
chunk_length_ms = 3000 # 3秒块
results = []
print("开始语音识别,请稍候...")
for i in range(0, len(audio), chunk_length_ms):
chunk = audio[i:i+chunk_length_ms]
if recognizer.AcceptWaveform(chunk.raw_data):
res_json = json.loads(recognizer.Result())
if 'text' in res_json:
start_time = i / 1000
end_time = (i + chunk_length_ms) / 1000
results.append((start_time, end_time, res_json['text']))
# 3. 生成SRT字幕
def seconds_to_srt_time(seconds):
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
secs = int(seconds % 60)
milliseconds = int((seconds - int(seconds)) * 1000)
return f"{hours:02}:{minutes:02}:{secs:02},{milliseconds:03}"
with open(srt_path, "w", encoding="utf-8") as f:
for idx, (start, end, text) in enumerate(results, 1):
if not text.strip():
continue # 跳过空字幕
f.write(f"{idx}\n")
f.write(f"{seconds_to_srt_time(start)} --> {seconds_to_srt_time(end)}\n")
f.write(f"{text}\n\n")
print("字幕已生成:", srt_path)
# 4. 将字幕添加到视频中
# 使用 moviepy 阅读字幕文件
from moviepy.video.tools.subtitles import SubtitlesClip
subtitles = SubtitlesClip(srt_path, lambda txt: TextClip(txt, fontsize=24, color='white', bg_color='black', align='South'))
# 设置字幕位置
subtitles = subtitles.set_pos(('bottom'))
# 合成视频
video = VideoFileClip(video_path)
video_with_subs = CompositeVideoClip([video, subtitles.set_duration(video.duration)])
# 5. 输出新视频
video_with_subs.write_videofile(output_path, codec='libx264', fps=video.fps)
# 其他清理(可选)
if os.path.exists(temp_audio_path):
os.remove(temp_audio_path)
print(f"视频已保存为:{output_path}") 这段代码运行后输出为
开始语音识别,请稍候...
字幕已生成: subtitles.srt
Moviepy - Building video video_with_subs.mp4.
MoviePy - Writing audio in video_with_subsTEMP_MPY_wvf_snd.mp3
chunk: 0%| | 0/4470 [00:00<?, ?it/s, now=None]Traceback (most recent call last):
File "D:\Moviepy\test.py", line 71, in <module>
video_with_subs.write_videofile(output_path, codec='libx264', fps=video.fps)
File "<decorator-gen-51>", line 2, in write_videofile
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\decorators.py", line 54, in requires_duration
return f(clip, *a, **k)
^^^^^^^^^^^^^^^^
File "<decorator-gen-50>", line 2, in write_videofile
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\decorators.py", line 137, in use_clip_fps_by_default
return f(clip, *new_a, **new_kw)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "<decorator-gen-49>", line 2, in write_videofile
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\decorators.py", line 22, in convert_masks_to_RGB
return f(clip, *a, **k)
^^^^^^^^^^^^^^^^
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\video\VideoClip.py", line 312, in write_videofile
self.audio.write_audiofile(audiofile, audio_fps,
File "<decorator-gen-73>", line 2, in write_audiofile
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\decorators.py", line 54, in requires_duration
return f(clip, *a, **k)
^^^^^^^^^^^^^^^^
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\audio\AudioClip.py", line 205, in write_audiofile
return ffmpeg_audiowrite(self, filename, fps, nbytes, buffersize,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<decorator-gen-70>", line 2, in ffmpeg_audiowrite
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\decorators.py", line 54, in requires_duration
return f(clip, *a, **k)
^^^^^^^^^^^^^^^^
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\audio\io\ffmpeg_audiowriter.py", line 166, in ffmpeg_audiowrite
for chunk in clip.iter_chunks(chunksize=buffersize,
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\audio\AudioClip.py", line 84, in iter_chunks
yield self.to_soundarray(tt, nbytes=nbytes, quantize=quantize,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<decorator-gen-72>", line 2, in to_soundarray
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\decorators.py", line 54, in requires_duration
return f(clip, *a, **k)
^^^^^^^^^^^^^^^^
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\audio\AudioClip.py", line 126, in to_soundarray
snd_array = self.get_frame(tt)
^^^^^^^^^^^^^^^^^^
File "<decorator-gen-10>", line 2, in get_frame
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\decorators.py", line 89, in wrapper
return f(*new_a, **new_kw)
^^^^^^^^^^^^^^^^^^^
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\Clip.py", line 95, in get_frame
return self.make_frame(t)
^^^^^^^^^^^^^^^^^^
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\audio\AudioClip.py", line 295, in make_frame
sounds = [c.get_frame(t - c.start)*np.array([part]).T
^^^^^^^^^^^^^^^^^^^^^^^^
File "<decorator-gen-10>", line 2, in get_frame
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\decorators.py", line 89, in wrapper
return f(*new_a, **new_kw)
^^^^^^^^^^^^^^^^^^^
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\Clip.py", line 95, in get_frame
return self.make_frame(t)
^^^^^^^^^^^^^^^^^^
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\audio\io\AudioFileClip.py", line 78, in <lambda>
self.make_frame = lambda t: self.reader.get_frame(t)
^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\audio\io\readers.py", line 184, in get_frame
self.buffer_around(fr_max)
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\audio\io\readers.py", line 238, in buffer_around
array = self.read_chunk(chunksize)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\Moviepy\.venv\Lib\site-packages\moviepy\audio\io\readers.py", line 112, in read_chunk
s = self.proc.stdout.read(L)
^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'stdout'是什么原因,应该怎么修改代码
最新发布