You need to enable JavaScript to run this app.
導航

數位分身&聲音復刻訓練API介面文檔

最近更新時間2023.09.25 10:44:33

首次發佈時間2023.08.11 17:43:01

製作分身

製作一個分身形象的完整流程如下:
step1:上傳製作形象所需的視頻素材
step2:視頻素材上傳完成後,調用觸發形象製作接口,開始形象製作
step3:調用分身形象製作信息查詢接口,查詢形象製作狀態

說明:
1、完整上傳一個視訊呼叫介面流程如下:建立分片上傳任務--> 順序上傳檔案分片--> 完成檔案分片上傳
2、conf_name欄位是形象的唯一標識,由客戶自己定義,後續使用sta等服務時,需要傳遞該值來表明調用哪個形象格式要求:允許大小寫字母數字以及'-'
3、input_resource字段為必傳字段,用於表明資料來源,建議填寫公司名稱

分身形象製作需提供以下影片素材:

  • 訓練影片:允許格式1080p/4K mp4/mov

針對在控制台下單的數字人資產,在呼叫訓練介面時:

  • 數字分身:形象id填入conf_name
  • 聲音復刻:聲音id填入voice_type

1、建立分片上傳任務POST

path:/init_part_upload
參數:json

{
    "conf_name": "LiuXuan",    //string 必传 用户上传形象调用conf_name,格式要求:允许大小写字母数字以及'-' 
    "role_show_name": "刘璇",   //string 必传 用户上传形象展示中文名
    "type": 1,   //int 必传  视频类型1:训练视频 2:模版视频 3:审核视频
    "input_resource": "",  //string 必传 视频上传来源,建议填写公司名称
    "appid": "xxxx",  //string 必传 appid
    "file_suffix": "mp4" //string 必传 视频格式尾缀 mp4或mov
}

標題:

headers = {'Content-Type': 'application/json', 'Authorization': token}

返回:

{
    "errno": 0,
    "errMsg": "success",
    "data": {
        "upload_id": "48501f0206918d1b5db63714" // 返回upload_id,用于标识此次分片上传任务
    }
}

2、上傳文件分片POST

說明:建議分片大小為10M,最後一片不足5M的與前一分片合併上傳
path:/video_part_upload
參數:json

{
        "conf_name": conf_name,  // string 必传 用户上传形象调用conf_name,格式要求:允许大小写字母数字以及'-'
        "type": video_type,   //int 必传  视频类型1:训练视频 2:模版视频 3:审核视频
        "upload_id": upload_id, //string 必传  init_part_upload接口返回的upload_id
        "file_suffix": "mp4", //string 必传 视频格式尾缀 mp4或mov
        "part_num": 1,  //int 必传  分片顺序:1,2,3,4... 要求第一个分片必须从1开始
        "content": "base64", //string 必传 分片内容,base64字符串
        "appid": "xxxx",  //string 必传 appid
}

標題:

headers = {'Content-Type': 'application/json', 'Authorization': token}

返回:

{
    "errno": 0,
    "errMsg": "success",
    "data": "video part upload success"
}

3、完成文件分片上傳POST

path:/video_complete_upload
參數:json

{
        "conf_name": conf_name,  // string 必传 用户上传形象调用conf_name,格式要求:允许大小写字母数字以及'-'
        "type": video_type,  //int 必传 视频类型1:训练视频 2:模版视频 3:审核视频
        "upload_id": upload_id,  //string 必传 init_part_upload接口返回的upload_id
        "file_suffix": "mp4", //string 必传 视频格式尾缀 mp4或mov
        "appid": "xxxx",  //string 必传 appid
}

標題:

headers = {'Content-Type': 'application/json', 'Authorization': token}

返回:

{
    "errno": 0,
    "errMsg": "success",
    "data": "finish video part upload successs"
}

4.觸發形象製作POST

說明:觸發形象訓練
path:/init_train_digime
參數:json

{
    "appid": "xxx",  //string 必传 appid
    "conf_name": "xxx",  //string 必传 用户上传形象调用conf_name,格式要求:允许大小写字母数字以及'-'
    "callback_url": "http://xxx.net/xx"    // 回调地址,POST,用于接收制作状态回调
}

標題:

headers = {'Content-Type': 'application/json', 'Authorization': token}

返回:

{
    "errno": 0,
    "errMsg": "success",
    "data": "init train digime succ"
}

製作狀態回呼格式如下:

傳遞的URL地址需支援POST method

{
    "conf_name": "xxx",  //string 形象调用conf_name
    "role_pic": "https://xxx.png", //形象图
    "pre_pic": "https://xxx.png", //前景图
    "state": 2     // 2:制作成功,3:制作失败
}

5.分身形象製作資訊查詢POST

說明:透過conf_name查詢分身形象製作狀態資訊
path:/digime_training_info
參數:json

{
    "appid": "xxx",  //string appid
    "conf_name": "xxx"  //string 用户上传形象调用conf_name,格式要求:允许大小写字母数字以及'-'
}

標題:

headers = {'Content-Type': 'application/json', 'Authorization': token}

返回:

{
    "errno": 0,
    "errMsg": "success",
    "data": {
        "conf_name": "xxx",  //string 形象调用conf_name
        "role_pic": "https://xxx.png", //形象图
        "pre_pic": "https://xxx.png", //前景图
        "state": 2 //制作状态 1:制作中,2:制作成功,3:制作失败
    }
}

6、接口地址

正式環境:https://openspeech.bytedance.com/virtual_human/avatar_platform/digime

7、演示

# script/init.py
# coding=utf-8

#####################

import json
import requests
import os
import base64

UPLOAD_URL = "https://openspeech.bytedance.com/virtual_human/avatar_platform/digime"


def check_res(result):
    if result.status_code != 200:
        raise Exception(f"request code is not {result.status_code}")
    # print(result.text)
    res = result.json()
    if res.get("errMsg") != "success" or res.get("errno") != 0:
        msg = res.get("errMsg")
        raise Exception(f"request err, msg: {msg}")
    return res


def post(url, data, token):
    """封装post方法"""
    headers = {'Content-Type': 'application/json', 'Authorization': token}
    result = requests.post(url=url, headers=headers, data=json.dumps(data))
    return check_res(result)


# def post_form(url, filepath, filekey, **kwargs):
#     """封装post方法 body是format data形式"""
#     data = kwargs.get("data")
#     fl = open(filepath, 'rb')
#     files = {
#         filekey: (filepath, fl)
#     }
#     result = requests.post(url, files=files, data=data)
#     print(check_res(result))

""" 按块读取 """


def read_file_by_chunk(file, chunk_size=1024 * 1024 * 10):
    with open(file, mode='rb') as f:
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                return
            yield chunk


def part_upload_file(file_path, conf_name, role_show_name, video_type, input_resource, app_id, token):
    init_data = {
        "conf_name": conf_name,
        "type": video_type,
        "role_show_name": role_show_name,
        "input_resource": input_resource,
        "appid": app_id,
        "file_suffix": file_path[-3:],
    }
    ret = post(UPLOAD_URL + "/init_part_upload", init_data, token)
    upload_id = ret["data"]
    print("upload_id is:", upload_id)

    upload_data = {
        "conf_name": conf_name,
        "type": video_type,
        "upload_id": upload_id,
        "appid": app_id,
        "file_suffix": file_path[-3:],
    }
    part_num = 1
    # 暂存前一个分片
    tmp_content_str = ""
    tmp_bytes = bytes()
    final_deal = True
    chunks = read_file_by_chunk(file_path)
    for chunk in chunks:
        # print("chunk size is:", len(bytes(chunk)))
        if part_num == 1:
            content = base64.b64encode(bytes(chunk))
            tmp_content_str = content.decode()
            tmp_bytes = bytes(chunk)
            part_num += 1
            continue
        if len(bytes(chunk)) >= 5242880:
            # 当前分片长度大于等于5m,上传前一个分片
            upload_data["part_num"] = part_num - 1
            upload_data["content"] = tmp_content_str
            print("upload part:", part_num - 1)
            ret = post(UPLOAD_URL + "/video_part_upload", upload_data, token)
            content = base64.b64encode(bytes(chunk))
            tmp_content_str = content.decode()
            tmp_bytes = bytes(chunk)
        else:
            # print("deal with last partiton merged")
            # 当前分片长度小于5m,与前一个分片合并上传
            # print("tmp_bytes size is:%d, chunk size is:%d", len(tmp_bytes), len(bytes(chunk)))
            content = base64.b64encode(tmp_bytes + bytes(chunk))
            content_str = content.decode()
            upload_data["part_num"] = part_num - 1
            upload_data["content"] = content_str
            print("upload part:", part_num - 1)
            ret = post(UPLOAD_URL + "/video_part_upload", upload_data, token)
            final_deal = False
        part_num += 1
    if final_deal:
        # print("deal with last partiton")
        upload_data["part_num"] = part_num - 1
        upload_data["content"] = tmp_content_str
        print("upload part:", part_num - 1)
        ret = post(UPLOAD_URL + "/video_part_upload", upload_data, token)

    complete_data = {
        "conf_name": conf_name,
        "type": video_type,
        "upload_id": upload_id,
        "appid": app_id,
        "file_suffix": file_path[-3:]
    }
    ret = post(UPLOAD_URL + "/video_complete_upload", complete_data, token)


if __name__ == "__main__":
    print("########begin part upload############")
    part_upload_file("2.mp4", "conf_name", "role_show_name", 1, "input_resource", "appid", "token")


製作音色

製作一個音色的完整流程如下:
step1:上傳製作音色所需音訊素材壓縮包(多條音訊檔案放到一個資料夾下壓縮),格式要求zip或tar

說明:
1、完整上傳一個音訊素材壓縮包呼叫介面流程如下:建立分片上傳任務--> 順序上傳文件分片--> 完成文件分片上傳
2、input_resource字段為必傳字段,用於顯示數據來源,建議填寫公司名稱

1、建立分片上傳任務POST

path:/init_part_upload
參數:json

{
    "conf_name": "",    //string 可选 音色对应分身形象conf_name
    "type": 11,   //int 必传  数据类型 11:音频压缩包数据
    "input_resource": "",  //string 必传 视频上传来源,建议填写公司名称
    "appid": "xxxx",  //string 必传 appid
    "file_suffix": "zip", //string 必传 压缩格式尾缀 zip或tar
    "tts_type": "xxx" //tts_model_v1 30min复刻 tts_model_v2 10min复刻
}

標題:

headers = {'Content-Type': 'application/json', 'Authorization': token}

返回:

{
    "errno": 0,
    "errMsg": "success",
    "data": {
        "upload_id": "48501f0206918d1b5db63714" // 返回upload_id,用于标识此次分片上传任务
    }
}

2、上傳文件分片POST

說明:建議分片大小為10M,最後一片不足5M的與前一分片合併上傳
path:/video_part_upload
參數:json

{
        "type": 11,   //int 必传  数据类型 11:音频压缩包数据
        "upload_id": upload_id, //string 必传  init_part_upload接口返回的upload_id
        "file_suffix": "zip" //string 必传 压缩格式尾缀 zip或tar
        "part_num": 1,  //int 必传  分片顺序:1,2,3,4... 要求第一个分片必须从1开始
        "content": "base64", //string 必传 分片内容,base64字符串
        "appid": "xxxx",  //string 必传 appid
}

標題:

headers = {'Content-Type': 'application/json', 'Authorization': token}

返回:

{
    "errno": 0,
    "errMsg": "success",
    "data": "video part upload success"
}

3、完成文件分片上傳POST

path:/video_complete_upload
參數:json

{
        "type": 11,   //int 必传  数据类型 11:音频压缩包数据
        "upload_id": upload_id,  //string 必传 init_part_upload接口返回的upload_id
        "file_suffix": "zip" //string 必传 压缩格式尾缀 zip或tar
        "appid": "xxxx",  //string 必传 appid
}

標題:

headers = {'Content-Type': 'application/json', 'Authorization': token}

返回:

{
    "errno": 0,
    "errMsg": "success",
    "data": "finish video part upload successs"
}