基于豆包大模型为音视频生成字幕-完整代码可用版

为音频和视频生成对应字幕的方法有很多,之前介绍过本地模型 openai-whisper ,虽然需要下载模型配置复杂环境,但全免费无限制。

今天介绍个更简单的方式,豆包提供的在线“音视频字幕生成”功能。相比 openai-whisper 简单许多,速度也更快,有20个小时的免费额度。

首先登陆注册火山引擎

登陆地址 console.volcengine.com/auth/login

若无账号,当然需要先注册了,还需要实名认证哦。

创建一个应用

上步登陆并实名认证后,打开“语音技术”模块,直达地址 console.volcengine.com/speech/app

点击 “创建应用”,名字填写英文,描述随意,重要的是下方的一堆复选框,拉到底部,选中“音视频字幕生成”,这是必须的,其他均可以不选。

image.png

image.png

点击确定,继续下一步“获取 APP ID 和 Access Token”

获取 Access Token / 开通正式版

创建应用后,去应用服务开通的地方复制 Access Token,按下图所示进入,点击左侧“API服务中心”–“音视频字幕”–“音视频字幕生成” 或 直接打开 console.volcengine.com/speech/serv…

image.png

在右侧,你将能看到已创建的所有应用,选择你要使用的那个

image.png

image.png

默认创建的是试用版,有20个小时的免费时长。

从上方应用名称里选择你要使用的的应用,拉到页面底部找到“服务接口认证信息”处,复制 APP IDAccess Token, 代码中将用到这2个信息。

你也可以点击开通,转为后付费正式版

image.png

安装python3.10和ffmpeg

如果不会安装,请查看教程 juejin.cn/post/738391…

开始接入识别

新建一个空白文件夹,在其内创建 start.py 文件, 输入代码

import time
import subprocess
import requests
import re
from datetime import timedelta

# 固定
base_url = 'https://openspeech.bytedance.com/api/v1/vc'
appid = "填写刚才记录的 APP ID"
access_token = "填写刚成记录的 Access Token"
# 音视频发声语言
language = 'zh-CN'
#待识别的文件
file_url = r'./60.mp4'


注意2个参数,一是 language 代表语言代码,中文是 zh-CN,其他语言对应填写

image.png

file_url 参数是你需要识别的音频或视频文件,为方便起见,可将这些文件复制到 start.py 所在目录,然后填写带后缀的文件名称,如果在其他目录下,请填写盘符开头的完整文件路径,直到文件后缀。

提取出音轨

需要确保设备已安装了ffmpeg并配置了环境变量,如果没有,请查看 juejin.cn/post/738391…

以下代码确保将任何格式的音视频均转为 1通道24k的wav音频文件。

subprocess.run(["ffmpeg","-y",'-i',file_url,"-ac","1","-ar","24000","./chuli.wav"])

chuli.wav 就是从视频中提取出来的将要发送给豆包进行识别的音轨文件。

接着以二进制形式提交音轨数据

    with open("./chuli.wav",'rb') as f:
        audio=f.read()
        response = requests.post(
                 '{base_url}/submit'.format(base_url=base_url),
                 params=dict(
                     appid=appid,
                     language=language,
                     use_itn='True',
                     caption_type='speech',
                     max_lines=1,
                     words_per_line=15,
                 ),
                 data=audio,
                 headers={
                    'Content-Type': 'audio/wav',
                    'Authorization': 'Bearer; {}'.format(access_token)
                 }
        )



这里要注意,以 rb 直接读取音频为 Byte 数据,然后传递给 data参数,headers参数里Content-Type需设为 audio/wav。

max_lines=1 表示每条字幕最多只能包含一行文字,如果 改为 max_lines=2,即代表最多允许2行。 words_per_line=15 表示一行最多15个字符,如果英文的话可以改成 50 更合适。

params 里还可提供更多参数,用于更细化的控制识别,具体可参考豆包文档

image.png www.volcengine.com/docs/6561/8…

如果没出错的话,提交后将返回

{ "code": "0", "message": "Success", "id": "fc5aa03e-6ae4-46a3-b8cf-1910a44e0d8a" }

id是任务编号,据此再去查询识别任务是否完成,如果任务已完成,不管失败还是成功,都会返回json数据

job_id = response.json()['id']
response = requests.get(
        '{base_url}/query'.format(base_url=base_url),
        params=dict(
            appid=appid,
            id=job_id,
        ),
        headers={
           'Authorization': 'Bearer; {}'.format(access_token)
        }
)
    
   

注意 params里的参数,默认是阻塞,即直到任务有了结果才返回,可以通过添加参数 blocking=0 改为非阻塞,即查询任务未完成也立即返回

如果不幸失败了,返回信息中 code 是错误代码,message 是错误原因。

"id": "d22cca84-8c8a-4d15-aa2c-ac550518d5ae", "code": 错误码, "message": "错误原因",

识别成功返回结果中将存到 utterances 列表,遍历列表中每个元素的textstart_timeend_time 字段,可获取识别结果,当然还可以进一步使用 words 字段,获取每个字符的时间戳

[ 
    { 
        "text": "如果您没有其他需要举报的话这边就先挂断了", 
        "start_time": 0, 
        "end_time": 3197, 
        "words": [ 
            { 
                "text": "如", 
                "start_time": 0, 
                "end_time": 208 
            }....

将结果转为 srt 格式的字幕

srts=[]
for i,it in enumerate(response.json()['utterances']):
    srts.append(f'{i+1}\n{ms_to_time_string(ms=it["start_time"])} --> {ms_to_time_string(ms=it["end_time"])}\n{it["text"]}\n\n')

with open(f'./chuli.srt','w',encoding='utf-8') as f:
    f.write("".join(srts))

打开 chuli.srt 字幕,效果还不错。

image.png

完整代码

import time
import subprocess
import requests
import re
import os
from datetime import timedelta

base_url = 'https://openspeech.bytedance.com/api/v1/vc'
# 应用 APP ID
appid = "填写应用APP ID"
# Access_Token
access_token = "填写Access Token"

# 音频视频中说话语言
language = 'zh-CN'
# 音视频文件地址
file_url = r'./60.mp4'

# 将毫秒转为字幕格式时间值
def ms_to_time_string(*, ms=0, seconds=None):
    # 计算小时、分钟、秒和毫秒
    if seconds is None:
        td = timedelta(milliseconds=ms)
    else:
        td = timedelta(seconds=seconds)
    hours, remainder = divmod(td.seconds, 3600)
    minutes, seconds = divmod(remainder, 60)
    milliseconds = td.microseconds // 1000

    time_string = f"{str(hours).zfill(2)}:{str(minutes).zfill(2)}:{str(seconds).zfill(2)},{str(milliseconds).zfill(3)}"
    return time_string

# 文件的基本名字
basename=os.path.basename(file_url)

# 提取音频
subprocess.run(["ffmpeg","-y",'-i',file_url,"-ac","1","-ar","24000",basename+".wav"])
with open(basename+".wav",'rb') as f:
    audio=f.read()
    response = requests.post(
             '{base_url}/submit'.format(base_url=base_url),
             params=dict(
                 appid=appid,
                 language=language,
                 use_itn='True',
                 caption_type='speech',
                 max_lines=1,#每条字幕只允许一行文字
                 words_per_line=15,#每行文字最多15个字符
             ),
             data=audio,#二进制音频
             headers={
                'Content-Type': 'audio/wav',
                'Authorization': 'Bearer; {}'.format(access_token)
             }
    )
print('submit response = {}'.format(response.text))
assert(response.status_code == 200)
assert(response.json()['message'] == 'Success')

# 得到任务id,继续执行查询任务状态
job_id = response.json()['id']
response = requests.get(
        '{base_url}/query'.format(base_url=base_url),
        params=dict(
            appid=appid,
            id=job_id,
        ),
        headers={
           'Authorization': 'Bearer; {}'.format(access_token)
        }
)
assert(response.status_code == 200)

result=response.json()

assert(result['code'] == 0)

# 保存 srt 字幕
srts=[]
for i,it in enumerate(result['utterances']):
    srt=f'{i+1}\n{ms_to_time_string(it["start_time"])} --> {it["end_time"]}\n{it["text"]}\n\n'
    srts.append(srt)
    print(srt)

with open(f'./{basename}.srt','w',encoding='utf-8') as f:
    f.write("".join(srts))



代码保存为 start.py, 填写好自己的APP ID 和 Access Token,以及音视频地址,然后打开 cmd 窗口(文件夹地址栏输入cmd回车),执行 python start.py,没意外的情况下,就能看到输出以及当前目录下创建的 srt 字幕文件了

srt 格式的字幕文件可用记事本打开

  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值