日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

數(shù)字人流媒體開發(fā)指南

本文介紹數(shù)字人流媒體服務(wù)的接入流程和開發(fā)方案,以及示例代碼。

數(shù)字人流媒體服務(wù)(包括3D數(shù)字人流媒體服務(wù)和2D數(shù)字人流媒體服務(wù))是將數(shù)字人在云端渲染出的視頻畫面通過流媒體的方式輸出到客戶端,平臺目前提供了阿里云RTC流媒體渠道和標準RTMP流媒體渠道兩種渠道。播報數(shù)字人(對應(yīng)開放平臺的“咨詢播報”場景)和互動數(shù)字人(對應(yīng)開放平臺的“客服助理”場景)使用阿里云RTC渠道,平臺會將數(shù)字人渲染的視頻流推到阿里云RTC服務(wù)器,客戶可以使用阿里云RTC的客戶端SDK進行拉流播放對應(yīng)視頻流;推流數(shù)字人(對應(yīng)開放平臺的“虛擬主播”場景)使用標準RTMP渠道,平臺可以將數(shù)字人渲染的視頻流通過RTMP協(xié)議推流到支持對應(yīng)協(xié)議的直播平臺,客戶可以從對應(yīng)的直播平臺觀看視頻流。

下面通過一個典型的客戶端-服務(wù)端架構(gòu)產(chǎn)品介紹數(shù)字人流媒體服務(wù)整體的接入流程。

1. 完整的技術(shù)鏈路圖

image
  • 整體架構(gòu)上分為客戶應(yīng)用、虛擬數(shù)字人開放平臺服務(wù)和阿里云RTC服務(wù)

  • 客戶應(yīng)用分為客戶端(包括:網(wǎng)頁,小程序,APP等)和服務(wù)端(java服務(wù)器,python服務(wù)器等)

    • 如果客戶只有客戶端,如一個APP,沒有服務(wù)端的情況,目前平臺的服務(wù)端API使用的是阿里云的openapi,支持android直接調(diào)用(java sdk)

2. 核心鏈路介紹

2.1 啟動數(shù)字人流媒體服務(wù)

  • 目的:

    • 啟動一路數(shù)字人流媒體服務(wù),數(shù)字人的視頻畫面將被推送到阿里云RTC服務(wù)器(推流數(shù)字人是直接推流到對應(yīng)的直播平臺)

  • 核心流程:

    • 客戶應(yīng)用客戶端向客戶應(yīng)用服務(wù)端發(fā)起啟動數(shù)字人流媒體服務(wù)請求,客戶應(yīng)用服務(wù)端收到請求后通過調(diào)用虛擬數(shù)字人開放平臺服務(wù)端SDK的StartInstance接口啟動一路數(shù)字人流媒體服務(wù)(目前平臺服務(wù)端SDK支持java/python/php三種開發(fā)語言,具體接入方案可參考服務(wù)端API接入。),拿到接口返回的sessionId和RTC流媒體服務(wù)參數(shù),然后返回給客戶應(yīng)用客戶端

2.2 拉取數(shù)字人視頻流

  • 目的:

    • 客戶端拉流對應(yīng)的數(shù)字人視頻流,并在客戶端進行顯示

  • 核心流程:

    • 通過上一步服務(wù)端返回的RTC流媒體服務(wù)參數(shù),接入阿里云RTC客戶端SDK進行拉流,目前阿里云RTC客戶端SDK支持全平臺接入(Android/IOS/Web/Windows等),接入方案可參考客戶端SDK接入。

2.3 向數(shù)字人發(fā)送播報指令

  • 目的:

    • 驅(qū)動數(shù)字人播報對應(yīng)的文本

  • 核心流程:

    • 客戶應(yīng)用客戶端向客戶應(yīng)用服務(wù)端發(fā)起驅(qū)動數(shù)字人播報文本請求,客戶應(yīng)用服務(wù)端收到請求后通過調(diào)用虛擬數(shù)字人開放平臺服務(wù)端SDK的SendText接口驅(qū)動數(shù)字人播報,具體可參考文檔:數(shù)字人播報API接入指南。

2.4 停止數(shù)字人流媒體服務(wù)

  • 目的:

    • 在使用完數(shù)字人流媒體服務(wù)之后停止對應(yīng)流媒體服務(wù),釋放資源(平臺根據(jù)數(shù)字人流媒體服務(wù)啟動的數(shù)量進行計費,請在使用完成后及時停止,避免造成無流媒體服務(wù)可用的情況)

  • 核心流程:

    • 客戶應(yīng)用客戶端向客戶應(yīng)用服務(wù)端發(fā)起停止數(shù)字人流媒體服務(wù)請求,客戶應(yīng)用服務(wù)端收到請求后通過調(diào)用虛擬數(shù)字人開放平臺服務(wù)端SDK的StopInstance接口停止數(shù)字人流媒體服務(wù)

3. 完整流媒體服務(wù)示例代碼

3.1 引入二方包

<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>avatar20220130</artifactId>
  <version>${使用最新版本}</version>
</dependency>
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>${選擇一個合適版本}</version>
</dependency>

3.2 示例代碼

package com.aliyun.avatar.sample;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

import com.aliyun.avatar20220130.Client;
import com.aliyun.avatar20220130.models.SendCommandRequest;
import com.aliyun.avatar20220130.models.SendCommandResponse;
import com.aliyun.avatar20220130.models.SendCommandResponseBody;
import com.aliyun.avatar20220130.models.SendTextRequest;
import com.aliyun.avatar20220130.models.SendTextResponse;
import com.aliyun.avatar20220130.models.SendTextResponseBody;
import com.aliyun.avatar20220130.models.StartInstanceRequest;
import com.aliyun.avatar20220130.models.StartInstanceRequest.StartInstanceRequestApp;
import com.aliyun.avatar20220130.models.StartInstanceRequest.StartInstanceRequestUser;
import com.aliyun.avatar20220130.models.StartInstanceResponse;
import com.aliyun.avatar20220130.models.StartInstanceResponseBody;
import com.aliyun.avatar20220130.models.StartInstanceResponseBody.StartInstanceResponseBodyData;
import com.aliyun.avatar20220130.models.StartInstanceResponseBody.StartInstanceResponseBodyDataChannel;
import com.aliyun.avatar20220130.models.StopInstanceRequest;
import com.aliyun.avatar20220130.models.StopInstanceResponse;
import com.aliyun.avatar20220130.models.StopInstanceResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;

/**
 * <pre>
 *     avatar sample
 * </pre>
 *
 */
public class AvatarOnlineSample {
    private Client client;

    /**
     * 初始化
     *
     * @throws Exception
     */
    public void init() throws Exception {
        // 請確保代碼運行環(huán)境設(shè)置了環(huán)境變量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        // 工程代碼泄露可能會導(dǎo)致 AccessKey 泄露,并威脅賬號下所有資源的安全性。以下代碼示例使用環(huán)境變量獲取 AccessKey 的方式進行調(diào)用,僅供參考,建議使用更安全的 STS 方式,更多鑒權(quán)訪問方式請參見:http://m.bestwisewords.com/document_detail/378657.html
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        client = createClient(accessKeyId, accessKeySecret);
    }

    /**
     * 使用AK&SK初始化賬號Client
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @return Client
     * @throws Exception
     */
    public Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        Config config = new Config()
            // 必填,您的 AccessKey ID
            .setAccessKeyId(accessKeyId)
            // 必填,您的 AccessKey Secret
            .setAccessKeySecret(accessKeySecret);
        // 訪問的域名
        config.endpoint = "avatar.cn-zhangjiakou.aliyuncs.com";
        return new Client(config);
    }

    /**
     * 啟動一路數(shù)據(jù)流媒體服務(wù)
     *
     * @param tenantId
     * @param appId
     */
    public StartInstanceResponseBodyData startInstance(Long tenantId, String appId) throws Exception {
        StartInstanceRequestUser user = new StartInstanceRequestUser();
        user.setUserId("avatar_sample_userId");
        user.setUserName("avatar_sample_userName");

        StartInstanceRequestApp app = new StartInstanceRequestApp();
        app.setAppId(appId);

        StartInstanceRequest request = new StartInstanceRequest();
        request.setTenantId(tenantId);
        request.setApp(app);
        request.setUser(user);
        RuntimeOptions runtime = new RuntimeOptions();
        StartInstanceResponse response = client.startInstanceWithOptions(request, runtime);
        StartInstanceResponseBody responseBody = response.getBody();
        if (null != responseBody.getSuccess() && responseBody.getSuccess()) {
            // 調(diào)用成功
            System.out.println("啟動成功,sessionId:" + responseBody.getData().getSessionId());
            return responseBody.getData();
        } else {
            // 調(diào)用失敗
            System.out.println("啟動失敗,原因:" + responseBody.getCode() + ":" + responseBody.getMessage());
            throw new Exception("啟動失敗");
        }
    }

    /**
     * 停止一路數(shù)據(jù)流媒體服務(wù)
     *
     * @param tenantId
     * @param sessionId
     */
    public void stopInstance(Long tenantId, String sessionId) throws Exception {
        StopInstanceRequest request = new StopInstanceRequest();
        request.setTenantId(tenantId);
        request.setSessionId(sessionId);
        RuntimeOptions runtime = new RuntimeOptions();
        StopInstanceResponse response = client.stopInstanceWithOptions(request, runtime);
        StopInstanceResponseBody responseBody = response.getBody();
        if (null != responseBody.getSuccess() && responseBody.getSuccess()) {
            // 調(diào)用成功
            System.out.println("停止成功,sessionId:" + responseBody.getData().getSessionId());
        } else {
            // 調(diào)用失敗
            System.out.println("停止失敗,原因:" + responseBody.getCode() + ":" + responseBody.getMessage());
            throw new Exception("停止失敗");
        }
    }

    /**
     * 發(fā)送文本消息
     *
     * @param tenantId
     * @param sessionId
     * @param text
     */
    public void sendText(Long tenantId, String sessionId, String text) throws Exception {
        System.out.println(formatCurrentTime() + ":開始發(fā)送文本消息:" + text);
        SendTextRequest request = new SendTextRequest();
        request.setTenantId(tenantId);
        request.setSessionId(sessionId);
        // 本次播報是否打斷當(dāng)前數(shù)字人正在播報的內(nèi)容
        // true表示打斷,false的話會等待當(dāng)前數(shù)字人正在播報的內(nèi)容結(jié)束才會播報本次播報內(nèi)容
        request.setInterrupt(true);
        request.setText(text);
        request.setUniqueCode(UUID.randomUUID().toString());
        RuntimeOptions runtime = new RuntimeOptions();
        SendTextResponse response = client.sendTextWithOptions(request, runtime);
        SendTextResponseBody responseBody = response.getBody();
        if (null != responseBody.getSuccess() && responseBody.getSuccess()) {
            // 調(diào)用成功
            System.out.println(formatCurrentTime() + ":發(fā)送文本消息成功, unqieCode: " + request.getUniqueCode());
        } else {
            // 調(diào)用失敗
            System.out.println("發(fā)送文本消息失敗,原因:" + responseBody.getCode() + ":" + responseBody.getMessage());
            throw new Exception("發(fā)送文本消息失敗");
        }
    }

    /**
     * 發(fā)送指令消息
     *
     * @param tenantId
     * @param sessionId
     * @param code
     * @param content
     */
    public void sendCommand(Long tenantId, String sessionId, String code, Map<String, Object> content)
        throws Exception {
        SendCommandRequest request = new SendCommandRequest();
        request.setTenantId(tenantId);
        request.setSessionId(sessionId);
        request.setCode(code);
        request.setContent(content);
        request.setUniqueCode(UUID.randomUUID().toString());
        RuntimeOptions runtime = new RuntimeOptions();
        SendCommandResponse response = client.sendCommandWithOptions(request, runtime);
        SendCommandResponseBody responseBody = response.getBody();
        if (null != responseBody.getSuccess() && responseBody.getSuccess()) {
            // 調(diào)用成功
            System.out.println(formatCurrentTime() + ":發(fā)送指令消息成功");
        } else {
            // 調(diào)用失敗
            System.out.println("發(fā)送指令消息失敗,原因:" + responseBody.getCode() + ":" + responseBody.getMessage());
            throw new Exception("發(fā)送指令消息失敗");
        }
    }

    public static void main(String[] args) throws Exception {
        // 開發(fā)者信息定義,獲取方式參考文檔:http://m.bestwisewords.com/document_detail/479093.html
        Long tenantId = null;
        String appId = null;
        AvatarOnlineSample sample = new AvatarOnlineSample();
        // 1. 初始化
        sample.init();

        // 2. 啟動一路數(shù)字人流媒體服務(wù)
        StartInstanceResponseBodyData response = sample.startInstance(tenantId, appId);
        // 2.1 獲取啟動成功的sessionId
        String sessionId = response.getSessionId();
        // 2.2 獲取對應(yīng)的channel信息用于客戶端拉流,可以使用平臺提供的測試頁面快速體驗:http://m.bestwisewords.com/document_detail/392352.html
        StartInstanceResponseBodyDataChannel channel = response.getChannel();
        System.out.println(JSONObject.toJSONString(channel, SerializerFeature.PrettyFormat));
        // 2.3 示例代碼這里sleep,可以去平臺的測試頁面拉流查看是否成功
        Thread.sleep(60000);

        // 3. 發(fā)送消息驅(qū)動數(shù)字人播報,詳細可參考文檔:http://m.bestwisewords.com/document_detail/478895.html
        // 3.1 發(fā)送一條測試文本消息
        //     發(fā)送之后數(shù)字人會進行播報,示例代碼通過sleep模擬等待數(shù)字人播報,實際可根據(jù)業(yè)務(wù)情況發(fā)送下一條播報
        sample.sendText(tenantId, sessionId, formatCurrentTime() + ",我是虛擬數(shù)字人,這是一段示例代碼,我正在播報一條示例文本");
        Thread.sleep(15000);
        // 3.2 發(fā)送一條測試文本消息,自定義數(shù)字人動作,詳細可參考文檔:http://m.bestwisewords.com/document_detail/478895.html
        //     注意:實際測試的時候可能會因為使用的數(shù)字人不同以及行業(yè)不同,導(dǎo)致下面的自定義動作不生效
        sample.sendText(tenantId, sessionId, "<speak>" + formatCurrentTime() + ",大家好<vh-action code=\"animation_4960\" interrupt=\"true\"/>,這是一段虛擬數(shù)字人播報測試文本,歡迎大家! </speak>");
        Thread.sleep(15000);
        // 3.3 發(fā)送一條測試指令消息,目前指令只支持打斷數(shù)字人播報
        sample.sendText(tenantId, sessionId, formatCurrentTime() + ",虛擬數(shù)字人是一項整合了語音、圖像、3D美術(shù)、自然語言處理等多領(lǐng)域綜合且復(fù)雜的技術(shù)。阿里云虛擬數(shù)字人開放平臺,依托阿里達摩院強大的AI技術(shù)能力,為阿里云客戶提供了低門檻、輕量級、易集成的3D數(shù)字人、2D數(shù)字人實時和離線驅(qū)動能力,讓阿里云客戶能夠輕松的將數(shù)字人能力接入到自己的業(yè)務(wù)中,從而體驗到數(shù)字人技術(shù)帶來的業(yè)務(wù)提升;同時平臺還提供了豐富的數(shù)字人資產(chǎn)形象庫,以及為了方便非開發(fā)人員使用和體驗還提供了完善的數(shù)字人視頻創(chuàng)作SAAS產(chǎn)品。");
        Thread.sleep(5000);
        sample.sendCommand(tenantId, sessionId, "INTERRUPT", null);
        Thread.sleep(3000);

        // 4. 停止數(shù)字人流媒體服務(wù),釋放資源
        sample.stopInstance(tenantId, sessionId);
    }

    private static String formatCurrentTime() {
        SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss,SSS");
        return format.format(new Date());
    }
}

以上就是一個典型的客戶端-服務(wù)端架構(gòu)產(chǎn)品使用數(shù)字人流媒體服務(wù)的整體鏈路,關(guān)于播報數(shù)字人、互動數(shù)字人等具體數(shù)字人流媒體服務(wù)的接入可參考下方詳細的接入指南: