全部產品
Search
文件中心

ApsaraVideo Live:直播錄製

更新時間:Nov 25, 2025

ApsaraVideo for Live錄製可對當前直播即時錄製並進行歷史回放。本文介紹ApsaraVideo for Live錄製功能。

功能介紹

ApsaraVideo for Live是以即時資料流的形式播放推流端資料,如果想要在直播結束後再次觀看,就必須要使用直播錄製功能。

直播錄製就是將直播中心接收到的推流資料進行錄製,儲存至您指定的儲存位置。目前直播錄製儲存提供兩種方式,錄製儲存至VOD錄製儲存至OSS

直播錄製的原理

直播錄製的過程,是通過拉取您推上來的直播流,將音視頻封裝成一個個單獨的媒體切片(封裝格式為TS),然後進行儲存。直播錄製在工作時遵循以下原則:

  • 直播錄製只修改音視頻的封裝格式(RTMP/FLV轉成TS),絕不修改音視頻內容(即編碼層內容)。舉個例子,如果您推送上來的直播流是花屏的,那麼錄製下來的也是花屏的。

  • 直播錄製有許可權往使用者儲存地址寫入錄製檔案,但是不會也沒有許可權修改/刪除使用者儲存地址的任務檔案(包括已寫入的錄製檔案)。使用者儲存地址中的錄製檔案,完全由您自己管理。

重要

使用直播錄製功能會產生錄製服務費,預設錄製檔案格式為TS/M3U8,如需轉碼封裝處理,將產生錄製轉封裝費。計費規則請參見直播錄製費用

限制條件

音視頻編碼格式

由於直播錄製需要先將直播流切分成TS檔案,因此您推上來的直播流的音視頻編碼格式必須滿足TS封裝格式的要求。根據FLV標準和ISO/IEC 13818-1標準,直播錄製目前僅支援以下編碼格式:

  • 視頻:H264、HEVC、MPEG4

  • 音頻:AAC、MP3

說明

如果直播流包含了非以上格式編碼的音視頻,直播錄製可能會出現:無法產生錄製檔案、錄製黑屏、錄製沒有聲音,以及其他一些無法預見的異常情況。

異常直播流處理機制

  1. 標準流(滿足編碼要求且幀率/時間戳記穩定) ✅ 100%正常產生錄製檔案

  2. 輕微異常流(偶發幀率波動/時間戳記跳變) ✅ 系統自動相容處理

  3. 嚴重異常流(長期無視訊框架/時間戳記錯亂/主要畫面格缺失) ❌ 無法保證錄製成功率

功能對比

錄製儲存至VOD和錄製儲存至OSS都可以對直播內容進行錄製儲存。兩者使用情境有所不同,您可以根據自己的業務決定具體採用哪種方式進行儲存。

儲存方式

關聯產品服務

支援錄製方式

封裝格式

適用情境

錄製儲存至VOD

開通ApsaraVideo for VOD服務

  • 自動錄製:按網域名稱、AppName、StreamName多層級的方式進行錄製。

  • TS/M3U8(預設)

傾向於對錄製內容進行二次生產,注重錄製內容的後期處理,如剪輯、播放、設定錄製視頻封面等。

錄製儲存至OSS

開通OSS服務

  • 自動錄製:按網域名稱、AppName、StreamName多層級的方式進行錄製。

  • 按需錄製:配置一個回調,直播服務得到需要錄製的響應後再進行錄製。

  • 手動錄製:預設不錄製,您可以通過調用介面來進行手動錄製。

  • TS/M3U8(預設)

  • MP4

  • FLV

  • CMAF

傾向於錄製內容管理,注重儲存。

說明
  • 同一個直播流不能同時配置兩種儲存方式。

  • 直播錄製都會先將直播流切片成一個個的TS切片,然後再合成對應封裝格式的錄製檔案。封裝為除TS/M3U8外的格式將產生轉封裝費用。

自動錄製生效規則

您可以指定網域名稱、應用程式名稱或流名稱,錄製某個網域名稱下所有App或App下所有的直播流,也可以精確錄製某一路直播流。AppName和StreamName可以填為*,表示所有AppName和所有StreamName。

配置儲存至OSS或儲存至VOD的錄製模板時您可以配置多個錄製模板,但是如果出現一路直播流同時可以匹配到多個錄製模板時,錄製模板生效存在優先順序,具體優先順序如下(數值越小,優先順序越高):

優先順序

DomainName

AppName

StreamName

1

2

*

3

*

*

✓ 代表通過控制台或API配置自動錄製規則時對應參數有值,且值不為*,* 代表對應參數值為*。

錄製儲存至VOD

前置條件

若採用錄製儲存至VOD方式進行直播錄製功能配置,需要開通ApsaraVideo for VOD服務,並進行配置管理儲存Bucket

重要
  • 錄製檔案儲存體在ApsaraVideo for VODVOD中,會產生儲存費用,在VOD中計費請參見點播基礎服務計費

  • 在啟用點播系統Bucket時,需要注意點播系統Bucket需要與待佈建網域名的直播中心同地區。

  • 使用金融雲帳號不可使用視訊直播錄製到點播。

功能配置

ApsaraVideo for Live目前提供兩種方式添加錄製儲存至VOD配置。

說明
  • 完成配置後重新推流錄製配置才會生效。

  • 斷流180秒後產生錄製檔案。

方法一:控制台配置

  1. 登入ApsaraVideo for Live控制台

  2. 在左側導覽列選擇功能管理>直播錄製,進入直播錄製頁面,選擇儲存至VOD配置頁簽。

  3. 選擇待配置的播流網域名稱,並且單擊添加

  4. 配置錄製模板。

    image

    錄製模板參數及說明如下表所示。

    參數

    描述

    AppName

    視頻的應用程式名稱,輸入的AppName必須與直播推流的AppName保持一致,方可生效。如果您想要進行網域名稱層級錄製,輸入星號(*)即可。

    StreamName

    儲存至VOD支援流層級的錄製。您只需輸入指定的流名稱即可。如果您想要進行全部流錄製,即該AppName下的流全部錄製,輸入星號(*)即可。

    說明

    AppNameStreamName參數支援英文、數字、“-”、“_”符號,長度限制在255個字元以內。

    儲存地址

    可選擇當前地區已經在點播服務中建立的儲存地址。若未找到可點擊重新整理進行同步。

    錄製周期

    錄製周期為當前直播轉為點播檔案後的最大時間長度。範圍為15~360分鐘,最大支援 6 小時錄製。超過 6 小時,系統將按照錄製命名規則產生新檔案。ts切片時間長度預設為 30s。

    錄製轉碼模板

    從列表中選擇儲存轉碼規則,可以在點播服務中對錄製的視頻進行轉碼處理。可轉碼為不同規格的視頻,也可以不轉碼即保持原畫格式。

    錄製轉碼模板具體操作,請參見ApsaraVideo for VOD轉碼配置

    說明

    ApsaraVideo for VOD轉碼模板所在地區需與您當前網域名稱所在地區保持一致。例如:當前網域名稱為華東2區,ApsaraVideo for VOD轉碼模板地區也需要在華東2區。

    自動合并

    開啟後可在直播錄製結束後自動將多個錄製周期檔案合并成一個錄製檔案儲存體到VOD中。

    說明

    開啟多錄製周期合并,會使用ApsaraVideo for VOD服務的基礎剪輯合成功能和轉碼功能。計費詳情參見剪輯合成計費媒資轉碼計費

    自動合并轉碼模板

    從列表中選擇儲存轉碼規則,對自動合成出來的視頻在點播服務中進行一次轉碼,錄製轉碼規則從當前點播系統中擷取。自動合并轉碼模板具體操作,請參見轉碼模板

    說明

    ApsaraVideo for VOD轉碼模板所在地區需與您當前網域名稱所在地區保持一致。例如:當前網域名稱為華東2區,ApsaraVideo for VOD轉碼模板地區也需要在華東2區。

  5. 單擊確定

方法二:API配置

調用添加直播錄製轉點播配置介面添加配置。SDK調用參考如下:

// This file is auto-generated, don't edit it. Thanks.
package demo;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.core.http.HttpClient;
import com.aliyun.core.http.HttpMethod;
import com.aliyun.core.http.ProxyOptions;
import com.aliyun.httpcomponent.httpclient.ApacheAsyncHttpClientBuilder;
import com.aliyun.sdk.service.live20161101.models.*;
import com.aliyun.sdk.service.live20161101.*;
import com.google.gson.Gson;
import darabonba.core.RequestConfiguration;
import darabonba.core.client.ClientOverrideConfiguration;
import darabonba.core.utils.CommonUtil;
import darabonba.core.TeaPair;

//import javax.net.ssl.KeyManager;
//import javax.net.ssl.X509TrustManager;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.io.*;

public class AddLiveRecordVodConfig {
    public static void main(String[] args) throws Exception {

        // HttpClient Configuration
        /*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
                .connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
                .responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
                .maxConnections(128) // Set the connection pool size
                .maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
                // Configure the proxy
                .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("<YOUR-PROXY-HOSTNAME>", 9001))
                        .setCredentials("<YOUR-PROXY-USERNAME>", "<YOUR-PROXY-PASSWORD>"))
                // If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
                .x509TrustManagers(new X509TrustManager[]{})
                .keyManagers(new KeyManager[]{})
                .ignoreSSL(false)
                .build();*/

        // Configure Credentials authentication information, including ak, secret, token
        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
                .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
                .build());

        // Configure the Client
        AsyncClient client = AsyncClient.builder()
                .region("<Your RegionId>") // Region ID
                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
                .credentialsProvider(provider)
                //.serviceConfiguration(Configuration.create()) // Service-level configuration
                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                  // Endpoint 請參考 https://api.aliyun.com/product/live
                                .setEndpointOverride("live.aliyuncs.com")
                        //.setConnectTimeout(Duration.ofSeconds(30))
                )
                .build();

        // Parameter settings for API request
        AddLiveRecordVodConfigRequest addLiveRecordVodConfigRequest = AddLiveRecordVodConfigRequest.builder()
                .regionId("<Your RegionId>")
                .domainName("<Your DomainNmae>")
                .appName("<Your AppName>")
                .streamName("<Your StreamName>")
                .vodTranscodeGroupId("<Your VodTranscodeGroupId>")
                // Request-level configuration rewrite, can set Http request parameters, etc.
                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
                .build();

        // Asynchronously get the return value of the API request
        CompletableFuture<AddLiveRecordVodConfigResponse> response = client.addLiveRecordVodConfig(addLiveRecordVodConfigRequest);
        // Synchronously get the return value of the API request
        AddLiveRecordVodConfigResponse resp = response.get();
        System.out.println(new Gson().toJson(resp));
        // Asynchronous processing of return values
        /*response.thenAccept(resp -> {
            System.out.println(new Gson().toJson(resp));
        }).exceptionally(throwable -> { // Handling exceptions
            System.out.println(throwable.getMessage());
            return null;
        });*/

        // Finally, close the client
        client.close();
    }

}
說明
  • 以上範例程式碼表示,對<DomainName>網域名稱進行錄製儲存至VOD配置,AppName為<AppName>,StreamName為<StreamName>。錄製內容不進行轉碼(VOD_NO_TRANSCODE),儲存至點播系統Bucket<StorageLocation>。

  • AppName和StreamName配置詳情請參見:自動錄製生效規則

錄製內容轉碼

錄製儲存至VOD檔案格式為m3u8,如果想儲存其他格式可以通過配置錄製轉碼模板實現。

 addLiveRecordVodConfigRequest.setVodTranscodeGroupId("<TranscodeGroupId>");
說明
  • 轉碼模板需要在點播系統進行配置,具體操作請參見點播轉碼模板

  • <TranscodeGroupId>為點播系統配置的轉碼模板組ID

  • 配置轉碼後,會對錄製檔案進行轉碼(原檔案仍然保留),產生轉碼地址。

錄製內容合并

錄製內容合并目前分為兩種形式:

  1. 同一路流斷流180秒以內再次推流,錄製內容會自動合并成一個錄製檔案。

  2. 推流時間長度超過錄製周期之後的檔案合并。在推流時間長度超過錄製周期之後,會產生一個新的錄製檔案(假設設定錄製周期5分鐘,推流時間長度8分鐘,一次推流將會產生兩個錄製檔案)。

    如果需要將多個錄製周期的檔案進行合并,可以進行合并配置。

    重要

    開啟多錄製周期合并,會使用ApsaraVideo for VOD服務的基礎剪輯合成功能和轉碼功能。計費詳情參見增值服務計費以及基礎服務計費

    添加直播錄製轉點播配置介面中配置錄製檔案合并範例程式碼如下:

    addLiveRecordVodConfigRequest.setAutoCompose("ON");
    addLiveRecordVodConfigRequest.setComposeVodTranscodeGroupId("<TranscodeGroupId>");
    說明
    • 合并之後會產生一個新的檔案,原錄製檔案仍然保留。

    • 轉碼模板需要在點播系統進行配置,具體操作請參見點播轉碼模板

    • <TranscodeGroupId>為點播系統配置的轉碼模板組ID

    設定錄製周期時間長度範例程式碼如下:

    //單位秒,取值範圍(300~21600),預設值900
    addLiveRecordVodConfigRequest.setCycleDuration(<300>);

錄製檔案管理

目前可以通過ApsaraVideo for Live控制台查看儲存至VOD的錄製檔案,您可以通過ApsaraVideo for VOD服務管理錄製檔案,詳情請參見ApsaraVideo for VOD媒體管理

在ApsaraVideo for Live控制台查看儲存至VOD錄製檔案

  1. 登入ApsaraVideo for Live控制台

  2. 在左側導覽列選擇功能管理>直播錄製,進入直播錄製頁面,選擇錄製檔案管理頁簽。

  3. 選擇配置的播流網域名稱。

  4. 單擊儲存至VOD頁簽。

    image

  5. 具體的錄製檔案可點擊去點播控制台管理,或登入點播控制台在音視頻版塊查看管理。

    image

錄製儲存至OSS

前置條件

若採用錄製儲存至OSS方式進行直播錄製功能配置,需要完成以下操作:

  1. 開通OSS服務並建立Bucket:具體操作請參見建立儲存空間

    重要
    • 錄製檔案儲存體在OSS中,會產生儲存費用,在OSS中計費請參見儲存費用

    • 直播錄製儲存至OSS所需Bucket的地區與錄製配置的網域名稱所在地區必須一致。例如,直播網域名稱在華東2時,Bucket必須選擇華東2。

  2. 配置直播寫入OSS許可權:正常情況下,開通直播服務時,您已完成自動授權。

    重要

    如果該許可權意外被刪除可點擊同意雲資源訪問授權完成快速授權。

    建議您使用阿里雲帳號完成授權,若使用RAM使用者必須擁有以下許可權:ram:CreateRoleram:GetRoleram:ListPoliciesForRoleram:AttachPolicyToRole,授予RAM使用者以上許可權存在安全風險(不推薦)。

功能配置

ApsaraVideo for Live目前提供兩種方式添加錄製儲存至OSS配置。

說明
  • 完成配置後重新推流錄製配置才會生效。

  • 斷流超過斷流拼接時間長度(預設180秒)後產生錄製檔案。

方法一:控制台配置

  1. 登入ApsaraVideo for Live控制台

  2. 在左側導覽列選擇功能管理>直播錄製,進入直播錄製頁面,選擇儲存至OSS配置頁簽。

  3. 選擇待配置的播流網域名稱,並單擊添加

  4. 配置錄製模板。

    image

    表 1. 錄製模板參數

    參數

    描述

    AppName

    視頻的應用程式名稱,輸入的AppName必須與直播推流地址的AppName保持一致,方可生效。如果您想要進行網域名稱層級錄製,輸入星號(*)可。

    StreamName

    儲存至OSS支援流層級的錄製。您只需輸入指定的流名稱即可。如果您想要進行全部流錄製,即該AppName下的流全部錄製,輸入星號(*)可。

    說明
    • AppNameStreamName參數支援英文、數字、短劃線(-)、底線(_)符號,長度限制在255字元以內。

    • *號只能作為單獨輸入,無法在字串中作為萬用字元輸入。

    儲存位置

    可選擇當前地區在OSS中建立的Bucket。

    說明

    儲存Bucket分為兩類:

    1. 標準Bucket:用於常規檔案儲存體

    2. 媒體Bucket:專用於視頻轉碼處理,存入該類型的檔案可自動觸發MPS轉碼任務

    當前系統未對Bucket類型進行標識區分,如需執行視頻轉碼,請自行記錄所使用的媒體Bucket名稱,以確保轉碼後的媒體檔案儲存位置準確。

    斷流拼接時間長度

    直播斷流時間長度超過設定的拼接時間長度後,將會產生新檔案,斷流拼接時間長度支援15~21600秒。

    儲存格式

    支援flv、m3u8、mp4、cmaf四種格式。

    說明

    至少配置一個儲存格式,其中CMAF格式不能與M3U8格式同時選擇。

    儲存規則

    預設的儲存路徑為:record/{AppName}/{StreamName}/{EscapedStartTime }_{EscapedEndTime }

    樣本:

    AppNameliveApp****StreamNameliveStream****,當錄製m3u8格式的儲存路徑為record/liveApp****/liveStream****/{EscapedStartTime}_{EscapedEndTime }

    單個TS時間長度

    單個切片時間長度,預設為30秒。支援單個TS時間長度範圍5~30秒。

    錄製周期

    錄製周期範圍為15分鐘~360分鐘,最大支援6小時錄製。超過6小時,系統將按照錄製命名規則產生新檔案。

    說明

    錄製周期為當前直播轉為點播檔案後的最大時間長度。

  5. 配置錄製轉碼流。(可選)

    重要

    使用直播轉碼功能會產生轉碼費用,按轉碼標準、解析度規格及對應總轉碼時間長度計費。計費規則詳見直播轉碼費用

    image

    表 2. 錄製轉碼流參數

    參數

    描述

    錄製轉碼流

    開啟錄製轉碼流開關,配置參數。

    儲存格式

    支援flvm3u8mp4cmaf四種格式。

    說明

    至少配置一個儲存格式,其中CMAF格式不能與M3U8格式同時選擇。

    儲存規則

    預設的儲存路徑為:transcodeRecord/{AppName}/{StreamName}_{轉碼模板ID}/{EscapedStartTime }_{EscapedEndTime }

    樣本:

    AppNameliveApp****StreamNameliveStream****轉碼模板ID為lld,當錄製m3u8格式的實際儲存路徑為transcodeRecord/liveApp****/liveStream****_lld/{EscapedStartTime}_{EscapedEndTime }

    單個TS時間長度

    單個切片時間長度,預設為30秒。支援單個TS時間長度5~30秒。

    錄製周期

    錄製周期範圍為15分鐘~360分鐘,最大支援6小時錄製。超過6小時,系統將按照錄製命名規則產生新檔案。

    說明

    錄製周期為當前直播轉為點播檔案後的最大時間長度。

    轉碼模板ID

    支援選擇指定轉碼模板(上限10個)或全部轉碼模板。

    轉碼模板所屬AppName需和錄製模板保持一致才可生效,若無轉碼模板,請先添加轉碼模板,請參見通用轉碼

  6. 單擊確定

方法二:API配置

調用添加錄製配置介面添加配置。SDK調用參考如下:

// This file is auto-generated, don't edit it. Thanks.
package demo;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.core.http.HttpClient;
import com.aliyun.core.http.HttpMethod;
import com.aliyun.core.http.ProxyOptions;
import com.aliyun.httpcomponent.httpclient.ApacheAsyncHttpClientBuilder;
import com.aliyun.sdk.service.live20161101.models.*;
import com.aliyun.sdk.service.live20161101.*;
import com.google.gson.Gson;
import darabonba.core.RequestConfiguration;
import darabonba.core.client.ClientOverrideConfiguration;
import darabonba.core.utils.CommonUtil;
import darabonba.core.TeaPair;

//import javax.net.ssl.KeyManager;
//import javax.net.ssl.X509TrustManager;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.io.*;

public class AddLiveAppRecordConfig {
    public static void main(String[] args) throws Exception {

        // HttpClient Configuration
        /*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
                .connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
                .responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
                .maxConnections(128) // Set the connection pool size
                .maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
                // Configure the proxy
                .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("<YOUR-PROXY-HOSTNAME>", 9001))
                        .setCredentials("<YOUR-PROXY-USERNAME>", "<YOUR-PROXY-PASSWORD>"))
                // If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
                .x509TrustManagers(new X509TrustManager[]{})
                .keyManagers(new KeyManager[]{})
                .ignoreSSL(false)
                .build();*/

        // Configure Credentials authentication information, including ak, secret, token
        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
                .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
                .build());

        // Configure the Client
        AsyncClient client = AsyncClient.builder()
                .region("<Your RegionId>") // Region ID
                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
                .credentialsProvider(provider)
                //.serviceConfiguration(Configuration.create()) // Service-level configuration
                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                  // Endpoint 請參考 https://api.aliyun.com/product/live
                                .setEndpointOverride("live.aliyuncs.com")
                        //.setConnectTimeout(Duration.ofSeconds(30))
                )
                .build();

        // Parameter settings for API request
        AddLiveAppRecordConfigRequest addLiveAppRecordConfigRequest = AddLiveAppRecordConfigRequest.builder()
                .domainName("<Your DomainName>")
                .appName("<Your AppName>")
                .ossEndpoint("<Your OSSEndpoint>")
                .ossBucket("<Your OSSBucket>")
                .streamName("<Your StreamName>")
                // Request-level configuration rewrite, can set Http request parameters, etc.
                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
                .build();

        // Asynchronously get the return value of the API request
        CompletableFuture<AddLiveAppRecordConfigResponse> response = client.addLiveAppRecordConfig(addLiveAppRecordConfigRequest);
        // Synchronously get the return value of the API request
        AddLiveAppRecordConfigResponse resp = response.get();
        System.out.println(new Gson().toJson(resp));
        // Asynchronous processing of return values
        /*response.thenAccept(resp -> {
            System.out.println(new Gson().toJson(resp));
        }).exceptionally(throwable -> { // Handling exceptions
            System.out.println(throwable.getMessage());
            return null;
        });*/

        // Finally, close the client
        client.close();
    }

}
說明
  • 以上範例程式碼表示,對<DomainName>網域名稱進行錄製儲存至OSS配置,AppName為<AppName>,StreamName為<StreamName>,儲存格式為m3u8,儲存至<OssBucket>中。

  • <OssEndpoint>可通過<OssBucket>所屬地區在OSS地區和Endpoint進行查看。

  • AppName和StreamName配置詳情請參見:自動錄製生效規則

錄製轉碼流

如果希望在儲存錄製內容時減少錄製檔案體積,可通過錄製轉碼流實現(在保證畫質品質的前提下,調整視頻碼率、提高視頻壓縮率、減小檔案體積)。錄製儲存至OSS功能支援同時儲存轉碼流與原始流,也支援僅儲存轉碼流或原始流。

重要

使用直播轉碼功能會產生轉碼費用,按轉碼標準、解析度規格及對應總轉碼時間長度計費。計費規則詳見直播轉碼費用

配置錄製轉碼流範例程式碼>>>

        //需要將<>內容替換成實際使用的值        
        List<AddLiveAppRecordConfigRequest.TranscodeRecordFormat> transcodeFormatList=new ArrayList<AddLiveAppRecordConfigRequest.TranscodeRecordFormat>();
        AddLiveAppRecordConfigRequest.TranscodeRecordFormat m3u8TranscodeFormat=new AddLiveAppRecordConfigRequest.TranscodeRecordFormat();
        m3u8TranscodeFormat.setFormat("m3u8");
        //轉碼流錄製OSS儲存的錄製檔案名稱
        m3u8TranscodeFormat.setOssObjectPrefix("<transcodeRecord/{AppName}/{StreamName}/{EscapedStartTime}_{EscapedEndTime}>");
        //轉碼流錄製切片名稱
        m3u8TranscodeFormat.setSliceOssObjectPrefix("<transcodeRecord/{AppName}/{StreamName}/{UnixTimestamp}_{Sequence}>");
        transcodeFormatList.add(m3u8TranscodeFormat);
        addLiveAppRecordConfigRequest.setTranscodeRecordFormats(transcodeFormatList);
        List<String> transcodeTemplateList=new ArrayList<String>();
        //轉碼模板ID
        transcodeTemplateList.add("<lld>");
        addLiveAppRecordConfigRequest.setTranscodeTemplatess(transcodeTemplateList);
說明
  • 若僅需錄製轉碼流,則可以不設定原始流(setRecordFormats)。

  • 設定錄製轉碼流(setTranscodeRecordFormats)時,需同時指定轉碼模板ID(setTranscodeTemplatess),轉碼模板需要進行配置,具體操作請參見直播轉碼

  • 錄製轉碼流需要在配置轉碼模板時,將轉碼配置為推流觸發

  • 轉碼流錄製檔案名稱StreamName會轉換成StreamName_轉碼模板ID的形式。

自訂錄製策略

功能配置中,我們進行了直播錄製功能的配置,在直播推流時即會開始對直播內容進行錄製,我們稱其為自動錄製

但有些時候,我們希望能夠通過業務決策自主決定是否需要對某一次直播內容進行錄製。直播錄製功能提供瞭解決這類問題的方法,自主決定錄製分為兩種情況:

  1. 由直播中心回調詢問您的業務系統是否需要對該直播內容進行錄製,得到響應需要錄製後再進行錄製,我們稱其為按需錄製

  2. 由您的業務系統給直播服務發出通知對直播內容進行錄製,我們稱其為手動錄製

按需錄製

按需錄製

實現按需錄製,需要您業務系統提供直播服務調用的URL地址,具體說明可參見按需錄製回調

設定錄製功能按需錄製範例程式碼如下:

        //OnDemand欄位填1,表示通過HTTP回調開啟按需錄製。
        addLiveAppRecordConfigRequest.setOnDemand(1);

同時調用 添加網域名稱層級錄製回調配置API進行錄製回調配置。

添加錄製回調配置範例程式碼>>>

// This file is auto-generated, don't edit it. Thanks.
package demo;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.core.http.HttpClient;
import com.aliyun.core.http.HttpMethod;
import com.aliyun.core.http.ProxyOptions;
import com.aliyun.httpcomponent.httpclient.ApacheAsyncHttpClientBuilder;
import com.aliyun.sdk.service.live20161101.models.*;
import com.aliyun.sdk.service.live20161101.*;
import com.google.gson.Gson;
import darabonba.core.RequestConfiguration;
import darabonba.core.client.ClientOverrideConfiguration;
import darabonba.core.utils.CommonUtil;
import darabonba.core.TeaPair;

//import javax.net.ssl.KeyManager;
//import javax.net.ssl.X509TrustManager;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.io.*;

public class AddLiveRecordNotifyConfig {
    public static void main(String[] args) throws Exception {

        // HttpClient Configuration
        /*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
                .connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
                .responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
                .maxConnections(128) // Set the connection pool size
                .maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
                // Configure the proxy
                .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("<YOUR-PROXY-HOSTNAME>", 9001))
                        .setCredentials("<YOUR-PROXY-USERNAME>", "<YOUR-PROXY-PASSWORD>"))
                // If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
                .x509TrustManagers(new X509TrustManager[]{})
                .keyManagers(new KeyManager[]{})
                .ignoreSSL(false)
                .build();*/

        // Configure Credentials authentication information, including ak, secret, token
        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
                .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
                .build());

        // Configure the Client
        AsyncClient client = AsyncClient.builder()
                .region("<Your RegionId>") // Region ID
                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
                .credentialsProvider(provider)
                //.serviceConfiguration(Configuration.create()) // Service-level configuration
                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                  // Endpoint 請參考 https://api.aliyun.com/product/live
                                .setEndpointOverride("live.aliyuncs.com")
                        //.setConnectTimeout(Duration.ofSeconds(30))
                )
                .build();

        // Parameter settings for API request
        AddLiveRecordNotifyConfigRequest addLiveRecordNotifyConfigRequest = AddLiveRecordNotifyConfigRequest.builder()
                .domainName("<Your DomainName>")
                .notifyUrl("<Your NotifyUrl>")
                // Request-level configuration rewrite, can set Http request parameters, etc.
                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
                .build();

        // Asynchronously get the return value of the API request
        CompletableFuture<AddLiveRecordNotifyConfigResponse> response = client.addLiveRecordNotifyConfig(addLiveRecordNotifyConfigRequest);
        // Synchronously get the return value of the API request
        AddLiveRecordNotifyConfigResponse resp = response.get();
        System.out.println(new Gson().toJson(resp));
        // Asynchronous processing of return values
        /*response.thenAccept(resp -> {
            System.out.println(new Gson().toJson(resp));
        }).exceptionally(throwable -> { // Handling exceptions
            System.out.println(throwable.getMessage());
            return null;
        });*/

        // Finally, close the client
        client.close();
    }

}
重要
  • <OnDemandUrl>為按需錄製回調請求URL地址,<NotifyUrl>為錄製回調(包括錄製事件和狀態回調) URL地址。

  • 因介面<NotifyUrl>參數不可為空,所以必須要設定<NotifyUrl>,如果您只需要接收按需錄製請求,不需要錄製事件和錄製狀態回調,可以配置<NotifyUrl>為一個沒有方法實現的URL地址。

相關API

手動錄製

實現手動錄製,需要將自動錄製功能關閉。範例程式碼如下:

        //OnDemand欄位填7,表示不進行自動錄製。
        addLiveAppRecordConfigRequest.setOnDemand(7);

然後在直播的過程中,您可以根據業務情況通過調用 即時錄製指令API開啟錄製。

開啟錄製範例程式碼>>>

        //需要將<>內容替換成實際使用的值 
        RealTimeRecordCommandRequest realTimeRecordCommandRequest=new RealTimeRecordCommandRequest();
        realTimeRecordCommandRequest.setCommand("start");
        realTimeRecordCommandRequest.setAppName("<AppName>");
        realTimeRecordCommandRequest.setStreamName("<StreamName>");
        realTimeRecordCommandRequest.setDomainName("<DomainName>");
        RealTimeRecordCommandResponse realTimeRecordCommandResponse = null;
        try {
            realTimeRecordCommandResponse = client.getAcsResponse(realTimeRecordCommandRequest);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        System.out.println(new Gson().toJson(realTimeRecordCommandResponse));
說明
  • 如果錄製的是轉碼流,此處需要將<StreamName>設定成StreamName_轉碼模板ID的形式。

  • setCommand("start")表示啟動錄製。

停止錄製

無論是自動錄製按需錄製手動錄製,都可以調用即時錄製指令API主動停止錄製。

// This file is auto-generated, don't edit it. Thanks.
package demo;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.core.http.HttpClient;
import com.aliyun.core.http.HttpMethod;
import com.aliyun.core.http.ProxyOptions;
import com.aliyun.httpcomponent.httpclient.ApacheAsyncHttpClientBuilder;
import com.aliyun.sdk.service.live20161101.models.*;
import com.aliyun.sdk.service.live20161101.*;
import com.google.gson.Gson;
import darabonba.core.RequestConfiguration;
import darabonba.core.client.ClientOverrideConfiguration;
import darabonba.core.utils.CommonUtil;
import darabonba.core.TeaPair;

//import javax.net.ssl.KeyManager;
//import javax.net.ssl.X509TrustManager;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.io.*;

public class RealTimeRecordCommand {
    public static void main(String[] args) throws Exception {

        // HttpClient Configuration
        /*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
                .connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
                .responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
                .maxConnections(128) // Set the connection pool size
                .maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
                // Configure the proxy
                .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("<YOUR-PROXY-HOSTNAME>", 9001))
                        .setCredentials("<YOUR-PROXY-USERNAME>", "<YOUR-PROXY-PASSWORD>"))
                // If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
                .x509TrustManagers(new X509TrustManager[]{})
                .keyManagers(new KeyManager[]{})
                .ignoreSSL(false)
                .build();*/

        // Configure Credentials authentication information, including ak, secret, token
        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
                .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
                .build());

        // Configure the Client
        AsyncClient client = AsyncClient.builder()
                .region("<Your RegionId>") // Region ID
                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
                .credentialsProvider(provider)
                //.serviceConfiguration(Configuration.create()) // Service-level configuration
                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                  // Endpoint 請參考 https://api.aliyun.com/product/live
                                .setEndpointOverride("live.aliyuncs.com")
                        //.setConnectTimeout(Duration.ofSeconds(30))
                )
                .build();

        // Parameter settings for API request
        RealTimeRecordCommandRequest realTimeRecordCommandRequest = RealTimeRecordCommandRequest.builder()
                .regionId("<Your RegionId>")
                .command("<Your Command>")
                .domainName("<Your DomainName>")
                .appName("<Your AppName>")
                .streamName("<Your StreamName>")
                // Request-level configuration rewrite, can set Http request parameters, etc.
                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
                .build();

        // Asynchronously get the return value of the API request
        CompletableFuture<RealTimeRecordCommandResponse> response = client.realTimeRecordCommand(realTimeRecordCommandRequest);
        // Synchronously get the return value of the API request
        RealTimeRecordCommandResponse resp = response.get();
        System.out.println(new Gson().toJson(resp));
        // Asynchronous processing of return values
        /*response.thenAccept(resp -> {
            System.out.println(new Gson().toJson(resp));
        }).exceptionally(throwable -> { // Handling exceptions
            System.out.println(throwable.getMessage());
            return null;
        });*/

        // Finally, close the client
        client.close();
    }

}
說明
  • setCommand("stop")表示停止錄製。

  • 主動停止錄製,同樣需等待斷流拼接時間長度之後才會產生錄製檔案。

  • 如果錄製的是轉碼流,此處需要將<StreamName>設定成StreamName_轉碼模板ID的形式。

斷流拼接

同一路流斷流在斷流拼接時間長度(預設180秒)以內再次推流,錄製內容會自動合并成一個錄製檔案。

說明

因需等待斷流拼接,所以才會在斷流拼接時間長度之後產生錄製檔案。

您可以根據您實際的業務調整斷流拼接時間長度,設定斷流拼接時間長度:

//單位秒,取值範圍(15~21600)
addLiveAppRecordConfigRequest.setDelayTime(<180>);

建議參考預設180秒配置。若產生錄製檔案的時間設定過短,由於網路波動,斷流重推等原因,就會產生大量的錄製檔案。若設定過長則會導致錄製檔案在直播結束(斷流)之後很長時間才能看到。

在一些特定的業務情境中,您可能完全不希望等待斷流拼接,而希望在直播結束後立即產生錄製檔案,這種情況也是可以實現的。您可以給推流設定回調事件(設定推流回調事件請參見直播推流回調),在接收到推流結束通知時通過調用 即時錄製指令API做到取消斷流拼接。

        //需要將<>內容替換成實際使用的值
        RealTimeRecordCommandRequest realTimeRecordCommandRequest=new RealTimeRecordCommandRequest();
        realTimeRecordCommandRequest.setCommand("cancel_delay");
        realTimeRecordCommandRequest.setAppName("<AppName>");
        realTimeRecordCommandRequest.setStreamName("<StreamName>");
        realTimeRecordCommandRequest.setDomainName("<DomainName>");
        RealTimeRecordCommandResponse realTimeRecordCommandResponse = null;
        try {
            realTimeRecordCommandResponse = client.getAcsResponse(realTimeRecordCommandRequest);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        System.out.println(new Gson().toJson(realTimeRecordCommandResponse));
說明
  • 如果錄製的是轉碼流,此處需要將<StreamName>設定成StreamName_轉碼模板ID的形式。

  • setCommand("cancel_delay") 即表示重設斷流延遲時間,完全停止錄製,立刻產生錄製檔案。

錄製周期配置

直播時間長度超過設定的錄製周期後,將產生新檔案(例如直播20分鐘,錄製周期設定為15分鐘,將會產生兩個錄製檔案),錄製周期支援15-360分鐘

設定錄製周期範例程式碼>>>

        List<AddLiveAppRecordConfigRequest.RecordFormat> formatList=new ArrayList<AddLiveAppRecordConfigRequest.RecordFormat>();
        AddLiveAppRecordConfigRequest.RecordFormat m3u8Format=new AddLiveAppRecordConfigRequest.RecordFormat();
        m3u8Format.setFormat("m3u8");
        m3u8Format.setOssObjectPrefix("<record/{AppName}/{StreamName}/{EscapedStartTime}_{EscapedEndTime}>");
        m3u8Format.setSliceOssObjectPrefix("<record/{AppName}/{StreamName}/{UnixTimestamp}_{Sequence}>");
       //設定錄製周期,單位秒
        m3u8Format.setCycleDuration(<900>);
        AddLiveAppRecordConfigRequest.RecordFormat mp4Format=new AddLiveAppRecordConfigRequest.RecordFormat();
        mp4Format.setFormat("mp4");
        mp4Format.setOssObjectPrefix("<record/{AppName}/{StreamName}/{EscapedStartTime}_{EscapedEndTime}>");
        //設定錄製周期,單位秒
        mp4Format.setCycleDuration(<1500>);
        formatList.add(mp4Format);
        formatList.add(m3u8Format);
        addLiveAppRecordConfigRequest.setRecordFormats(formatList);
說明

注意在以上樣本中,同時配置了兩種儲存格式,分別設定了錄製周期。按照此設定進行推流20分鐘,將會產生3個錄製檔案(一個mp4,兩個m3u8)。

在直播未超過錄製周期的情況下,錄製檔案一般在直播結束後產生。若是您的業務需要在直播未結束的情況下查看錄製檔案,可以通過調用 即時錄製指令API重新整理錄製內容,強制重新開始錄製,如果restart之前在錄製,會立即產生錄製檔案。

重新開始錄製範例程式碼>>>

        //需要將<>內容替換成實際使用的值 
        RealTimeRecordCommandRequest realTimeRecordCommandRequest=new RealTimeRecordCommandRequest();
        realTimeRecordCommandRequest.setCommand("restart");
        realTimeRecordCommandRequest.setAppName("<AppName>");
        realTimeRecordCommandRequest.setStreamName("<StreamName>");
        realTimeRecordCommandRequest.setDomainName("<DomainName>");
        RealTimeRecordCommandResponse realTimeRecordCommandResponse = null;
        try {
            realTimeRecordCommandResponse = client.getAcsResponse(realTimeRecordCommandRequest);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        System.out.println(new Gson().toJson(realTimeRecordCommandResponse));
說明
  • setCommand("restart")表示重新開始錄製。

  • 如果錄製的是轉碼流,此處需要將<StreamName>設定成StreamName_轉碼模板ID的形式。

  • 若您的直播流錄製配置了多種儲存格式,此操作會將多種儲存格式一起重新整理。

錄製內容合并與提取

ApsaraVideo for Live支援通過建立索引檔案將錄製內容按照時間段提取出檔案,也可以將起止時間段內的多個錄製檔案內容合并為一個。

說明
  • 無論錄製內容最終儲存成哪種格式,直播錄製都會先將直播流切片成一個個的TS切片,然後再合成對應封裝格式的錄製檔案。通過此特性,可以自主建立M3U8索引檔案,將TS切片檔案進行組合,從而實現錄製內容的合并與提取。

  • 錄製內容需要包含M3U8儲存格式才能夠進行合并或提取。

調用建立錄製索引檔案API建立錄製內容索引檔案。

建立錄製內容索引檔案範例程式碼>>>

// This file is auto-generated, don't edit it. Thanks.
package demo;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.core.http.HttpClient;
import com.aliyun.core.http.HttpMethod;
import com.aliyun.core.http.ProxyOptions;
import com.aliyun.httpcomponent.httpclient.ApacheAsyncHttpClientBuilder;
import com.aliyun.sdk.service.live20161101.models.*;
import com.aliyun.sdk.service.live20161101.*;
import com.google.gson.Gson;
import darabonba.core.RequestConfiguration;
import darabonba.core.client.ClientOverrideConfiguration;
import darabonba.core.utils.CommonUtil;
import darabonba.core.TeaPair;

//import javax.net.ssl.KeyManager;
//import javax.net.ssl.X509TrustManager;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.io.*;

public class CreateLiveStreamRecordIndexFiles {
    public static void main(String[] args) throws Exception {

        // HttpClient Configuration
        /*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
                .connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
                .responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
                .maxConnections(128) // Set the connection pool size
                .maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
                // Configure the proxy
                .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("<YOUR-PROXY-HOSTNAME>", 9001))
                        .setCredentials("<YOUR-PROXY-USERNAME>", "<YOUR-PROXY-PASSWORD>"))
                // If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
                .x509TrustManagers(new X509TrustManager[]{})
                .keyManagers(new KeyManager[]{})
                .ignoreSSL(false)
                .build();*/

        // Configure Credentials authentication information, including ak, secret, token
        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
                .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
                .build());

        // Configure the Client
        AsyncClient client = AsyncClient.builder()
                .region("<Your RegionId>") // Region ID
                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
                .credentialsProvider(provider)
                //.serviceConfiguration(Configuration.create()) // Service-level configuration
                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                  // Endpoint 請參考 https://api.aliyun.com/product/live
                                .setEndpointOverride("live.aliyuncs.com")
                        //.setConnectTimeout(Duration.ofSeconds(30))
                )
                .build();

        // Parameter settings for API request
        CreateLiveStreamRecordIndexFilesRequest createLiveStreamRecordIndexFilesRequest = CreateLiveStreamRecordIndexFilesRequest.builder()
                .domainName("<Your domainName>")
                .appName("<Your appName>")
                .streamName("<Your streamName>")
                .ossEndpoint("<Your ossEndpoint>")
                .ossBucket("<Your ossBucket>")
                .ossObject("<Your ossObject>")
                .startTime("<Your startTime>")
                .endTime("<Your endTime>")
                // Request-level configuration rewrite, can set Http request parameters, etc.
                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
                .build();

        // Asynchronously get the return value of the API request
        CompletableFuture<CreateLiveStreamRecordIndexFilesResponse> response = client.createLiveStreamRecordIndexFiles(createLiveStreamRecordIndexFilesRequest);
        // Synchronously get the return value of the API request
        CreateLiveStreamRecordIndexFilesResponse resp = response.get();
        System.out.println(new Gson().toJson(resp));
        // Asynchronous processing of return values
        /*response.thenAccept(resp -> {
            System.out.println(new Gson().toJson(resp));
        }).exceptionally(throwable -> { // Handling exceptions
            System.out.println(throwable.getMessage());
            return null;
        });*/

        // Finally, close the client
        client.close();
    }

}
說明
  • 以上樣本表示,將直播流<AppName> <StreamName>的錄製內容,按照起止時間<StartTime>至<EndTime>建立出一個新的索引檔案。儲存至<OssEndpoint>的<OssBucket>中,索引檔案名稱為<IndexFiles/OssObject.m3u8>。

  • <StartTime>至<EndTime>格式為:yyyy-MM-ddTHH:mm:ssZ(UTC時間)。

重要
  • 建立錄製索引必須保證直播流發生過推流行為,如果設定的時間內未發生過直播或直播流名稱錯誤等會導致建立錄製索引失敗。

  • 錄製內容分為檔案資訊(包含AppName,StreamName,OSS儲存路徑等)和檔案。檔案資訊(TS分區檔案資訊和建立的M3U8索引檔案資訊)儲存在ApsaraVideo for Live中,檔案(TS分區檔案和M3U8索引檔案)儲存在OSS中。

  • 儲存在OSS中的檔案儲存時間由OSS的儲存配置決定。

  • TS分區檔案資訊在ApsaraVideo for Live系統中僅儲存3個月,建立M3U8索引檔案只能選擇最近3個月的錄製內容。

  • M3U8索引檔案資訊在ApsaraVideo for Live系統中僅儲存6個月,若要查詢僅能查詢6個月內建立的索引檔案的資訊。

  • 如要合并或提取轉碼流,需要將StreamName設定成StreamName_轉碼模板ID的形式。

  • <OssBucket>需要與直播中心同地區,否則無法通過網域名稱查詢到建立的M3U8索引檔案資訊。

相關API

錄製檔案管理

查看錄製檔案

ApsaraVideo for Live支援三種方式查看錄製檔案。

方法一:控制台查看

  1. 登入ApsaraVideo for Live控制台

  2. 在左側導覽列選擇功能管理>直播錄製,進入直播錄製頁面,選擇錄製檔案管理頁簽。

  3. 選擇待配置的播流網域名稱。

  4. 單擊儲存至OSS頁簽。

    image

方法二:API查看

通過調用DescribeLiveStreamRecordIndexFiles - 查詢某個時間段內的所有錄製索引檔案介面。SDK範例程式碼如下:

// This file is auto-generated, don't edit it. Thanks.
package demo;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.core.http.HttpClient;
import com.aliyun.core.http.HttpMethod;
import com.aliyun.core.http.ProxyOptions;
import com.aliyun.httpcomponent.httpclient.ApacheAsyncHttpClientBuilder;
import com.aliyun.sdk.service.live20161101.models.*;
import com.aliyun.sdk.service.live20161101.*;
import com.google.gson.Gson;
import darabonba.core.RequestConfiguration;
import darabonba.core.client.ClientOverrideConfiguration;
import darabonba.core.utils.CommonUtil;
import darabonba.core.TeaPair;

//import javax.net.ssl.KeyManager;
//import javax.net.ssl.X509TrustManager;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.io.*;

public class DescribeLiveStreamRecordIndexFiles {
    public static void main(String[] args) throws Exception {

        // HttpClient Configuration
        /*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
                .connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
                .responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
                .maxConnections(128) // Set the connection pool size
                .maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
                // Configure the proxy
                .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("<YOUR-PROXY-HOSTNAME>", 9001))
                        .setCredentials("<YOUR-PROXY-USERNAME>", "<YOUR-PROXY-PASSWORD>"))
                // If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
                .x509TrustManagers(new X509TrustManager[]{})
                .keyManagers(new KeyManager[]{})
                .ignoreSSL(false)
                .build();*/

        // Configure Credentials authentication information, including ak, secret, token
        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
                .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
                .build());

        // Configure the Client
        AsyncClient client = AsyncClient.builder()
                .region("<Your RegionId>") // Region ID
                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
                .credentialsProvider(provider)
                //.serviceConfiguration(Configuration.create()) // Service-level configuration
                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                  // Endpoint 請參考 https://api.aliyun.com/product/live
                                .setEndpointOverride("live.aliyuncs.com")
                        //.setConnectTimeout(Duration.ofSeconds(30))
                )
                .build();

        // Parameter settings for API request
        DescribeLiveStreamRecordIndexFilesRequest describeLiveStreamRecordIndexFilesRequest = DescribeLiveStreamRecordIndexFilesRequest.builder()
                .domainName("<Your DomainName>")
                .appName("<Your AppName>")
                .streamName("<Your StreamName>")
                .startTime("<Your StartTime>")
                .endTime("<Your EndTime>")
                .order("<Your Order>")
                // Request-level configuration rewrite, can set Http request parameters, etc.
                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
                .build();

        // Asynchronously get the return value of the API request
        CompletableFuture<DescribeLiveStreamRecordIndexFilesResponse> response = client.describeLiveStreamRecordIndexFiles(describeLiveStreamRecordIndexFilesRequest);
        // Synchronously get the return value of the API request
        DescribeLiveStreamRecordIndexFilesResponse resp = response.get();
        System.out.println(new Gson().toJson(resp));
        // Asynchronous processing of return values
        /*response.thenAccept(resp -> {
            System.out.println(new Gson().toJson(resp));
        }).exceptionally(throwable -> { // Handling exceptions
            System.out.println(throwable.getMessage());
            return null;
        });*/

        // Finally, close the client
        client.close();
    }

}
重要
  • 目前只支援查詢6個月內的資料。

  • EndTime和StartTime格式為:yyyy-MM-ddTHH:mm:ssZ(UTC時間),間隔不能超過4天。

方法三:OSS查看

在配置錄製功能時,您已指定了錄製檔案在OSS中的儲存地址。如果需要在OSS中查看錄製檔案,可參見OSS列舉檔案

刪除錄製檔案

ApsaraVideo for Live儲存的是錄製檔案資訊,如AppName,StreamName,OSS檔案儲存路徑等,檔案是儲存在OSS中。如果在刪除錄製時需要同步刪除儲存在OSS中的檔案,則需要建立服務角色AliyunMTSVideoLifecycleRole,並精确授权AliyunMTSVideoLifecycleRolePolicy系統策略。

詳細授權過程

在直播控制台刪除錄製檔案時需要先進行授權,您需要按照如下步驟在RAM控制台建立並授權RAM角色後,再登入直播控制台刪除錄製檔案。

建立普通服務角色

  1. 使用Resource Access Management員登入RAM控制台

  2. 在左側導覽列,選擇身份管理 > 角色

  3. 角色頁面,單擊创建角色

    image

  4. 创建角色頁面,選擇信任主體類型雲端服務,然後選擇具體的阿里雲服務,最後單擊確定

    image

    說明

    信任主體名稱下拉框中請選擇“ApsaraVideo for Media Processing”。

  5. 在彈出的建立角色對話方塊,角色名稱欄中輸入“AliyunMTSVideoLifecycleRole”作為角色名稱,然後單擊確定image

  6. 角色建立成功後,在角色基本資料頁面下選擇許可權管理頁簽。

  7. 點擊精確授權,請按照以下參數配置:

    • 選擇權限類別型:系統策略

    • 輸入策略名稱稱:AliyunMTSVideoLifecycleRolePolicy

    配置完成後,單擊確定image

目前有三種方式進行錄製檔案刪除。

方法一:控制台刪除

  1. 登入ApsaraVideo for Live控制台

  2. 在左側導覽列選擇錄製檔案管理

  3. 選擇待刪除錄製檔案的網域名稱。

  4. 單擊儲存至OSS頁簽,選擇刪除

    刪除錄製檔案

  5. 單擊確定

    同步刪除選項預設不選中。若選中此選項,則在刪除ApsaraVideo for Live控制台上錄製檔案記錄時會同步刪除OSS中的錄製檔案。確定刪除

方法二:API刪除

通過調用刪除直播錄製檔案介面。SDK範例程式碼如下:

// This file is auto-generated, don't edit it. Thanks.
package demo;

import com.aliyun.auth.credentials.Credential;
import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
import com.aliyun.core.http.HttpClient;
import com.aliyun.core.http.HttpMethod;
import com.aliyun.core.http.ProxyOptions;
import com.aliyun.httpcomponent.httpclient.ApacheAsyncHttpClientBuilder;
import com.aliyun.sdk.service.live20161101.models.*;
import com.aliyun.sdk.service.live20161101.*;
import com.google.gson.Gson;
import darabonba.core.RequestConfiguration;
import darabonba.core.client.ClientOverrideConfiguration;
import darabonba.core.utils.CommonUtil;
import darabonba.core.TeaPair;

//import javax.net.ssl.KeyManager;
//import javax.net.ssl.X509TrustManager;
import java.net.InetSocketAddress;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.io.*;

public class DeleteLiveStreamRecordIndexFiles {
    public static void main(String[] args) throws Exception {

        // HttpClient Configuration
        /*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
                .connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
                .responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
                .maxConnections(128) // Set the connection pool size
                .maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
                // Configure the proxy
                .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("<YOUR-PROXY-HOSTNAME>", 9001))
                        .setCredentials("<YOUR-PROXY-USERNAME>", "<YOUR-PROXY-PASSWORD>"))
                // If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
                .x509TrustManagers(new X509TrustManager[]{})
                .keyManagers(new KeyManager[]{})
                .ignoreSSL(false)
                .build();*/

        // Configure Credentials authentication information, including ak, secret, token
        StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
                .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
                .build());

        // Configure the Client
        AsyncClient client = AsyncClient.builder()
                .region("<Your RegionId>") // Region ID
                //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
                .credentialsProvider(provider)
                //.serviceConfiguration(Configuration.create()) // Service-level configuration
                // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
                .overrideConfiguration(
                        ClientOverrideConfiguration.create()
                                  // Endpoint 請參考 https://api.aliyun.com/product/live
                                .setEndpointOverride("live.aliyuncs.com")
                        //.setConnectTimeout(Duration.ofSeconds(30))
                )
                .build();

        // Parameter settings for API request
        DeleteLiveStreamRecordIndexFilesRequest deleteLiveStreamRecordIndexFilesRequest = DeleteLiveStreamRecordIndexFilesRequest.builder()
                .regionId("<Your RegionId>")
                .recordId(java.util.Arrays.asList(
                    "<Your RecordId_1>"
                ))
                .domainName("<Your DomainName>")
                .appName("<Your AppName>")
                .streamName("<Your StreamName>")
                .removeFile("<Your RemoveFile>")
                // Request-level configuration rewrite, can set Http request parameters, etc.
                // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
                .build();

        // Asynchronously get the return value of the API request
        CompletableFuture<DeleteLiveStreamRecordIndexFilesResponse> response = client.deleteLiveStreamRecordIndexFiles(deleteLiveStreamRecordIndexFilesRequest);
        // Synchronously get the return value of the API request
        DeleteLiveStreamRecordIndexFilesResponse resp = response.get();
        System.out.println(new Gson().toJson(resp));
        // Asynchronous processing of return values
        /*response.thenAccept(resp -> {
            System.out.println(new Gson().toJson(resp));
        }).exceptionally(throwable -> { // Handling exceptions
            System.out.println(throwable.getMessage());
            return null;
        });*/

        // Finally, close the client
        client.close();
    }

}
重要

方法三:OSS刪除

一般情況下,不建議您直接刪除儲存在OSS中的錄製檔案。如果需要刪除儲存在OSS中的錄製檔案,可以通過ApsaraVideo for Live刪除錄製檔案時同步刪除儲存在OSS中的檔案。如果您因為業務需求需要直接刪除儲存在OSS中的錄製檔案,可參考文檔OSS刪除檔案

其他刪除檔案方法

由於媒體資源均存放在OSS的Bucket中,需要授權訪問才能正常刪除錄製檔案,您可以點擊授權進行一鍵授權。

刪除超過6個月的檔案:由於只能查詢6個月以內的錄製檔案資訊,若要刪除超過6個月的檔案請通過OSS進行,詳情請參見OSS刪除檔案

到期刪除錄製檔案:完成授權後,再提交工單申請,我們會在後台為您配置您需要的到期時間。關於如何提交工單,請參見聯絡我們。配置到期時間後,錄製檔案到期刪除功能授權操作即為完成。

說明

雲資源訪問授權是對系統建立,供ApsaraVideo for Live使用授予訪問雲資源許可權的角色。授權後如果誤刪角色,可進行重新授權。

配置CDN網域名稱

如果您希望錄製的直播視頻能夠更快速的在網路中進行分發,可以配置一個CDN加速網域名稱。CDN將視頻分發到各地節點,使用者就近訪問而無需串連OSS來源站點,不僅可提升邊緣使用者的訪問速度和體驗,且外網流量費用僅為OSS的50%,有效節省網路費用。具體操作可參見OSS通過CDN加速訪問OSS

相關文檔

使用直播錄製時遇到問題,請參見直播錄製常見問題

使用Java SDK,請參見Java SDK使用說明

更多錄製回調功能使用,請參見直播錄製回調以及按需錄製回調