接口描述
音视频翻译API集成文字识别、智能断句、机器翻译等先进技术,可实现对音视频“听译转写-文字识别-智能断句-打轴-翻译”的一站式处理。音视频翻译API的调用分为“提交任务”和“查询结果”两步。
接口限制
- 支持语向:可在语言支持列表中查看音视频翻译支持的的源语言及目标语言。
- 音视频参数要求:
- 视频 / 音频格式:推荐mp3、mp4、wav、ogg格式
- 视频 / 音频大小限制:不超过512MB
- 视频 / 音频时长限制:不超过240分钟
- 支持由用户预先将视频中的音频文件抽出上传
接口说明
Step1 提交任务
字段 | 类型 | 是否为必须项 | 说明 | 备注 |
---|
SourceLanguage | String | 是 | 源语言 | 支持 en, zh, ko |
TargetLanguage | String | 是 | 目标语言 | 支持 en, zh, ko, ja, pt, fr, de, es |
Uri | String | 是 | 待翻译的视频/音频文件链接 | 建议配合视频点播使用,避免服务端下载视频失败 |
字段 | 类型 | 说明 | 备注 |
---|
ResponseMetadata | ResponseMetadata | 通用字段 | 无 |
TaskId | String | 任务ID | 无 |
- 样例
{
"SourceLanguage": "en",
"TargetLanguage": "zh",
"Uri": "http://xx/xx.mp4"
}
{
"TaskId": "asdasda",
"ResponseMetadata": {
"RequestId": "202004092306480100140440781F5D7119",
"Action": "SubmitAudio",
"Version": "2020-06-01",
"Service": "translate",
"Region": "cn-north-1",
"Error": null
}
}
Step2 查询结果
字段 | 类型 | 是否为必须项 | 说明 | 备注 |
---|
TaskId | String | 是 | 任务ID | 无 |
字段 | 类型 | 说明 | 备注 |
---|
ResponseMetadata | ResponseMetadata | 通用字段 | 无 |
Subtitles | [Subtitle] | 包含时间信息、识别文本、翻译文本等信息的结果列表 | Subtitles 列表内具体字段信息见下表 |
Status | String | 任务状态 | Status 的字段信息见下表 |
Subtitle:
字段 | 类型 | 说明 | 备注 |
---|
StartTime | Int | 单句识别的开始时间 | 无 |
EndTime | Int | 单句识别的结束时间 | 无 |
Text | String | 单句识别内容 | 无 |
Translation | String | 单句翻译结果 | 无 |
Status:
status | 说明 |
---|
created | 任务已创建,正在排队 |
download_failed | 视频/音频文件下载失败 |
asr_failed | 视频中的音频/音频文件内容识别失败 |
translate_failed | 机器翻译失败 |
save_failed | 保存结果失败 |
failed | 其他原因失败 |
success | 成功 |
- 样例
{
"TaskId": "asdasda"
}
{
"Subtitles": [
{
"StartTime": 0,
"EndTime": 1000,
"Text": "Hello",
"Translation": "你好"
}
],
"Status": "success",
"ResponseMetadata": {
"RequestId": "202004092306480100140440781F5D7119",
"Action": "QueryAudio",
"Version": "2020-06-01",
"Service": "translate",
"Region": "cn-north-1",
"Error": null
}
}
示例代码
依赖 volc-sdk-python
import json
import time
from volcengine.ApiInfo import ApiInfo
from volcengine.Credentials import Credentials
from volcengine.ServiceInfo import ServiceInfo
from volcengine.base.Service import Service
k_access_key = '密钥管理中的 AccessKey ID' # https://console.volcengine.com/iam/keymanage/
k_secret_key = '密钥管理中的 AccessKey Secret'
k_timeout = 5 # second
k_service_info = \
ServiceInfo('open.volcengineapi.com',
{'Content-Type': 'application/json'},
Credentials(k_access_key, k_secret_key, 'translate', 'cn-north-1'),
5,
5)
k_api_info = {
'submit_audio': ApiInfo('POST', '/', {
'Action': 'SubmitAudio',
'Version': '2020-06-01'
}, {}, {}),
'query_audio': ApiInfo('POST', '/', {
'Action': 'QueryAudio',
'Version': '2020-06-01'
}, {}, {}),
}
service = Service(k_service_info, k_api_info)
# 提交任务
submit_body = {
'SourceLanguage': 'en',
'TargetLanguage': 'zh',
'Uri': "http://xx/xx.mp4",
}
submit_result = json.loads(service.json('submit_audio', {}, json.dumps(submit_body)))
task_id = submit_result["TaskId"]
print(task_id)
# 查询任务
status = "created"
while status == "created":
time.sleep(60)
query_body = {
'TaskId': task_id,
}
query_result = json.loads(service.json('query_audio', {}, json.dumps(query_body)))
status = query_result["Status"]
print(status)
if status == "success":
for subtitle in query_result["Subtitles"]:
print("{} - {}: {} -> {}".format(subtitle["StartTime"],
subtitle["EndTime"],
subtitle["Text"],
subtitle["Translation"]))
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/volcengine/volc-sdk-golang/base"
)
const (
kAccessKey = "密钥管理中的 AccessKey ID" // https://console.volcengine.com/iam/keymanage/
kSecretKey = "密钥管理中的 AccessKey Secret"
kServiceVersion = "2020-06-01"
)
var (
ServiceInfo = &base.ServiceInfo{
Timeout: 5 * time.Second,
Host: "open.volcengineapi.com",
Header: http.Header{
"Accept": []string{"application/json"},
},
Credentials: base.Credentials{Region: base.RegionCnNorth1, Service: "translate"},
}
ApiInfoList = map[string]*base.ApiInfo{
"SubmitAudio": {
Method: http.MethodPost,
Path: "/",
Query: url.Values{
"Action": []string{"SubmitAudio"},
"Version": []string{kServiceVersion},
},
},
"QueryAudio": {
Method: http.MethodPost,
Path: "/",
Query: url.Values{
"Action": []string{"QueryAudio"},
"Version": []string{kServiceVersion},
},
},
}
)
func newClient() *base.Client {
client := base.NewClient(ServiceInfo, ApiInfoList)
client.SetAccessKey(kAccessKey)
client.SetSecretKey(kSecretKey)
return client
}
type SubmitReq struct {
SourceLanguage string `json:"SourceLanguage"`
TargetLanguage string `json:"TargetLanguage"`
Uri string `json:"Uri"`
}
type SubmitResp struct {
TaskId string `json:"TaskId"`
ResponseMetadata struct {
RequestId string `json:"RequestId"`
Action string `json:"Action"`
Version string `json:"Version"`
Service string `json:"Service"`
Region string `json:"Region"`
Error interface{} `json:"Error"`
} `json:"ResponseMetadata"`
}
type QueryReq struct {
TaskId string `json:"TaskId"`
}
type QueryResp struct {
Subtitles []struct {
StartTime int `json:"StartTime"`
EndTime int `json:"EndTime"`
Text string `json:"Text"`
Translation string `json:"Translation"`
} `json:"Subtitles"`
Status string `json:"Status"`
ResponseMetadata struct {
RequestId string `json:"RequestId"`
Action string `json:"Action"`
Version string `json:"Version"`
Service string `json:"Service"`
Region string `json:"Region"`
Error interface{} `json:"Error"`
} `json:"ResponseMetadata"`
}
func SubmitAudio(cli *base.Client, uri, sourceLanguage, targetLanguage string) (*SubmitResp, error) {
req := &SubmitReq{
SourceLanguage: sourceLanguage,
TargetLanguage: targetLanguage,
Uri: uri,
}
reqData, err := json.Marshal(req)
if err != nil {
return nil, err
}
respData, code, err := cli.Json("SubmitAudio", nil, string(reqData))
if err != nil {
return nil, err
}
if code != 200 {
return nil, fmt.Errorf("code:%d,err:%s", code, string(respData))
}
resp := &SubmitResp{}
err = json.Unmarshal(respData, resp)
if err != nil {
return nil, err
}
return resp, nil
}
func QueryAudio(cli *base.Client, taskId string) (*QueryResp, error) {
req := &QueryReq{
TaskId: taskId,
}
reqData, err := json.Marshal(req)
if err != nil {
return nil, err
}
respData, code, err := cli.Json("QueryAudio", nil, string(reqData))
if err != nil {
return nil, err
}
if code != 200 {
return nil, fmt.Errorf("code:%d,err:%s", code, string(respData))
}
resp := &QueryResp{}
err = json.Unmarshal(respData, resp)
if err != nil {
return nil, err
}
return resp, nil
}
func main() {
cli := newClient()
submitResp, err := SubmitAudio(cli, "http://xx/xx.mp4", "en", "zh")
if err != nil {
panic(err)
}
status := "created"
for status == "created" {
time.Sleep(time.Minute)
queryResp, err := QueryAudio(cli, submitResp.TaskId)
if err != nil {
panic(err)
}
status = queryResp.Status
if status == "success" {
for _, subtitle := range queryResp.Subtitles {
fmt.Printf("%d - %d: %s -> %s", subtitle.StartTime, subtitle.EndTime, subtitle.Text, subtitle.Translation)
}
}
}
}
// 提交任务,获取任务ID
TranslateAudioSubmitRequest translateAudioSubmitRequest = new TranslateAudioSubmitRequest();
translateAudioSubmitRequest.setSourceLanguage("en");
translateAudioSubmitRequest.setTargetLanguage("zh");
translateAudioSubmitRequest.setUri("http://xx/xx.mp4");
TranslateAudioSubmitResponse translateAudioSubmitResponse = translateService.translateAudioSubmit(translateAudioSubmitRequest);
System.out.println(JSON.toJSONString(translateAudioSubmitResponse));
// 等待任务完成
Thread.sleep(5000); // 视频时长*0.3
// 查询结果
TranslateAudioQueryRequest translateAudioQueryRequest = new TranslateAudioQueryRequest();
translateAudioQueryRequest.setTaskId(translateAudioSubmitResponse.getTaskId());
TranslateAudioQueryResponse translateAudioQueryResponse = translateService.translateAudioQuery(translateAudioQueryRequest);
System.out.println(JSON.toJSONString(translateAudioQueryResponse));