如何自动识别视频语音内容并生成字幕

本文介绍了如何利用腾讯云COSSDK调用语音识别服务生成视频字幕,并通过TCPlayer播放挂载字幕的视频。适用于短视频制作场景,详细阐述了从初始化SDK、创建语音识别任务到获取字幕文件的步骤,以及如何在TCPlayer中设置和播放带字幕的视频。
摘要由CSDN通过智能技术生成

概览

本文将介绍如何使用腾讯云COS SDK调用数据万象的语音识别 能力生成视频字幕文件,并使用腾讯云点播超级播放器(TCPlayer) 播放挂载了字幕的视频。

业务场景

适用于短视频制作时,原始视频无字幕,需要自动识别视频语音内容并生成字幕的场景。可应用于 PGC/UGC 平台、视频网站、短视频应用、资讯平台等对媒体内容制作有较高智能化和时效性需求的行业。

准备工作

已创建和绑定存储桶,详情请参见 存储桶操作

已 开通语音识别 功能。

上传视频文件

在页面中引入 腾讯云COS SDK 与 TCPlayer 相关脚本文件:

<!--播放器样式文件-->

<link href="https://web.sdk.qcloud.com/player/tcplayer/release/v4.6.0/tcplayer.min.css" rel="stylesheet" />

<!--播放器脚本文件-->

<script src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.6.0/tcplayer.v4.6.0.min.js"></script>

<!--COS SDK-->

<script src="https://cdn.jsdelivr.net/npm/cos-js-sdk-v5/dist/cos-js-sdk-v5.min.js"></script>

设置播放器容器节点: 在需要展示播放器的页面位置加入播放器容器。例如,在 index.html 中加入如下代码(容器 ID 以及宽高都可以自定义)。

<video id="player-container" width="414" height="270" preload="auto" playsinline webkit-playsinline></video>

生成字幕文件步骤

步骤 1:初始化 腾讯云COS SDK 并配置相关信息

// 密钥请在访问管理控制台获取。

const cos = new COS({

SecretId: 'AKID*******',

SecretKey: '**********',

});

步骤 2:创建语音识别任务

构造提交语音识别任务接口并发起请求 请求参数

// 存储桶配置请在 cos 控制台获取。

// 格式参考:Bucket: 'abc-1250000000', Region: 'ap-shanghai'

const config = {

// 需要替换成您自己的存储桶信息

Bucket: '***-125********' /* 存储桶,必须 */,

Region: '**-*****' /* 存储桶所在地域,必须字段 */,

FileName: 'demo.mp4' /* 文件名 */,

};

//需在地址前拼接/asr_jobs,即:`https://<BucketName-APPID>.ci.<Region>.myqcloud.com/

const host = config.Bucket + '.ci.' + config.Region + '.myqcloud.com';

const url = 'https://' + host + '/asr_jobs';

//使用 cos sdk 发起语音识别任务请求

const body = COS.util.json2xml({

Request: {

Tag: 'SpeechRecognition' /* 创建任务的 Tag:SpeechRecognition ,必须*/,

Input: {

Object:config.FileName /* 需要语音识别的视频文件,存储桶里的路径 */,

},

Operation: {

SpeechRecognition: {

EngineModelType: '16k_zh_video' /* 引擎模型类型:16k 音视频领域 ,必须 */,

ChannelNum: 1 /* 语音声道数,必须 */,

ResTextFormat: 1 /* 识别结果返回形式,必须 */,

OutputFileType: 'srt',

},

Output: {

Bucket: config.Bucket /* 存储结果的存储桶 ,必须 */,

Region: config.Region /* 存储结果存储桶地域 ,必须 */,

Object: `demo.srt` /* 结果文件的名称 ,必须 */,

},

},

QueueId: '******************' /* 任务所在的队列 ID ,必须 */,

},

});

cos.request(

{

Bucket: config.Bucket,

Region: config.Region,

Method: 'POST',

Url: url,

Key: '/asr_jobs' /** 固定值,必须 */,

ContentType: 'application/xml' /** 固定值,必须 */,

Body: body,

},

(err, data) => {

console.log(err || data);

}

);

请求方式为 POST,Content-Type 为 application/xml,Tag 为 SpeechRecognition 语音识别,Input.Object 为 准备工作中上传的 视频文件,Operation.Output 为结果输出地址可以填准备工作中创建的存储桶,需要注意 Output.Object 文件名称后缀名应为 .srt 格式,Operation.SpeechRecognition 为语音识别配置参数。

接口响应参数,JobsDetail 节点下为下面 获取提语音识别任务接口接口响应 任务信息。其中 JobId 为关键信息,下面 构造查询语音识别任务链接 会用到。

步骤 3:获取字幕文件

查询语音识别任务执行是否完成,获取字幕文件

// 存储桶配置请在 cos 控制台获取。

// 格式参考:Bucket: 'abc-1250000000', Region: 'ap-shanghai'

const config = {

// 需要替换成您自己的存储桶信息

Bucket: '***-125********' /* 存储桶,必须 */,

Region: '**-*****' /* 存储桶所在地域,必须字段 */,

FileName: 'demo.srt' /* 文件名 */,

};

// 需在对象地址前面拼接 ai_jobs/<jobId>,即:`https://<BucketName-APPID>.ci.<Region>.myqcloud.com/ai_jobs/<jobId>`

// jobId 即为刚刚创建的任务 ID

const host = config.Bucket + '.ci.' + config.Region + '.myqcloud.com';

const url = 'https://' + host + '/asr_jobs/' + JobId;

cos.request(

{

Bucket: config.Bucket,

Region: config.Region,

Method: 'GET',

Url: url,

Key: '/asr_jobs/' + JobId /** 固定值,必须 */,

ContentType: 'application/xml' /** 固定值,必须 */,

},

(err, data) => {

if (err) {

// 语音识别任务查询失败,请在 console 查看报错信息;

console.log(JSON.stringify(err));

return;

}

const resp = data.Response || {};

//判断语音识别任务是否执行中

if (resp.JobsDetail.State !== 'Success') {

console.log('...语音识别任务执行中');

return;

}

//任务执行完成 字幕文件地址为

const srtUrl = `https://${config.Bucket}.cos.${config.Region}.myqcloud.com/${config.FileName}`;

}

);

返回体 Content-Type 为 application/xml,其中 State 为 Success 代表已经完成语音识别,读取到通过语音识别的字幕文件地址为 https://${Operation.Output.Bucket}.cos.${Operation.Output.Region}.myqcloud.com/${Operation.Output.Object}。

注意:

        目前腾讯云有COS特惠活动,新人1元起

使用 TCPlayer 播放挂载了字幕的视频

1. 获取上面 准备工作 创建的视频文件地址: https://&lt;BucketName-APPID&gt;.cos.&lt;Region&gt;.myqcloud.com/xxx.mp4

2. 获取上面 生成字幕文件 创建的字幕文件地址: https://&lt;BucketName-APPID&gt;.cos.&lt;Region&gt;.myqcloud.com/xxx.srt

3. 初始化播放器,并设置视频地址和字幕文件:

// TODO: 使用 Web 播放器时,为获取更佳的兼容性,可将普通 srt 格式字幕文件转换为 webvtt 格式

const getWebvvtUrl = url => {

return fetch(url)

.then(response => response.text())

.then(text => {

const arr = text.split('\n');

text = arr.slice(0, arr.length - 4).join('\n');

const vvtText = 'WEBVTT\n' + '\n' + text.replace(/,/g, '.') + '\n';

console.log(vvtText);

return URL.createObjectURL(new Blob([vvtText]));

});

};

// srt 文件格式转 webvvt 格式,非必须,TCPlayer 播放器字幕文件暂只支持 webvvt 格式

const webvvtUrl = await getWebvvtUrl(`https://<BucketName-APPID>.cos.<Region>.myqcloud.com/xxx.srt`);

// 初始化播放并设置播放地址及字幕文件

const Player = TCPlayer('player-container', {});

Player.src(`https://<BucketName-APPID>.cos.<Region>.myqcloud.com/xxx.mp4`);

Player.on('ready', function () {

// 添加语音识别任务生成的字幕文件

const subTrack = Player.addRemoteTextTrack(

{

src: webvvtUrl, // 字幕文件

kind: 'subtitles',

srclang: 'zh-cn',

label: '中文',

default: 'true',

},

true

);

});

若存在跨域问题,则需要进行存储桶跨域访问 CORS 设置,详情请参见 设置跨域访问 。

若存储桶为私有读写,则对象地址需要携带签名,详情请参见 请求签名 。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于Transformer的语音识别代码,使用PyTorch实现: ```python import torch import torch.nn as nn import torch.nn.functional as F class PositionalEncoding(nn.Module): def __init__(self, d_model, max_seq_len=200): super().__init__() self.d_model = d_model self.pe = torch.zeros(max_seq_len, d_model) position = torch.arange(0, max_seq_len, dtype=torch.float).unsqueeze(1) div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model)) self.pe[:, 0::2] = torch.sin(position * div_term) self.pe[:, 1::2] = torch.cos(position * div_term) self.pe = self.pe.unsqueeze(0) self.register_buffer('pe', self.pe) def forward(self, x): x = x * math.sqrt(self.d_model) seq_len = x.size(1) x = x + self.pe[:, :seq_len] return x class ScaledDotProductAttention(nn.Module): def __init__(self, temperature): super().__init__() self.temperature = temperature def forward(self, q, k, v, mask=None): attention = torch.matmul(q / self.temperature, k.transpose(2, 3)) if mask is not None: attention = attention.masked_fill(mask == 0, -1e9) attention = F.softmax(attention, dim=-1) output = torch.matmul(attention, v) return output, attention class MultiHeadAttention(nn.Module): def __init__(self, d_model, n_head): super().__init__() self.d_model = d_model self.n_head = n_head self.d_k = d_model // n_head self.d_v = d_model // n_head self.w_qs = nn.Linear(d_model, n_head * self.d_k, bias=False) self.w_ks = nn.Linear(d_model, n_head * self.d_k, bias=False) self.w_vs = nn.Linear(d_model, n_head * self.d_v, bias=False) self.attention = ScaledDotProductAttention(temperature=self.d_k ** 0.5) self.fc = nn.Linear(n_head * self.d_v, d_model, bias=False) self.layer_norm = nn.LayerNorm(d_model) def forward(self, q, k, v, mask=None): batch_size = q.size(0) residual = q q = self.w_qs(q).view(batch_size, -1, self.n_head, self.d_k).transpose(1, 2) k = self.w_ks(k).view(batch_size, -1, self.n_head, self.d_k).transpose(1, 2) v = self.w_vs(v).view(batch_size, -1, self.n_head, self.d_v).transpose(1, 2) if mask is not None: mask = mask.unsqueeze(1).repeat(1, self.n_head, 1, 1) output, attention = self.attention(q, k, v, mask=mask) output = output.transpose(1, 2).contiguous().view(batch_size, -1, self.n_head * self.d_v) output = self.fc(output) output = self.layer_norm(output + residual) return output, attention class PositionwiseFeedForward(nn.Module): def __init__(self, d_model, d_ff): super().__init__() self.w_1 = nn.Linear(d_model, d_ff) self.w_2 = nn.Linear(d_ff, d_model) self.layer_norm = nn.LayerNorm(d_model) def forward(self, x): residual = x output = F.relu(self.w_1(x)) output = self.w_2(output) output = self.layer_norm(output + residual) return output class EncoderLayer(nn.Module): def __init__(self, d_model, n_head, d_ff): super().__init__() self.multi_head_attention = MultiHeadAttention(d_model, n_head) self.positionwise_feed_forward = PositionwiseFeedForward(d_model, d_ff) def forward(self, x, mask=None): output, attention = self.multi_head_attention(x, x, x, mask=mask) output = self.positionwise_feed_forward(output) return output, attention class Encoder(nn.Module): def __init__(self, d_model, n_head, d_ff, n_layers): super().__init__() self.layers = nn.ModuleList([EncoderLayer(d_model, n_head, d_ff) for _ in range(n_layers)]) def forward(self, x, mask=None): attentions = [] for layer in self.layers: x, attention = layer(x, mask=mask) attentions.append(attention) return x, attentions class TransformerSpeechRecognizer(nn.Module): def __init__(self, vocab_size, d_model, n_head, d_ff, n_layers, input_dim, dropout=0.1): super().__init__() self.d_model = d_model self.embedding = nn.Sequential( nn.Linear(input_dim, d_model), nn.Dropout(p=dropout), nn.LayerNorm(d_model), nn.ReLU(), PositionalEncoding(d_model) ) self.encoder = Encoder(d_model, n_head, d_ff, n_layers) self.output_layer = nn.Linear(d_model, vocab_size) def forward(self, x, mask=None): x = self.embedding(x) x, attentions = self.encoder(x, mask=mask) x = self.output_layer(x) return x, attentions ``` 这是一个简单的Transformer语音识别模型,包含了Transformer的核心组件:多头自注意力、前馈网络和位置编码。在这个模型中,输入的音频信号首先通过一个线性层和位置编码层进行编码,然后传入多个Encoder层进行特征提取,最后经过一个线性输出层得到最终的识别结果。其中,每个Encoder层包含了一个多头自注意力和一个前馈网络。在训练过程中,我们可以使用交叉熵损失函数对模型进行训练。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值