邊轉邊播是面向視頻線上播放需求的即時轉碼功能。通過閱讀本文,您可以瞭解邊轉邊播功能的優勢以及如何使用邊轉邊播。
功能簡介
不同於媒體轉碼需要在視頻上傳完成後等待整個視頻轉碼完成才能播放,邊轉邊播作為即時轉碼功能,可以實現原視頻檔案上傳完成後立即開始播放,並在播放時僅對需要播放的視頻片段進行轉碼。邊轉邊播主要能為您帶來:
邊播放邊轉碼,播放無需等待。
轉碼最佳化,秒級開播跳播,接近本地的播放體驗。
不播放不轉碼,即使轉碼檔案刪除了也能重新轉,顯著節省轉碼和儲存成本。
支援幾十種轉碼參數,轉碼參數可高度自訂。
相容性高,支援300+種音視頻格式。
邊轉邊播不支援匿名播放。
使用流程
將視頻檔案上傳到Object Storage Service。
通過GenerateVideoPlaylist介面快速產生媒體播放清單檔案,並使用OSS的簽名功能對播放清單進行簽名,最終擷取簽名後的播放清單。
播放器擷取播放清單進行播放,播放過程中自動觸發邊轉邊播功能。
使用情境
網盤:使用者上傳視頻到網盤,各種網盤用戶端立即能根據網路情況選擇不同的解析度進行播放。既保證了播放的即時性,又能確保視頻在不同裝置上的相容性。且網盤中大部分視頻都是冷視頻,使用邊轉邊播功能,沒有被使用者播放的視頻內容不會觸發轉碼,極大節省了轉碼和儲存成本。
聊天軟體視頻預覽:在即時通訊或社交媒體平台中,發送方把視頻發送完畢(服務端接收完成),接收方立刻可以開始播放視頻,提高交流的即時性。歷史聊天記錄中長期不被觀看的視頻,轉碼產生的視頻檔案可以定期清理以降低儲存成本,再次播放時亦可立刻播放。
網路論壇與部落格交流:使用邊轉邊播功能,使用者在要分享的原視頻上傳完成後,其他使用者可以立即播放轉碼後的視頻,同時保證視頻播放的流暢性、清晰度和相容性。
功能特性
邊轉邊播的更多功能特性如下表所示。
特性 | 說明 |
標準化 |
|
低成本 |
|
高效率 |
|
支援音視頻格式列表
邊轉邊播支援的音視頻格式有300多種,幾乎包含了所有常見的音視頻格式。下面是邊轉邊播支援的部分常見音視頻格式。
輸入視頻格式 | avi、mov、flv、mkv、webm、mpeg、wmv、rm、vob、ts等所有主流格式 |
輸入音頻格式 | mp3、wav、aac、flac、wma等所有主流格式 |
輸出容器格式 | ts |
前提條件
已開通OSS服務、建立儲存空間並上傳檔案到儲存空間。具體操作,請參見控制台快速入門。
已開通Intelligent Media Management服務並建立專案。具體操作,請參見開通產品和建立專案。
說明您也可以調用CreateProject介面建立專案。
您可以調用ListProjects - 列出所有專案資訊的列表介面列出指定地區下已建立的所有專案資訊。
使用邊轉邊播功能時,您需要為RAM使用者授予IMM處理所需的相關許可權。
使用邊轉邊播前,需要先綁定IMM Project。關於控制台和API如何綁定,請參見快速入門和AttachOSSBucket - 綁定Object Storage Service桶。
如您對源視頻或輸出目標視頻所在Bucket啟用了防盜鏈,請確保您設定“允許空Referer”的防盜鏈策略。
如您的播放器需跨域訪問OSS,請務必為目標視頻所在的Bucket啟用OSS跨域訪問,請參見:跨網域設定。
使用方法
使用Media Playlist樣本
轉碼資訊
源視頻資訊
視頻格式:AVI
視頻源地址:oss://your-oss-bucket-name/test.avi
目標視頻資訊
轉碼分區大小:10秒
預轉視頻長度:36秒
視頻流格式:H.264
視頻解析度:1280x720
視訊框架率:25 fps
視頻碼率:2 Mbps
音頻流格式:AAC
音頻碼率:128 Kbps
目標檔案儲存路徑首碼:oss://your-oss-bucket-name/output/media
步驟一:產生播放清單
請求樣本
{ "ProjectName": "test-project", "SourceURI": "oss://your-oss-bucket-name/test.avi", "Targets": [ { "Audio": { "TranscodeAudio": { "Codec": "aac", "Bitrate": 128000, "SampleRate": 44100 } }, "Duration": 10, "InitialSegments": [ 2, 2, 2 ], "InitialTranscode": 36, "URI": "oss://your-oss-bucket-name/output/media", "Video": { "TranscodeVideo": { "Codec": "h264", "Bitrate": 2400000, "FrameRate": 25, "Resolution": "1280x", "ScaleType": "fit" } } } ] }返回樣本
{ "RequestId": "********-3ADC-576A-BD1E-************", "VideoPlaylist": [ { "FrameRate": "25", "Resolution": "1280x720", "Token": "3d8ca7d6b3**********4b3cb69fe3bf", "URI": "oss://your-oss-bucket-name/output/media.m3u8" } ] }範例程式碼
# -*- coding: utf-8 -*- import json from alibabacloud_imm20200930 import models as imm_20200930_models from alibabacloud_imm20200930.client import Client as imm20200930Client from alibabacloud_tea_openapi import models as open_api_models class Sample: def __init__(self): pass @staticmethod def create_client( access_key_id: str, access_key_secret: str, ) -> imm20200930Client: """ 使用AccessKey ID和AccessKey Secret初始化帳號Client。 @param access_key_id: @param access_key_secret: @return: Client @throws Exception """ config = open_api_models.Config( # 填寫您的AccessKey ID。 access_key_id=access_key_id, # 填寫您的AccessKey Secret。 access_key_secret=access_key_secret ) # 填寫訪問的IMM網域名稱。 config.endpoint = f'imm.cn-hangzhou.aliyuncs.com' return imm20200930Client(config) @staticmethod def main() -> None: # 填寫IMM的AccessKey ID、AccessKey Secret,建議從配置中讀取。 imm_access_key_id = "yourAccessKeyId" imm_access_key_secret = "yourAccessKeySecret" # 填寫專案名稱。 project_name = "test-project" # 填寫源視頻的OSS URI。 source_uri = "oss://your-oss-bucket-name/test.avi" # 目標URI。 target_uri = "oss://your-oss-bucket-name/output/media" # 初始化用戶端。 client = Sample.create_client(imm_access_key_id, imm_access_key_secret) # 建立Target。 target = imm_20200930_models.GenerateVideoPlaylistRequestTargets( audio=imm_20200930_models.TargetAudio( transcode_audio=imm_20200930_models.TargetAudioTranscodeAudio( codec="aac", bitrate=128000, sample_rate=44100, ) ), duration=10, initial_segments=[2, 2, 2], initial_transcode=36, uri=target_uri, video=imm_20200930_models.TargetVideo( transcode_video=imm_20200930_models.TargetVideoTranscodeVideo( codec="h264", bitrate=2400000, frame_rate=25, resolution="1280x", scale_type="fit", ) ), ) # 建立API請求。 req = imm_20200930_models.GenerateVideoPlaylistRequest( project_name=project_name, source_uri=source_uri, targets=[target] ) # 列印API的請求值。 print(json.dumps(req.to_map(), indent=4)) # 發起請求 response = client.generate_video_playlist(req) # 列印API的傳回值。 print(json.dumps(response.body.to_map(), indent=4)) if __name__ == '__main__': Sample.main()package main import ( "fmt" openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" imm "github.com/alibabacloud-go/imm-20200930/v2/client" "github.com/alibabacloud-go/tea/tea" ) func main() { // 初始化IMM用戶端。 immClient, err := imm.NewClient(&openapi.Config{ RegionId: tea.String("cn-hangzhou"), // 填寫專案所在地區ID。 AccessKeyId: tea.String("your_access_key_id"), // 填寫RAM使用者的AccessKey ID。 AccessKeySecret: tea.String("your_access_key_secret"), // 填寫RAM使用者的AccessKey Secret。 }) if err != nil { // 錯誤處理。 panic(err) } // 填寫專案名稱。 projectName := "test-project" // 填寫視頻的OSS URI。 sourceUri := "oss://your-oss-bucket-name/test.avi" // 目標URI。 targetUri := "oss://your-oss-bucket-name/output/media" target := &imm.GenerateVideoPlaylistRequestTargets{ Audio: &imm.TargetAudio{ TranscodeAudio: &imm.TargetAudioTranscodeAudio{ Bitrate: tea.Int32(98304), Codec: tea.String("aac"), SampleRate: tea.Int32(44100), }, }, Duration: tea.Float32(10), InitialSegments: []*float32{tea.Float32(2), tea.Float32(2), tea.Float32(2)}, InitialTranscode: tea.Float32(36), URI: tea.String(targetUri), Video: &imm.TargetVideo{ TranscodeVideo: &imm.TargetVideoTranscodeVideo{ Codec: tea.String("h264"), Bitrate: tea.Int32(2400000), FrameRate: tea.Float32(25), Resolution: tea.String("1280x"), ScaleType: tea.String("fit"), }, }, } // 建立API請求。 req := &imm.GenerateVideoPlaylistRequest{ ProjectName: tea.String(projectName), SourceURI: tea.String(sourceUri), Targets: []*imm.GenerateVideoPlaylistRequestTargets{target}, } // 發起請求 res, err := immClient.GenerateVideoPlaylist(req) if err != nil { panic(err) } // 列印API的傳回值。 fmt.Println("Response:", *res.Body) }// This file is auto-generated, don't edit it. Thanks. package com.aliyun.sample; import com.aliyun.tea.*; public class Sample { /** * <b>description</b> : * <p>使用AK&SK初始化帳號Client</p> * @return Client * * @throws Exception */ public static com.aliyun.teaopenapi.Client createClient() throws Exception { // 工程代碼泄露可能會導致 AccessKey 泄露,並威脅帳號下所有資源的安全性。以下程式碼範例僅供參考。 // 建議使用更安全的 STS 方式,更多鑒權訪問方式請參見:https://www.alibabacloud.com/help/document_detail/378657.html。 com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config() // 必填,請確保代碼運行環境設定了環境變數 ALIBABA_CLOUD_ACCESS_KEY_ID。 .setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")) // 必填,請確保代碼運行環境設定了環境變數 ALIBABA_CLOUD_ACCESS_KEY_SECRET。 .setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")); // Endpoint 請參考 https://api.aliyun.com/product/imm config.endpoint = "imm.cn-beijing.aliyuncs.com"; return new com.aliyun.teaopenapi.Client(config); } /** * <b>description</b> : * <p>API 相關</p> * * @param path string Path parameters * @return OpenApi.Params */ public static com.aliyun.teaopenapi.models.Params createApiInfo() throws Exception { com.aliyun.teaopenapi.models.Params params = new com.aliyun.teaopenapi.models.Params() // 介面名稱 .setAction("GenerateVideoPlaylist") // 介面版本 .setVersion("2020-09-30") // 介面協議 .setProtocol("HTTPS") // 介面 HTTP 方法 .setMethod("POST") .setAuthType("AK") .setStyle("RPC") // 介面 PATH .setPathname("/") // 介面請求體內容格式 .setReqBodyType("json") // 介面響應體內容格式 .setBodyType("json"); return params; } public static void main(String[] args_) throws Exception { java.util.List<String> args = java.util.Arrays.asList(args_); com.aliyun.teaopenapi.Client client = Sample.createClient(); com.aliyun.teaopenapi.models.Params params = Sample.createApiInfo(); // query params java.util.Map<String, Object> queries = new java.util.HashMap<>(); queries.put("ProjectName", "test-project"); queries.put("SourceURI", "oss://your-oss-bucket-name/test.avi"); queries.put("Targets", "[{\"Video\":{\"TranscodeVideo\":{\"Codec\":\"h264\",\"Bitrate\":128000,\"FrameRate\":25,\"Resolution\":\"1280x\"}},\"Audio\":{\"TranscodeAudio\":{\"SampleRate\":44100,\"Codec\":\"aac\",\"Bitrate\":2400000}},\"Duration\":10,\"InitialSegments\":[2,2,2],\"InitialTranscode\":36,\"URI\":\"oss://your-oss-bucket-name/output/media\"}]"); // runtime options com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions(); com.aliyun.teaopenapi.models.OpenApiRequest request = new com.aliyun.teaopenapi.models.OpenApiRequest() .setQuery(com.aliyun.openapiutil.Client.query(queries)); // 複製代碼運行請自行列印 API 的傳回值 // 傳回值實際為 Map 類型,可從 Map 中獲得三類資料:響應體 body、回應標頭 headers、HTTP 返回的狀態代碼 statusCode。 client.callApi(params, request, runtime); } }
步驟二:對播放清單簽名
# -*- coding: utf-8 -*-
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請先配置環境變數。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# 填寫Bucket所在地區對應的Endpoint。請按實際情況填寫。
endpoint = 'yourEndpoint'
# 填寫Endpoint對應的Region資訊,例如cn-hangzhou。
region = 'cn-hangzhou'
# 目標Bucket名稱。
bucket_name = 'your-oss-bucket-name'
# 填寫產生的播放清單名稱。
key = 'output/media.m3u8'
# 指定Bucket執行個體,所有檔案相關的方法都需要通過Bucket執行個體來調用。
bucket = oss2.Bucket(auth, endpoint, bucket_name, region=region)
# x-oss-process的處理方式為hls/sign,live_1。
params = {}
params.update({oss2.Bucket.PROCESS: 'hls/sign,live_1'})
# 簽名URL。
url = bucket.sign_url('GET', key, 7200, params=params, slash_safe=True)
# 產生的URL可以直接在HLS播放器中播放。
print(url)
# 本例產生的URL: http://your-oss-bucket-name.yourendpoint/output/media.m3u8?x-oss-process=hls%2Fsign%2Clive_1&x-oss-signature-version=OSS2&x-oss-expires=1683619052&x-oss-access-key-id=yourAccessKeyId&x-oss-signature=4Lja6Sgb7zXWzY9R9QTRe4FxI240fApDavp%2BSMj3ufg%3D
package main
import (
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"net/http"
"net/url"
"os"
"strings"
)
func main() {
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請先配置環境變數。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 建立OSSClient執行個體。
// yourEndpoint填寫Bucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
// yourRegion填寫Endpoint對應的Region資訊,例如cn-hangzhou。
client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider), oss.AuthVersion(oss.AuthV4), oss.Region("yourRegion"))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 填寫Bucket名稱,例如your-oss-bucket-name。
bucket, err := client.Bucket("your-oss-bucket-name")
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 使用oss hls/sign簽名。"hls/sign,live_1" 是指使用邊轉邊播的能力,為固定的格式。
// 填寫m3u8的完整路徑,例如output/media.m3u8。
// 填寫簽名的有效時間,例如7200,兩個小時有效。
signedURL, err := bucket.SignURL("output/media.m3u8", http.MethodGet, 7200, oss.Process("hls/sign,live_1"))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 轉換為可供播放器使用的URL。
rawUrl, err := url.Parse(signedURL)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
rawUrl.RawPath = strings.Replace(rawUrl.RawPath, "%2F", "/", -1)
// 列印輸出簽名後的URL。
fmt.Println(rawUrl.String())
// 簽名輸出URL可以直接粘貼到HLS播放器中播放。
//http://your-oss-bucket-name.yourEndpoint/output/media.m3u8?x-oss-access-key-id=yourAccessKeyId&x-oss-expires=1683618084&x-oss-process=hls%2Fsign%2Clive_1&x-oss-signature=%2BqTZ0R04Ft065gdyoP6f9yJdd1UXi%2F8eoxd9c9Stl2g%3D&x-oss-signature-version=OSS2
}
package com.aliyun.sample;
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import java.net.URL;
import java.util.Date;
public class demo {
public static void main(String[] args) throws Throwable {
// 以華東2(北京)的外網Endpoint為例,其它Region請按實際情況填寫。
String endpoint = "https://oss-cn-beijing.aliyuncs.com";
String region = "cn-beijing";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
// 必填,請確保代碼運行環境設定了環境變數 ALIBABA_CLOUD_ACCESS_KEY_ID。
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
// 必填,請確保代碼運行環境設定了環境變數 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "test-project";
// 填寫Object完整路徑,例如exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectKey = "output/media.m3u8";
// 建立OSSClient執行個體。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
// 設定URL到期時間
Date expiration = new Date(new Date().getTime() + 7200 * 1000); // 2小時
GeneratePresignedUrlRequest request=new GeneratePresignedUrlRequest(bucketName, objectKey, HttpMethod.GET);
request.setExpiration(expiration);
request.setProcess("hls/sign,live_1");
// 產生簽名URL
URL signedUrl = ossClient.generatePresignedUrl(request);
// 輸出簽名URL
System.out.println(signedUrl);
// 關閉OSS用戶端
// 關閉OSSClient。
ossClient.shutdown();
try {
// 設定簽名URL到期時間,單位為毫秒。本樣本以設定到期時間為1小時為例。
URL url = ossClient.generatePresignedUrl(bucketName, objectKey, expiration);
System.out.println(url);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
步驟三:播放視頻
步驟二:對播放清單簽名中產生的簽名後的URL,可以直接粘貼到HLS播放器中播放,操作方法如下。
Mac使用Safari播放
Mac系統的Safari播放器支援HLS視頻播放,您可以直接粘貼URL到Safari地址欄播放。
使用Aliplayer播放
開啟阿里雲Aliplayer播放器,粘貼URL到地址欄後播放,如下圖所示。
說明您也可以整合阿里雲播放器SDK到您的業務系統中,在您的業務系統中播放。具體操作,請參見Web播放器簡介。

使用HLS播放器播放
把簽名後的URL粘貼到HLS播放器中。
使用Master Playlist樣本
轉碼資訊
源視頻資訊
視頻格式:AVI
視頻源地址:oss://your-oss-bucket-name/test.avi
Master playlist地址:oss://your-oss-bucket-name/output/master.m3u8
目標視頻資訊1
轉碼分區大小:10秒
預轉視頻長度:36秒
視頻流格式:H.264
視頻解析度:1920x1080
視訊框架率:25 fps
音頻流格式:AAC
音頻碼率:128 Kbps
目標檔案儲存路徑首碼:oss://your-oss-bucket-name/output/1080p/1080p
目標視頻資訊2
轉碼分區大小:10秒
預轉視頻長度:36秒
視頻流格式:H.264
視頻解析度:1280x720
視訊框架率:25 fps
音頻流格式:AAC
音頻碼率:96 Kbps
目標檔案儲存路徑首碼:oss://your-oss-bucket-name/output/720p/720p
目標視頻資訊3
轉碼分區大小:10秒
預轉視頻長度:36秒
視頻流格式:H.264
視頻解析度:720x540
視訊框架率:25 fps
音頻流格式:AAC
音頻碼率:64 Kbps
目標檔案儲存路徑首碼:oss://your-oss-bucket-name/output/540p/540p
步驟一:產生播放清單
請求樣本
{ "MasterURI": "oss://your-oss-bucket-name/output/master.m3u8", "ProjectName": "test-project", "SourceSubtitles": [], "SourceURI": "oss://your-oss-bucket-name/test.avi", "Targets": [ { "Audio": { "TranscodeAudio": { "Bitrate": 131072, "Codec": "aac", "SampleRate": 44100 } }, "Duration": 10, "InitialSegments": [ 2, 2, 2 ], "InitialTranscode": 36, "URI": "oss://your-oss-bucket-name/output/1080p/1080p", "Video": { "TranscodeVideo": { "CRF": 26, "Codec": "h264", "FrameRate": 25, "Resolution": "1920x", "ScaleType": "fit" } } }, { "Audio": { "TranscodeAudio": { "Bitrate": 98304, "Codec": "aac", "SampleRate": 44100 } }, "Duration": 10, "InitialSegments": [ 2, 2, 2 ], "InitialTranscode": 36, "URI": "oss://your-oss-bucket-name/output/720p/720p", "Video": { "TranscodeVideo": { "CRF": 26, "Codec": "h264", "FrameRate": 25, "Resolution": "1280x", "ScaleType": "fit" } } }, { "Audio": { "TranscodeAudio": { "Bitrate": 65536, "Codec": "aac", "SampleRate": 44100 } }, "Duration": 10, "InitialSegments": [ 2, 2, 2 ], "InitialTranscode": 36, "URI": "oss://your-oss-bucket-name/output/540p/540p", "Video": { "TranscodeVideo": { "CRF": 26, "Codec": "h264", "FrameRate": 25, "Resolution": "720x", "ScaleType": "fit" } } } ] }返回樣本
{ "Duration": 60.085, "MasterURI": "oss://your-oss-bucket-name/output/master.m3u8", "RequestId": "********-3ADC-576A-BD1E-************", "Token": "1deb790e****************231a6f9d", "VideoPlaylist": [ { "FrameRate": "25", "Resolution": "720x406", "Token": "8bcd9bc0****************67a65f48", "URI": "oss://your-oss-bucket-name/output/540p/540p.m3u8" }, { "FrameRate": "25", "Resolution": "1280x720", "Token": "89ca4337****************cd031957", "URI": "oss://your-oss-bucket-name/output/720p/720p.m3u8" }, { "FrameRate": "25", "Resolution": "1920x1080", "Token": "11fb1afb****************4f3683fc", "URI": "oss://your-oss-bucket-name/output/1080p/1080p.m3u8" } ] }範例程式碼
# -*- coding: utf-8 -*- import json from alibabacloud_imm20200930 import models as imm_20200930_models from alibabacloud_imm20200930.client import Client as imm20200930Client from alibabacloud_tea_openapi import models as open_api_models class Sample: def __init__(self): pass @staticmethod def create_client( access_key_id: str, access_key_secret: str, ) -> imm20200930Client: """ 使用AccessKey ID和AccessKey Secret初始化帳號Client。 @param access_key_id: @param access_key_secret: @return: Client @throws Exception """ config = open_api_models.Config( # 填寫您的AccessKey ID。 access_key_id=access_key_id, # 填寫您的AccessKey Secret。 access_key_secret=access_key_secret ) # 填寫訪問的IMM網域名稱。 config.endpoint = f'imm.cn-hangzhou.aliyuncs.com' return imm20200930Client(config) @staticmethod def main() -> None: # 填寫IMM的AccessKey ID、AccessKey Secret,建議從配置中讀取。 imm_access_key_id = "yourAccessKeyId" imm_access_key_secret = "yourAccessKeySecret" # 填寫專案名稱。 project_name = "test-project" # 填寫源視頻的OSS URI。 source_uri = "oss://your-oss-bucket-name/test.avi" # 目標URI。 target_uri_prefix = "oss://your-oss-bucket-name/output" master_uri = f"{target_uri_prefix}/master.m3u8" target_1080p_uri = f"{target_uri_prefix}/1080p/1080p" target_720p_uri = f"{target_uri_prefix}/720p/720p" target_540p_uri = f"{target_uri_prefix}/540p/540p" # 初始化用戶端。 client = Sample.create_client(imm_access_key_id, imm_access_key_secret) # 建立 1080p Target。 target_1080p = imm_20200930_models.GenerateVideoPlaylistRequestTargets( audio=imm_20200930_models.TargetAudio( transcode_audio=imm_20200930_models.TargetAudioTranscodeAudio( codec="aac", bitrate=131072, sample_rate=44100, ) ), duration=10, initial_segments=[2, 2, 2], initial_transcode=36, uri=target_1080p_uri, video=imm_20200930_models.TargetVideo( transcode_video=imm_20200930_models.TargetVideoTranscodeVideo( codec="h264", crf=26, frame_rate=25, resolution="1920x", scale_type="fit", ) ), ) # 建立 720p Target。 target_720p = imm_20200930_models.GenerateVideoPlaylistRequestTargets( audio=imm_20200930_models.TargetAudio( transcode_audio=imm_20200930_models.TargetAudioTranscodeAudio( codec="aac", bitrate=98304, sample_rate=44100, ) ), duration=10, initial_segments=[2, 2, 2], initial_transcode=36, uri=target_720p_uri, video=imm_20200930_models.TargetVideo( transcode_video=imm_20200930_models.TargetVideoTranscodeVideo( codec="h264", crf=26, frame_rate=25, resolution="1280x", scale_type="fit", ) ), ) # 建立 540p Target。 target_540p = imm_20200930_models.GenerateVideoPlaylistRequestTargets( audio=imm_20200930_models.TargetAudio( transcode_audio=imm_20200930_models.TargetAudioTranscodeAudio( codec="aac", bitrate=65536, sample_rate=44100, ) ), duration=10, initial_segments=[2, 2, 2], initial_transcode=36, uri=target_540p_uri, video=imm_20200930_models.TargetVideo( transcode_video=imm_20200930_models.TargetVideoTranscodeVideo( codec="h264", crf=26, frame_rate=25, resolution="720x", scale_type="fit", ) ), ) # 建立API請求。 req = imm_20200930_models.GenerateVideoPlaylistRequest( project_name=project_name, source_uri=source_uri, master_uri=master_uri, targets=[target_1080p, target_720p, target_540p] ) # 列印API的請求值。 print(json.dumps(req.to_map(), indent=4)) # 發起請求 response = client.generate_video_playlist(req) # 列印API的傳回值。 print(json.dumps(response.body.to_map(), indent=4)) if __name__ == '__main__': Sample.main()package main import ( "fmt" openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client" imm "github.com/alibabacloud-go/imm-20200930/v2/client" "github.com/alibabacloud-go/tea/tea" ) func main() { // 初始化IMM用戶端。 immClient, err := imm.NewClient(&openapi.Config{ RegionId: tea.String("cn-hangzhou"), // 填寫專案所在地區ID。 AccessKeyId: tea.String("your_access_key_id"), // 填寫RAM使用者的AccessKey ID。 AccessKeySecret: tea.String("your_access_key_secret"), // 填寫RAM使用者的AccessKey Secret。 }) if err != nil { // 錯誤處理。 panic(err) } // 填寫專案名稱。 projectName := "test-project" // 填寫視頻的OSS URI。 sourceUri := "oss://your-oss-bucket-name/test.avi" // 目標URI。 targetURIPrefix := "oss://your-oss-bucket-name/output" masterURI := targetURIPrefix + "/master.m3u8" target1080pURI := targetURIPrefix + "/1080p/1080p" target720pURI := targetURIPrefix + "/720p/720p" target540pURI := targetURIPrefix + "/540p/540p" target1080p := &imm.GenerateVideoPlaylistRequestTargets{ Audio: &imm.TargetAudio{ TranscodeAudio: &imm.TargetAudioTranscodeAudio{ Bitrate: tea.Int32(131072), Codec: tea.String("aac"), SampleRate: tea.Int32(44100), }, }, Duration: tea.Float32(10), InitialSegments: []*float32{tea.Float32(2), tea.Float32(2), tea.Float32(2)}, InitialTranscode: tea.Float32(36), URI: tea.String(target1080pURI), Video: &imm.TargetVideo{ TranscodeVideo: &imm.TargetVideoTranscodeVideo{ Codec: tea.String("h264"), CRF: tea.Float32(26), FrameRate: tea.Float32(25), Resolution: tea.String("1920x"), ScaleType: tea.String("fit"), }, }, } target720p := &imm.GenerateVideoPlaylistRequestTargets{ Audio: &imm.TargetAudio{ TranscodeAudio: &imm.TargetAudioTranscodeAudio{ Bitrate: tea.Int32(98304), Codec: tea.String("aac"), SampleRate: tea.Int32(44100), }, }, Duration: tea.Float32(10), InitialSegments: []*float32{tea.Float32(2), tea.Float32(2), tea.Float32(2)}, InitialTranscode: tea.Float32(36), URI: tea.String(target720pURI), Video: &imm.TargetVideo{ TranscodeVideo: &imm.TargetVideoTranscodeVideo{ Codec: tea.String("h264"), CRF: tea.Float32(26), FrameRate: tea.Float32(25), Resolution: tea.String("1280x"), ScaleType: tea.String("fit"), }, }, } target540p := &imm.GenerateVideoPlaylistRequestTargets{ Audio: &imm.TargetAudio{ TranscodeAudio: &imm.TargetAudioTranscodeAudio{ Bitrate: tea.Int32(65536), Codec: tea.String("aac"), SampleRate: tea.Int32(44100), }, }, Duration: tea.Float32(10), InitialSegments: []*float32{tea.Float32(2), tea.Float32(2), tea.Float32(2)}, InitialTranscode: tea.Float32(36), URI: tea.String(target540pURI), Video: &imm.TargetVideo{ TranscodeVideo: &imm.TargetVideoTranscodeVideo{ Codec: tea.String("h264"), CRF: tea.Float32(26), FrameRate: tea.Float32(25), Resolution: tea.String("720x"), ScaleType: tea.String("fit"), }, }, } // 建立API請求。 req := &imm.GenerateVideoPlaylistRequest{ ProjectName: tea.String(projectName), SourceURI: tea.String(sourceUri), MasterURI: tea.String(masterURI), Targets: []*imm.GenerateVideoPlaylistRequestTargets{target1080p, target720p, target540p}, } // 發起請求 res, err := immClient.GenerateVideoPlaylist(req) if err != nil { panic(err) } // 列印API的傳回值。 fmt.Println("Response:", *res.Body) }
步驟二:對播放清單簽名
您需要對返回的master playlist進行OSS URL簽名。簽名方式請參見步驟二:對播放清單簽名。
步驟三:播放視頻
播放方式請參見步驟三:播放視頻。
常見問題
需要使用定製的播放器嗎?
不需要。邊轉邊播功能支援標準的HLS協議,您使用支援標準HLS協議的播放器(例如:阿里雲Aliplayer播放器,Safari瀏覽器)即可使用邊轉邊播功能。
輸出檔案包括有哪些?
我們會根據您指定的輸入路徑首碼產生m3u8檔案和ts檔案,m3u8檔案立刻產生。
如果您指定了預轉時間長度,系統將非同步產生與該預轉時間長度相對應的TS檔案。未指定預轉的部分將在視頻播放時按需觸發非同步轉碼。如果視頻從未播放,則不會為未指定預轉的部分產生TS檔案。例如,如果視頻從15分鐘的位置開始播放,系統僅會從該位置開始進行轉碼。相應產生的檔案分類樹如下:
.
├── outobjprefix.m3u8
├── outobjprefix-c280f054328fcde47c1732a8f2915009-0.ts
├── outobjprefix-c280f054328fcde47c1732a8f2915009-1.ts
├── outobjprefix-c280f054328fcde47c1732a8f2915009-2.ts
├── outobjprefix-c280f054328fcde47c1732a8f2915009-3.ts已經產生的ts檔案手動刪除後能正常播放嗎?
可以。只要視頻源檔案和m3u8播放清單未被刪除,手動刪除部分或全部ts檔案後,視頻仍能正常播放。這是因為當m3u8播放清單再次被請求時,會觸發ts檔案的重建。這種方法允許對之前已播放但長時間未被觀看的視頻的ts檔案進行清理,從而減少儲存成本,而不影響視頻未來的重新播放。
能使用非邊轉邊播的m3u8檔案做邊轉邊播嗎?
不允許使用非邊轉邊播產生的m3u8檔案來實現邊轉邊播功能。
能使用CDN為邊轉邊播加速嗎?
可以。詳情參見使用CDN為邊轉邊播加速。