tencent cloud

Media Processing Service

動向とお知らせ
Release Notes
お知らせ
製品の説明
製品概要
製品の機能
製品の優位性
ユースケース
購入ガイド
課金説明
購入ガイドライン
支払い更新の説明
支払い延滞の説明
返金説明
クイックスタート
コンソールガイド
概要
タスクの作成
タスク管理
編成管理
テンプレート管理
リソースパック管理
動画評価
AIGCコンテンツの生成
ターミナルSDK
字幕編集ツール
使用量統計
CAM例
導入ガイド
音声・動画トランスコードの導入
1 音声・動画エンハンスメントの導入
Audio Separation Integration
電子透かしと可視透かしの導入
メディアAI 導入ガイド
メディア品質検査の導入
クライアントサイドSDKの導入
ライブストリームの録画機能の導入
DRMの導入
その他の導入ガイド
シナリオ実践チュートリアル
画質向上シナリオ
音声・動画コスト最適化シナリオ
ショートドラマの海外展開シナリオ
コンテンツ生成シナリオ
オンライン教育シナリオ
よくある質問
製品の基本情報について
アカウントへの権限付与について
タスク設定について
タスク開始について
タスク結果の確認について
Related Agreement
Service Level Agreement
プライバシーポリシー
データ処理とセキュリティ契約

スマート字幕の導入

PDF
フォーカスモード
フォントサイズ
最終更新日: 2026-03-17 17:17:27

スマート字幕の概要

スマート字幕機能は、オフラインの音声・動画ファイルおよびライブストリーミングの処理に対応しており、音声認識(ASR)または文字認識(OCR)を通じて動画のソース言語字幕を抽出し、多言語翻訳を実現します。また、字幕ファイルに対する大規模言語モデルを用いたテキスト翻訳もサポートしています。さらに、音声認識とLLM翻訳の精度を向上させるため、ホットワード辞書や用語集の設定も可能です。
スマート字幕機能
説明
対応する入力タイプ
音声認識(ASR)による字幕生成
ASRにより、対話音声を字幕ファイルに変換し、大規模言語モデルによる翻訳を行います。
音声認識とLLM翻訳の精度を向上させるため、ホットワード辞書や用語集の設定をサポートしています。
字幕を映像へ焼き込むレンダリング処理をサポートしています。
音声ファイル、動画ファイル、ライブストリーミング、リアルタイム音声ストリーム
文字認識(OCR)による字幕生成
OCRにより、画面上の文字を字幕ファイルとして抽出し、大規模言語モデルによる翻訳を行います。
動画ファイル(画面に焼き付け字幕があるもの)
字幕ファイルの翻訳
字幕ファイルを入力とし、LLMを通じて多言語に翻訳し、新しい字幕ファイルを生成します。
字幕ファイル(WebVTT、SRT形式に対応)
上記の機能は、さまざまなタイプのスマート字幕テンプレートを作成することで利用できます。詳細については、スマート字幕テンプレートをご参照ください。

技術の強み

全プラットフォーム対応:オンデマンドファイル、ライブストリーム、インタラクティブな音声・動画の処理をサポート。ライブ配信のリアルタイム同時翻訳字幕は、確定表示モードと逐次表示モードをサポートしており、再生クライアント側の改修は不要で、容易に導入できます。
高精度:大規模モデルによる処理、カスタム単語集・用語集のサポートにより、業界トップクラスの精度を実現します。
豊富な言語対応:数百の言語、複数の方言、および中国語と英語が混在した音声などの認識をサポートします。
スタイルのカスタマイズ:字幕をビデオに焼き込むことをサポートし、字幕のスタイル(フォント、サイズ、色、背景、位置など)はカスタマイズ可能です。ページ側でのカスタムレンダリングもサポートしています。

無料で体験

1. 体験ラボを開き、「スマート字幕」の体験ページに移動します。右側でオンデマンドファイルまたはライブストリームを選択し、元の言語と字幕タイプを選んで、処理を開始をクリックします。
2. 処理が完了すると、結果を確認できます。
説明:
体験ラボの機能は限定的であり、基本的な効果を体験するためのものです。完全な機能をテストするには、API経由で導入してください。


シナリオ1:オフラインファイルの処理

方法1:コンソールからノーコードタスクを開始

手動でタスクを開始

MPSコンソールにログインし、タスク作成 > オンデマンド処理タスクをクイック作成をクリックします。

1. 入力ファイルの指定
Tencent Cloud COSバケット内のビデオファイルを選択するか、ビデオのダウンロードURLを指定できます。現在、字幕生成および翻訳機能では、AWS S3を入力ソースとして使用することはサポートされていません。
2. 入力ファイルの処理
ワークフローを作成を選択し、「スマート字幕」ノードを挿入します。

システムのプリセットテンプレートを選択するか、カスタムパラメータを使用できます。詳細なテンプレート設定ガイドについては、スマート字幕テンプレートをご参照ください。

3. 出力パスの指定
出力ファイルの保存パスを指定します。
4. タスクの開始
作成をクリックし、タスクを開始します。

ワークフローによるタスクの自動実行(任意)

COSバケットにビデオファイルをアップロードした際に、プリセットのパラメータに従って自動的にスマート字幕処理を実行させたい場合は、以下の手順で設定できます。
1. オンデマンドワークフローメニューに移動し、オンデマンドサービスワークフローを作成をクリックします。タスク設定でスマート字幕ノードを選択し、トリガーとなるBucketやディレクトリなどのパラメータを設定します。

2. 作成後、オンデマンドワークフローリストに移動し、作成したワークフローを見つけ、起動のスイッチをオンにします。以降、トリガーディレクトリに新しいビデオファイルが追加されると、このワークフローでプリセットされたフローとパラメータに従って自動的にタスクが開始され、処理後のビデオファイルが設定された出力パスに保存されます。
注意:
ワークフローを有効にした後、設定が反映されるまで3~5分かかります。


方法2:APIインターフェースの呼び出し

ProcessMedia APIを呼び出し、テンプレートIDを指定してタスクを開始します。例:
{
"InputInfo": {
"Type": "URL",
"UrlInputInfo": {
"Url": "https://test-1234567.cos.ap-guangzhou.myqcloud.com/video/test.mp4" // 処理したいビデオのURLに置き換えてください
}
},
"SmartSubtitlesTask": {
"Definition": 122 // 122はプリセットの「中国ソース→中英字幕生成」テンプレートIDです。ご自身のカスタムスマート字幕テンプレートIDに置き換え可能です
"UserExtPara": "" //拡張パラメータ
},
"OutputStorage": {
"CosOutputStorage": {
"Bucket": "test-1234567",
"Region": "ap-guangzhou"
},
"Type": "COS"
},
"OutputDir": "/output/",
"Action": "ProcessMedia",
"Version": "2019-06-12"
}
コンソールでワークフローを作成している場合は、ProcessMedia APIを呼び出し、ワークフローIDを指定してタスクを開始することもできます。例:
{
"InputInfo": {
"Type": "COS",
"CosInputInfo": {
"Bucket": "facedetectioncos-125*****11",
"Region": "ap-guangzhou",
"Object": "/video/123.mp4"
}
},
"ScheduleId": 12345, //カスタムワークフローIDに置き換えてください。12345は単なる例であり、実際の意味はありません
"Action": "ProcessMedia",
"Version": "2019-06-12"
}
説明:
コールバックURLが設定されている場合、レスポンスの詳細はイベント通知の解析ドキュメントをご参照ください。

拡張パラメータによる機能のカスタマイズ

スマート字幕では、拡張パラメータUserExtParaを使用してさまざまな機能をカスタマイズできます。拡張パラメータはシリアライズされたJSON文字列です。サポートされている拡張パラメータの一覧は以下のとおりです。
パラメータ名
パラメータタイプ
機能の説明
参考値
need_wordlist
int
単語のタイムスタンプを返すかどうかを指定します(一部のテンプレートは非対応のため返されません)。デフォルトでは返されません。
1:単語のタイムスタンプを返します。
1
accurate_mode
int
精確モードを有効にするかどうかを指定します。精確モードはオプション機能で、より精度の高いタイムスタンプを提供します。デフォルトでは無効です。
1:精確モードを有効にします。
1
adapt_words
string
ホットワードのテキストです。具体的なフォーマットについては、
をご参照ください。ホットワードは不確定なシナリオに適しており、リクエストごとにカスタマイズ可能です。指定できるホットワードの数は128個以内です。
Tencent Cloud|10,メディア処理|10
上記の機能は特別な記載がない限り、同時に有効にすることができます。

字幕をビデオに焼き込む(オプション機能)

ProcessMedia APIを呼び出し、トランスコードタスクを開始し、SubtitleTemplateフィールドで字幕のvttファイルパスと焼き込みスタイルを指定します。以下にパラメータの渡し方の例を示します。コンソールでのタスク開始方法や字幕スタイルなどの詳細については、音声・動画トランスコードの導入 - 字幕の焼き込みをご参照ください。
{
"MediaProcessTask": {
"TranscodeTaskSet": [
{
"Definition": 100040, //トランスコードテンプレートID。必要なテンプレートIDに置き換えてください
"OverrideParameter": { //パラメータの上書き。トランスコードテンプレート内の一部パラメータを柔軟に上書きできます
"SubtitleTemplate": { //字幕焼き込み設定
"Path": "https://test-1234567.cos.ap-nanjing.myqcloud.com/mps_autotest/subtitle/1.vtt",
"StreamIndex": 2,
"FontType": "simkai.ttf",
"FontSize": "10px",
"FontColor": "0xFFFFFF",
"FontAlpha": 0.9
}
}
}
]
},
"InputInfo": { //入力情報
"Type": "URL",
"UrlInputInfo": {
"Url": "https://test-1234567.cos.ap-nanjing.myqcloud.com/mps_autotest/subtitle/123.mkv"
}
},
"OutputStorage": { //出力バケット
"Type": "COS",
"CosOutputStorage": {
"Bucket": "test-1234567",
"Region": "ap-nanjing"
}
},
"OutputDir": "/mps_autotest/output2/", //出力パス
"Action": "ProcessMedia",
"Version": "2019-06-12"
}

タスク結果の照会

コンソールでのタスク照会

1. コンソールのオンデマンドタスク管理に移動すると、タスクリストに開始したばかりのタスクが表示されます。

2. サブタスクのステータスが「成功」になったら、結果を表示をクリックすると、字幕のスタイルをプレビューできます。

3. 生成されたVTT字幕ファイルは、ワークフロー管理 > COS Bucket > 出力Bucketで確認できます。

中国語字幕の例:



中国語・英語字幕の例:




イベント通知コールバック

ProcessMediaからメディア処理タスクを開始する際、TaskNotifyConfigパラメータでイベントコールバックを設定できます。タスク処理が完了すると、設定されたコールバック情報を通じてタスク結果が通知されます。ParseNotificationを使用してイベント通知結果を解析できます。

API呼び出しによるタスク結果の照会

DescribeTaskDetailインターフェースを呼び出し、タスクID(例:24000022-WorkflowTask-b20a8exxxxxxx1tt110253、24000022-ScheduleTask-774f101xxxxxxx1tt110253)を入力してタスク結果を照会します。例は以下の通りです。


シナリオ2:ライブストリーム

ライブストリームで字幕および翻訳を利用するには、現在2つの方法があります:CSSコンソールで字幕機能を有効にする方法と、MPSからのテキストコールバックを利用してライブストリームに焼き込む方法です。CSSコンソールで字幕機能を有効にする方法を推奨します。各方法の説明は以下の通りです。

方法1:ライブ配信コンソールで字幕機能を有効にする

1. ライブ配信字幕機能の設定
1.1 CSSMPSを有効にします。
1.2 CSSコンソールにログインし、字幕テンプレートを作成してトランスコードテンプレートをバインドします。
2. 字幕付きストリームのプル
トランスコードストリーム(対応するライブストリームのStreamNameの後ろに、字幕テンプレートをバインドしたトランスコード名_トランスコードテンプレート名を追加して生成したストリームアドレス)をプルすると、字幕が表示されます。再生URLの結合ルールについては、再生URLの結合をご参照ください。
説明:
現在、字幕の表示形式は2種類あります:リアルタイム逐次表示字幕と遅延確定表示字幕。リアルタイム逐次表示字幕は、ライブ配信中の音声内容に応じて字幕が逐次動的に修正され、出力内容がリアルタイムに変動します。遅延確定表示字幕は、システムが設定された時間だけ遅延して、完全な一文として字幕を表示するため、視聴体験が向上します。

方法2:MPSによるテキストコールバック

現在、MPSコンソールからライブストリームのスマート字幕タスクを開始することはサポートされていません。API経由で開始する必要があります。
使用例は以下の通りです。詳細なAPIドキュメントはライブストリーム処理を、リアルタイムコールバックの内容はライブストリーム処理結果の解析をご参照ください。
注意:
MPSでライブストリームを処理する場合、現在はスマート認識テンプレートを使用し、音声認識または音声翻訳機能を設定して実装する必要があります。
{
"Url": "http://5000-wenzhen.liveplay.myqcloud.com/live/123.flv",
"AiRecognitionTask": {
"Definition": 10101 //10101はプリセットの中国語字幕テンプレートIDです。ご自身のカスタムスマート認識テンプレートIDに置き換え可能です
},
"OutputStorage": {
"CosOutputStorage": {
"Bucket": "6c0f30dfvodgzp*****0800-10****53",
"Region": "ap-guangzhou"
},
"Type": "COS"
},
"OutputDir": "/6c0f30dfvodgzp*****0800/0d1409d3456551**********652/",
"TaskNotifyConfig": {
"NotifyType": "URL",
"NotifyUrl": "http://****.qq.com/callback/qtatest/?token=*****"
},
"Action": "ProcessLiveStream",
"Version": "2019-06-12"
}

シナリオ3:WebSocketによるプライベート音声ストリームの処理

ビデオ会議やフルデュプレックス音声対話などのシナリオにおいて、WebSocketプロトコルを通じて音声を認識・翻訳サービスへ送信し、その結果をWebSocketプロトコル経由で受け取ることができます。単一認識、認識および翻訳、マルチチャンネルリアルタイム音声ストリームの同時認識・翻訳、リアルタイム結果字幕の確定モードおよび漸次変化モードに対応しています。プロトコルの詳細はWebSocket認識プロトコルをご参照ください。
コードサンプル:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import argparse
import struct
import time
import os
import signal
import sys
import hashlib
import hmac
import random
from urllib.parse import urlencode, urlunsplit, quote
import websockets
import asyncio
import logging
import json

# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class AudioPacket:
def __init__(self, format=1, is_end=False, timestamp=0, audio_src_id="123456", ext_data=b'', data=b''):
self.format = format
self.is_end = is_end
self.timestamp = timestamp
self.audio_src_id = audio_src_id
self.ext_data = ext_data
self.data = data

def marshal(self):
"""Serialize audio packet to binary format"""
header = struct.pack(
'>BBQH',
self.format,
1 if self.is_end else 0,
self.timestamp,
len(self.audio_src_id)
)
audio_src_bytes = self.audio_src_id.encode('utf-8')
ext_len = struct.pack('>H', len(self.ext_data))
return header + audio_src_bytes + ext_len + self.ext_data + self.data

def sha256hex(s):
"""Calculate SHA256 hex digest"""
if isinstance(s, str):
s = s.encode('utf-8')
return hashlib.sha256(s).hexdigest()

def hmacsha256(s, key):
"""Calculate HMAC-SHA256"""
if isinstance(s, str):
s = s.encode('utf-8')
if isinstance(key, str):
key = key.encode('utf-8')
return hmac.new(key, s, hashlib.sha256).digest()

def generate_random_number(digits):
"""Generate random number with specified digits"""
low = 10 ** (digits - 1)
high = (10 ** digits) - 1
return random.randint(low, high)

def generate_url_v3(args):
"""Generate WebSocket URL with TC3-HMAC-SHA256 signature"""
query_params = {}
if args.dstLang:
query_params["transSrc"] = args.lang
query_params["transDst"] = args.dstLang
else:
query_params["asrDst"] = args.lang
query_params["fragmentNotify"] = "1" if args.frame else "0"
query_params["timeoutSec"] = str(args.timeout)
timestamp = int(time.time())
expire_timestamp = timestamp + 3600
query_params["timeStamp"] = str(timestamp)
query_params["expired"] = str(expire_timestamp)
query_params["secretId"] = args.secretId
query_params["nonce"] = str(generate_random_number(10))
# Sort keys and build canonical query string
sorted_keys = sorted(query_params.keys())
canonical_query = "&".join(
["{}={}".format(k, quote(query_params[k], safe=''))
for k in sorted_keys]
)
# Build canonical request
path = "/wss/v1/{}".format(args.appid)
http_method = "post"
canonical_uri = path
canonical_headers = "content-type:application/json; charset=utf-8\\nhost:{}\\n".format(args.addr)
signed_headers = "content-type;host"
canonical_request = "{}\\n{}\\n{}\\n{}\\n{}\\n".format(
http_method,
canonical_uri,
canonical_query,
canonical_headers,
signed_headers,
)
# Build string to sign
date = time.strftime("%Y-%m-%d", time.gmtime(timestamp))
credential_scope = "{}/mps/tc3_request".format(date)
hashed_canonical = sha256hex(canonical_request)
algorithm = "TC3-HMAC-SHA256"
string_to_sign = "{}\\n{}\\n{}\\n{}".format(
algorithm,
timestamp,
credential_scope,
hashed_canonical
)
# Calculate signature
secret_date = hmacsha256(date, "TC3" + args.secretKey)
secret_service = hmacsha256("mps", secret_date)
secret_signing = hmacsha256("tc3_request", secret_service)
signature = hmac.new(
secret_signing,
string_to_sign.encode('utf-8'),
hashlib.sha256
).hexdigest()
# Add signature to query params
query_params["signature"] = signature
# Build final URL
scheme = "wss" if args.ssl else "ws"
url = urlunsplit((
scheme,
args.addr,
path,
urlencode(query_params),
""
))
return url

async def receive_messages(websocket, stop_event):
"""Handle incoming WebSocket messages"""
try:
while not stop_event.is_set():
message = await websocket.recv()
if isinstance(message, bytes):
try:
message = message.decode('utf-8')
except UnicodeDecodeError:
message = str(message)
logger.info("Received: %s", message)
except Exception as e:
logger.info("Connection closed: %s", e)

async def run_client():
parser = argparse.ArgumentParser()
parser.add_argument("--addr", default="mps.cloud.tencent.com", help="websocket service address")
parser.add_argument("--file", default="./wx_voice.pcm", help="pcm file path")
parser.add_argument("--appid", default="121313131", help="app id")
parser.add_argument("--lang", default="zh", help="language")
parser.add_argument("--dstLang", default="", help="destination language")
parser.add_argument("--frame", action="store_true", help="enable frame notify")
parser.add_argument("--secretId", default="123456", help="secret id")
parser.add_argument("--secretKey", default="123456", help="secret key")
parser.add_argument("--ssl", action="store_true", help="use SSL")
parser.add_argument("--timeout", type=int, default=10, help="timeout seconds")
parser.add_argument("--wait", type=int, default=700, help="wait seconds after end")
args = parser.parse_args()

url = generate_url_v3(args)
logger.info("Connecting to %s", url)

try:
# Python 3.6 compatible websockets connection
websocket = await websockets.connect(url, ping_timeout=5)

# Handle initial response
initial_msg = await websocket.recv()
try:
result = json.loads(initial_msg)
if result.get("Code", 0) != 0:
logger.error("Handshake failed: %s", result.get("Message", ""))
return
logger.info("TaskId %s handshake success", result.get("TaskId", ""))
except ValueError: # json.JSONDecodeError not available in 3.6
logger.error("Invalid initial message")
return

# Setup signal handler
loop = asyncio.get_event_loop()
stop_event = asyncio.Event()
loop.add_signal_handler(signal.SIGINT, stop_event.set)

# Start receiver
receiver_task = asyncio.ensure_future(receive_messages(websocket, stop_event))

# Audio processing
try:
with open(args.file, "rb") as fd:
PCM_DUR_MS = 40
pcm = bytearray(PCM_DUR_MS * 32)
pkt = AudioPacket(data=pcm)
is_end = False
wait_until = 0

while not stop_event.is_set():
if is_end:
if time.time() > wait_until:
logger.info("Finish")
break
await asyncio.sleep(0.1)
continue

# Read PCM data
n = fd.readinto(pkt.data)
if n < len(pkt.data):
pkt.is_end = True
is_end = True
wait_until = time.time() + args.wait

# Send audio packet
await websocket.send(pkt.marshal())
logger.info("Sent ts %d", pkt.timestamp)
pkt.timestamp += n // 32

await asyncio.sleep(PCM_DUR_MS / 1000)

except IOError: # FileNotFoundError not available in 3.6
logger.error("Open file error: %s", args.file)
return

# Cleanup
await asyncio.wait_for(receiver_task, timeout=1)
await websocket.close()

except Exception as e:
logger.error("Connection error: %s", e)
return

if __name__ == "__main__":
# Python 3.6 compatible asyncio runner
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(run_client())
finally:
loop.close()



よくあるご質問

スマート字幕で対応できる言語

言語に関する説明については、スマート字幕テンプレートドキュメントをご参照ください。

スマート字幕の料金について

後払いに対応しています。詳細は料金説明ドキュメントをご参照ください。

ヘルプとサポート

この記事はお役に立ちましたか?

フィードバック