用AI和阿里云FunASR实现视频语音识别和自动字幕脚本制作

1,355 阅读4分钟

前言

我除了有个 AI 生成壁纸的计划,还有一个想法就是用 AI 剪视频,AI 剪视频当然是需要 AI 理解视频,最简单的就是理解视频中的字幕,之前写过文章介绍如何用 AI 来识别语音,今天就利用阿里云开源项目制作 FunASR 进行语音识别。

部署

部署文档链接:github.com/modelscope/…

​这里是参考官方文档进行CPU 离线语音识别部署,先下载 Docker 镜像:

sudo docker pull  registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.5

然后创建模型文件夹,运行容器

mkdir -p ./funasr-runtime-resources/models

sudo docker run -p 10095:10095 -it --privileged=true  -v $PWD/funasr-runtime-resources/models:/workspace/models registry.cn-hangzhou.aliyuncs.com/funasr_repo/funasr:funasr-runtime-sdk-cpu-0.4.5

这时自动进入了容器内部,使用 nohup 运行服务端程序

nohup bash run_server.sh \
  --download-model-dir /workspace/models \
  --vad-dir damo/speech_fsmn_vad_zh-cn-16k-common-onnx \
  --model-dir damo/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-onnx  \
  --punc-dir damo/punc_ct-transformer_cn-en-common-vocab471067-large-onnx \
  --lm-dir damo/speech_ngram_lm_zh-cn-ai-wesp-fst \
  --itn-dir thuduj12/fst_itn_zh \
  --hotword /workspace/models/hotwords.txt > log.txt 2>&1 &

在这种情况下很难调试这个服务端程序的,只能通过查看程序的进程来看看是否正常运行。

微信截图_20240722214835.png

接着来调试客户端,最简单的就是直接使用HTML进行测试,需要下载官方的 demo。

github.com/alibaba-dam…

在这个文件夹下找到 html5/static/index.html 直接用本地浏览器打开。

填写服务端地址,需要注意是 WebSocket 的地址,用 wss 开头,再选择本地的文件选择上传,最后点击链接自动回上传到服务端处理识别语音。

微信截图_20240722220131.png

可以直接选择 mp4 文件,不用特地转换为 mp4 格式。挺方便的。

最后我将这段HTML代码交给了AI ,让 AI 生成了一段代码,模拟了HTML代码的功能,通过脚本的方式进行语音识别,下面是通过AI生成的脚本,用于制作SRT字幕::


import asyncio
import websockets
import json
import ssl


def convert_to_srt(json_data):
    """将 JSON 格式的识别结果转换为 SRT 字幕格式。

    Args:
        json_data (str or dict): JSON 格式的识别结果,可以是字符串或字典。

    Returns:
        str: SRT 格式的字幕文本。
    """

    if isinstance(json_data, str):
        json_data = json.loads(json_data)

    srt_text = ""
    for i, segment in enumerate(json_data['stamp_sents']):
        start_time_ms = segment['start']
        end_time_ms = segment['end']

        # 将毫秒转换为 SRT 时间格式 (HH:MM:SS,mmm)
        start_time = f"{int(start_time_ms / 3600000):02d}:{int(start_time_ms / 60000) % 60:02d}:{int(start_time_ms / 1000) % 60:02d},{int(start_time_ms % 1000):03d}"
        end_time = f"{int(end_time_ms / 3600000):02d}:{int(end_time_ms / 60000) % 60:02d}:{int(end_time_ms / 1000) % 60:02d},{int(end_time_ms % 1000):03d}"

        srt_text += f"{i + 1}\n"
        srt_text += f"{start_time} --> {end_time}\n"
        srt_text += f"{segment['text_seg']}{segment['punc']}\n\n"

    return srt_text

async def run_asr(uri, file_path, chunk_size=960):
    """
    使用 WebSocket 发送音频文件并获取识别结果。

    Args:
        uri (str): WebSocket 服务器地址。
        file_path (str): 音频文件路径。
        chunk_size (int): 每个数据块的大小(以字节为单位)。

    Returns:
        str: 识别结果文本。
    """
    ssl_context = ssl.create_default_context()
    ssl_context.check_hostname = False
    ssl_context.verify_mode = ssl.CERT_NONE
    async with websockets.connect(uri, ssl=ssl_context) as websocket:

        # 发送初始请求
        request = {
            "chunk_size": [5105],
            "wav_name":  "h5",
            "is_speaking":  True,
            "chunk_interval"10,
            "mode""offline",
        }
        request1 = {"chunk_size":[5,10,5],"wav_name":"h5","is_speaking":True,"chunk_interval":10,"itn":False,"mode":"offline","wav_format":"mp4","hotwords":"{\"阿里巴巴\":20,\"hello world\":40}"}

        await websocket.send(json.dumps(request1))

        # 读取并发送音频数据
        with open(file_path, 'rb'as f:
            while True:
                chunk = f.read(chunk_size)
                if not chunk:
                    break
                await websocket.send(chunk)

        # 发送结束信号
        request["is_speaking"] = False
        await websocket.send(json.dumps(request))

        # 接收并处理结果
        async for message in websocket:
            data = json.loads(message)
            return data


# 设置 WebSocket 服务器地址和音频文件路径
websocket_uri = "wss://***.***.***.***:*****"  # 请替换为您的 WebSocket 服务器地址
audio_file = "./1.wav"  # 请替换为您的音频文件路径

# 运行异步函数
result = asyncio.run(run_asr(websocket_uri, audio_file))



# 打印识别结果
print("识别结果:", result)

srt_str = convert_to_srt(result)

print('srt:', srt_str)

Python 编程中 websockets 和 asyncio 自己不太熟练,还有创建 SRT 格式的字幕文本格式也没有做过,AI 节省了很多查找资料的时间和精力,非常不错。

微信截图_20240722221427.png

最后

视频中的语音识别已经完成,后面还会继续分享字幕纠正处理,视频剪辑相关的内容,如果感兴趣可以继续关注我

如果觉得内容不错,欢迎点个关注