人工智能——离线情况下自动给视频添加字幕,支持中文,英文,日文等等

前言

最近打开百度网盘,看到播放视频有一个AI字幕功能,心情非常激动,看视频的同时可以看自动生成的字幕,防止听不清视频中人物的话语
然而不是SVIP,我试用过了之后就没有这个功能选项了
我在想,如果随便哪一个“免费”播放器,都可以一边播放视频,一边生成字幕,外文自动翻译,那不是牛哄哄?
看教程,看视频都可以方便很多,因为语音太杂了,听完后有时还要猜视频中的人物说的什么,尤其是倍速情况下,有了自动生成的字幕之后,都不再是问题
问题是如何达到这一点?当然喽,重点是免费,高效
当然,我已经实现了,Follow me!
文件都在这里,下载好文件一步步来就可以了
配置环境:

  • 系统: win10
  • ffmpeg:ffmpeg-5.1.2-essentials_build.zip
  • python:3.8.8
  • python包:vosk-0.3.45-py3-none-win_amd64.whl
  • 语音模型:vosk-model-cn-0.22

流程

设想这样一个情景,向视频播放器中塞进一个语音转文字模型,当它加载视频流的时候,一边提前读取视频流,用语音模型生成字幕,一遍播放已经生成字幕的视频,不就是如此吗?
先安装相关文件

当然依旧存在的一个问题是,识别到中文,英文,日文,意大利文,俄文字幕后怎么翻译为中文的问题

作为白嫖党,我是不付费的,虽然有道,百度都提供了付费的api接口,用于对视频生成srt收费,以及提供了翻译服务
可以边生成原文语音文本,再翻译为中文文本,但是问题是他是付费的啊
但我是不可能付费的
我采取的办法是这样的
将视频丢进vosk语音识别模型生成带时间戳的字幕srt文件,然后再将这个srt备份转为纯文本的的docx文件,
(这样就得到了一个不带时间戳而只有对话的纯文本docx文件,以及一个带时间戳的外文srt视频字幕文件)
然后将这个docx文件丢进谷歌翻译中翻译为中文docx文件
然后将这个翻译过的中文docx文件对照srt中文本进行替换,就得到了带时间戳的中文srt文件

安装ffmpeg

https://ffmpeg.org/download.html
这是官网
在这里插入图片描述
在这里插入图片描述
安装就是解压而已,然后在系统变量中添加文件中的bin路径
在这里插入图片描述
然后cmd输入命令,查看是否已经识别

ffmpeg –version

在这里插入图片描述

安装python包

自己从官网下再安装 https://pypi.org/
vosk-0.3.45-py3-none-win_amd64.whl放到目录下,

pip install  vosk-0.3.45-py3-none-win_amd64.whl

测试模型——对视频使用语音模型生成srt字幕,拖入视频播放器中

官网 模型文件下载地址https://alphacephei.com/vosk/models
先生成字幕文件
将想要识别语言类别的对应模型解压,想要识别中文语音就用中文模型,英文就用英文模型,日文就用日文模型等
需要注意的是先将视频文件,转成单通道wma语音文件,语音模型是对wma文件识别的,抛弃了对语音识别无用的图像信息

这里有一个自动的srt字幕生成,只需要将视频文件所在的目录设置好,就可以了,它可以为目录下所有的mp4文件生成srt字幕

from moviepy.editor import *
from moviepy.audio.fx.all import audio_left_right
from moviepy.audio.AudioClip import AudioArrayClip
import time
import subprocess
import os
import sys
from vosk import Model, KaldiRecognizer, SetLogLevel

# 解压的模型文件,英文,中文用对应model
getCn = r"D:\PGMCode\Mycode\pythonCode\goodTools\videoSrtpgm\iModel\cn\vosk-model-cn-0.22"
getCn1 = r"D:\PGMCode\Mycode\pythonCode\goodTools\videoSrtpgm\iModel\cn\vosk-model-cn-kaldi-multicn-0.15"
getJP = r"D:\PGMCode\Mycode\pythonCode\goodTools\videoSrtpgm\iModel\jp\vosk-model-ja-0.22"
getEn = r"D:\PGMCode\Mycode\pythonCode\goodTools\videoSrtpgm\iModel\en\vosk-model-en-us-0.42-gigaspeech"
def list_files(path):
    fileMP4List = []
    fileSRTList = []
    count=1
    # 遍历目录下的所有文件和子目录,并输出
    for root, dirs, files in os.walk(path):
        for file in files:
            if file.endswith("mp4"):
                fileMP4List.append([count,os.path.join(root, file)])
                count=count+1
            if file.endswith("srt"):
                fileSRTList.append(os.path.join(root, file)[:-4])
    for i in range(len(fileMP4List)):
        if fileMP4List[i][1][:-4] in fileSRTList:
            fileMP4List[i][1]+="    已有srt"
    return fileMP4List
def getWav(videoPath):
    print("提取音频")
    clip = VideoFileClip(videoPath)
    audio = clip.audio

    # 将音频转换为单通道
    audio_array = audio.to_soundarray()
    audio_left_right(audio_array)
    # 获取音频剪辑的持续时间
    duration = audio.duration
    # 将单通道音频转换为音频剪辑对象
    audio_mono = AudioArrayClip(audio_array, fps=audio.fps)
    newWavePath=videoPath[:-4]+'.wav'
    # 保存音频为WAV文件
    audio_mono.write_audiofile(newWavePath)
    print("音频生成完成,准备输出srt")
    return newWavePath
def getSrt(newWavePath,modelLanguage):
    print("提取srt中...")
    print("开始加载识别模型")
    SAMPLE_RATE = 16000
    SetLogLevel(-1)
    model = Model(modelLanguage)
    print("模型加载完毕,开始识别...")
    rec = KaldiRecognizer(model, SAMPLE_RATE)
    # 修改需要识别的语音文件路径
    wavPath=newWavePath
    print(wavPath)
    rec.SetWords(True)
    result = []
    with subprocess.Popen(["ffmpeg", "-loglevel", "quiet", "-i",
                                wavPath,
     "-ar", str(SAMPLE_RATE) , "-ac", "1", "-f", "s16le", "-"],
     stdout=subprocess.PIPE).stdout as stream:
        word=rec.SrtResult(stream)
        result.append(word)
        print("识别到字幕  {}".format(word))
    # 生成srt文件
    output = open(wavPath[:-4]+'.srt','w')
    output.write("\n".join(result))
    output.close()
    print("srt输出完成")
    os.remove(wavPath)
    # 列出当前目录下的所有文件和子目录
filePath = r"D:\迅雷下载\新建文件夹"
allFile = list_files(filePath)
modelLanguage=getJP
for i in range(0, len(allFile)):
    if  "已有srt" in allFile[i][1]:
        pass
    else:
        videoPath = allFile[i][1]
        print("开始识别的文件为:"+videoPath)
        # try:
        getSrt(getWav(videoPath),modelLanguage)
        # except:
        #     # print("字幕生成错误")
        time.sleep(3)
print("设定目录全部字幕生成完成")



如果想要单条,可以麻烦点手动,下面这个是以前的,手动将视频转成声音文件,上面的是升级过的,自动在代码里转化了
古老的:
格式工厂
在这里插入图片描述
将代码中的音频文件换一下位置,模型文件换个解压好的名字,等待输出就行了
如果报错wma非pcm开头等等,请确认一下wma文件是否是单通道,测试中发现格式工厂使用高质量输出可以,保持原采样率,如果降低质量则识别失败,使用中保持原始采样率即可,单改通道

import subprocess
import os
import sys
from vosk import Model, KaldiRecognizer, SetLogLevel
SAMPLE_RATE = 16000
SetLogLevel(-1) 
# 解压的模型文件,英文,中文用对应model
model = Model(r"C:\Users\Administrator\MyFileLi\AIPrograms\model_cn")
rec = KaldiRecognizer(model, SAMPLE_RATE)
# 修改需要识别的语音文件路径
wavPath=r"D:\FFOutput\课时1.wma"
rec.SetWords(True)
result = []
with subprocess.Popen(["ffmpeg", "-loglevel", "quiet", "-i",
                            wavPath,
 "-ar", str(SAMPLE_RATE) , "-ac", "1", "-f", "s16le", "-"],
 stdout=subprocess.PIPE).stdout as stream:
    result.append(rec.SrtResult(stream))
print(result)
# 生成srt文件
output = open(wavPath.split("\\")[-1].split(".")[:-1][0]+'.srt','w')
output.write("\n".join(result))
output.close()

将srt拖入视频,输出

在这里插入图片描述

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值