您可以通過視頻拼接功能,將多個視頻拼接為一個視頻並轉換為需要的格式。
功能簡介
視頻拼接是將多個視頻片段合并為一個完整視頻並轉換為所需格式的能力。

使用情境
影視製作:在電影、電視劇及短片的製作過程中,視頻拼接是核心環節之一,協助剪輯師將不同的鏡頭和情境整合,以構建完整的敘事結構。
內容創作:在短視頻社交媒體平台上,內容創作者通常運用視頻拼接技術製作Vlog、教程或主題視頻,以提升內容的吸引力和可視性。
教育與培訓:教師和培訓師可以通過拼接不同的視頻片段,以結合理論與實踐的方式製作教學視頻,從而促進學生的理解與學習。
體育賽事回放:在體育轉播中,視頻拼接技術被用於製作精彩瞬間集錦,以協助觀眾回顧比賽中激動人心的時刻。
如何使用
前提條件
已開通Intelligent Media Management(IMM)服務。具體操作,請參見開通產品。
已綁定IMM Project。通過OSS控制台綁定的具體操作,請參見步驟一:綁定IMM。通過API綁定的具體操作,請參見AttachOSSBucket - 綁定Object Storage Service桶。
視頻拼接
僅支援使用Java、Python、Go SDK通過非同步處理的方式完成視頻拼接。
Java
要求使用3.17.4及以上版本的Java SDK。
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.AsyncProcessObjectRequest;
import com.aliyun.oss.model.AsyncProcessObjectResult;
import com.aliyuncs.exceptions.ClientException;
import java.util.Base64;
public class Demo {
public static void main(String[] args) throws ClientException {
// yourEndpoint填寫Bucket所在地區對應的Endpoint。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 指定阿里雲通用Region ID,例如cn-hangzhou。
String region = "cn-hangzhou";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 指定Bucket名稱。
String bucketName = "examplebucket";
// 指定拼接後的視頻檔案名稱。
String targetObject = "dest.mp4";
// 指定原視頻檔案名稱。
String sourceVideo = "src.mp4";
// 指定需要拼接的視頻檔案名稱。
String video1 = "concat1.mp4";
String video2 = "concat2.mp4";
// 建立OSSClient執行個體。
// 當OSSClient執行個體不再使用時,調用shutdown方法以釋放資源。
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.build();
try {
// 對視頻檔案名稱進行編碼。
String video1Encoded = Base64.getUrlEncoder().withoutPadding().encodeToString(video1.getBytes());
String video2Encoded = Base64.getUrlEncoder().withoutPadding().encodeToString(video2.getBytes());
// 構建視頻處理樣式字串以及視頻拼接處理參數。
String style = String.format("video/concat,ss_0,f_mp4,vcodec_h264,fps_25,vb_1000000,acodec_aac,ab_96000,ar_48000,ac_2,align_1/pre,o_%s/sur,o_%s,t_0", video1Encoded, video2Encoded);
// 構建非同步處理指示。
String bucketEncoded = Base64.getUrlEncoder().withoutPadding().encodeToString(bucketName.getBytes());
String targetEncoded = Base64.getUrlEncoder().withoutPadding().encodeToString(targetObject.getBytes());
String process = String.format("%s|sys/saveas,b_%s,o_%s/notify,topic_QXVkaW9Db252ZXJ0", style, bucketEncoded, targetEncoded);
// 建立AsyncProcessObjectRequest對象。
AsyncProcessObjectRequest request = new AsyncProcessObjectRequest(bucketName, sourceVideo, process);
// 執行非同步處理任務。
AsyncProcessObjectResult response = ossClient.asyncProcessObject(request);
System.out.println("EventId: " + response.getEventId());
System.out.println("RequestId: " + response.getRequestId());
System.out.println("TaskId: " + response.getTaskId());
} finally {
// 關閉OSSClient。
ossClient.shutdown();
}
}
}Python
要求使用Python SDK 2.18.4及以上版本。
# -*- coding: utf-8 -*-
import base64
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
def main():
# 從環境變數中擷取臨時訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID、OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
endpoint = 'https://oss-cn-hangzhou.aliyuncs.com'
# 指定阿里雲通用Region ID,例如cn-hangzhou。
region = 'cn-hangzhou'
# 指定Bucket名稱,例如examplebucket。
bucket = oss2.Bucket(auth, endpoint, 'examplebucket', region=region)
# 指定拼接後的視頻名稱。
target_object = 'out.mp4'
# 指定原視頻檔案名稱。
source_video = 'emrfinal.mp4'
# 指定需要拼接的視頻檔案名稱。
video1 = 'osshdfs.mp4'
video2 = 'product.mp4'
# 構建視頻處理的樣式字串以及視頻拼接處理參數。
video1_encoded = base64.urlsafe_b64encode(video1.encode()).decode().rstrip('=')
video2_encoded = base64.urlsafe_b64encode(video2.encode()).decode().rstrip('=')
style = f"video/concat,ss_0,f_mp4,vcodec_h264,fps_25,vb_1000000,acodec_aac,ab_96000,ar_48000,ac_2,align_1/pre,o_{video1_encoded}/sur,o_{video2_encoded},t_0"
# 構建非同步處理指示。
bucket_encoded = base64.urlsafe_b64encode('examplebucket'.encode()).decode().rstrip('=')
target_encoded = base64.urlsafe_b64encode(target_object.encode()).decode().rstrip('=')
process = f"{style}|sys/saveas,b_{bucket_encoded},o_{target_encoded}/notify,topic_QXVkaW9Db252ZXJ0"
print(process)
# 執行非同步處理任務。
try:
result = bucket.async_process_object(source_video, process)
print(f"EventId: {result.event_id}")
print(f"RequestId: {result.request_id}")
print(f"TaskId: {result.task_id}")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()
Go
要求使用Go SDK 3.0.2及以上版本。
package main
import (
"encoding/base64"
"fmt"
"os"
"strings"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// 從環境變數中擷取臨時訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
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指定阿里雲通用Region ID,例如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名稱,例如examplebucket。
bucketName := "examplebucket"
bucket, err := client.Bucket(bucketName)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 填寫拼接後的視頻檔案名稱。
targetObject := "dest.mp4"
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 指定原視頻檔案名稱。
sourcevideo := "src.mp4"
// 指定需要拼接的視頻檔案名稱。
video1 := "concat1.mp4"
video2 := "concat2.mp4"
// 構建視頻處理的樣式字串以及視頻拼接處理參數。
style := fmt.Sprintf("video/concat,ss_0,f_mp4,vcodec_h264,fps_25,vb_1000000,acodec_aac,ab_96000,ar_48000,ac_2,align_1/pre,o_%s/sur,o_%s,t_0", strings.TrimRight(base64.URLEncoding.EncodeToString([]byte(video1)), "="), strings.TrimRight(base64.URLEncoding.EncodeToString([]byte(video2)), "="))
// 構建非同步處理指示。
process := fmt.Sprintf("%s|sys/saveas,b_%v,o_%v/notify,topic_QXVkaW9Db252ZXJ0", style, strings.TrimRight(base64.URLEncoding.EncodeToString([]byte(bucketName)), "="), strings.TrimRight(base64.URLEncoding.EncodeToString([]byte(targetObject)), "="))
fmt.Printf("%#v\n", process)
rs, err := bucket.AsyncProcessObject(sourcevideo, process)
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
fmt.Printf("EventId:%s\n", rs.EventId)
fmt.Printf("RequestId:%s\n", rs.RequestId)
fmt.Printf("TaskId:%s\n", rs.TaskId)
}由於非同步處理請求在返回時不會返回處理結果,如您需要擷取非同步任務的處理結果,可結合輕量訊息佇列SMQ(原MNS)使用,請參見訊息通知。
參數說明
操作名稱:video/concat
具體參數如下表所示。
拼接參數
video/concat的拼接順序按照pre與sur在請求串中的先後順序進行拼接,具體如下:
/pre:前置拼接的視頻檔案。/sur:後置拼接的視頻檔案。
參數 | 類型 | 是否必須 | 描述 |
ss | int | 否 | 首碼、尾碼視頻的拼接起始時間,單位為毫秒。取值:
|
t | int | 否 | 首碼、尾碼視頻的拼接持續時間長度,單位為毫秒。取值:
|
o | string | 是 | 當前Bucket下的OSS Object,需要以Base64 URL安全方式編碼。 |
轉碼參數
參數 | 類型 | 是否必須 | 描述 |
ss | int | 否 | 被拼接視頻的轉碼起始時間,單位為毫秒。取值:
|
t | int | 否 | 被拼接視頻的轉碼持續時間長度,單位為毫秒。取值:
|
f | string | 是 | 視頻容器,取值:
|
vn | int | 否 | 是否禁用視頻流。取值:
|
vcodec | string | 是 | 視頻codec(編碼格式)。取值:
說明 mxf與flv不支援h265。 |
fps | float | 否 | 視訊框架率。預設與align指定的源視頻一致,取值範圍為0~240。 |
fpsopt | int | 否 | 視訊框架率選項。取值:
說明 該參數需要與fps一同設定。 |
pixfmt | string | 否 | 像素採樣格式。預設與align指定的源視頻一致,取值:
|
s | string | 否 | 解析度。
|
sopt | int | 否 | 解析度選項。取值:
說明 該參數需要與s一同設定。 |
scaletype | string | 否 | 縮放方式。取值:
|
arotate | int | 否 | 自適應解析度方向。取值:
|
g | int | 否 | 主要畫面格間隔。預設值為150。取值範圍:1~100000。 |
vb | int | 否 | 視頻位元速率(碼率),單位為位元/秒(bps)。取值範圍:10000~100000000。 說明 該參數與crf互斥,表示不同碼率控制演算法。若都不設定則按照輸出解析度的預設碼率進行編碼。 |
vbopt | int | 否 | 視頻碼率選項。取值:
說明 該參數需要與vb一同設定。 |
crf | float | 否 | 碼率控制因子。取值範圍:0~51。數值越大畫質越差,建議取值範圍為18~38。 |
maxrate | int | 否 | 峰值碼率,單位為位元/秒(bps),預設為0。取值範圍:10000~100000000。 說明 該參數需要與crf一同設定。 |
bufsize | int | 否 | 緩衝區大小,單位為位元(bits),預設為0。取值範圍:10000~200000000。 說明 該參數需要與crf一同設定。 |
an | int | 否 | 是否禁用音頻流。取值:
|
acodec | string | 是 | 音頻codec(編碼格式)。取值:
說明 mp4不支援pcm;mov不支援flac與opus;asf不支援opus;avi不支援opus;mxf只支援pcm;ts不支援flac、vorbis、amr與pcm;flv不支援flac、vorbis、amr、opus與pcm。 |
ar | int | 否 | 音頻採樣率。預設與align指定的源視頻一致,取值:
說明 不同格式支援的採樣率有所不同,mp3僅支援48kHz及以下;opus支援8kHz、12kHz、16kHz、24kHz與48kHz;ac3支援32kHz、44.1kHz與48kHz;amr僅支援8kHz與16kHz。 |
ac | int | 否 | 音頻聲道數。預設與align指定的源視頻一致,取值範圍:1~8。 說明 不同格式支援的聲道數有所不同,mp3僅支援單、雙聲道;ac3最大支援6聲道(5.1);amr僅支援單聲道。 |
aq | int | 否 | 音頻壓縮品質。取值範圍:0~100。 說明 該參數與ab互斥,若都不設定則按照編碼器預設碼率進行編碼。 |
ab | int | 否 | 音頻位元速率(碼率)。單位為位元/秒(bps)。取值範圍:1000~10000000。 |
abopt | string | 否 | 音頻碼率選項。取值:
說明 該參數需要與ab一同設定。 |
align | int | 否 | 主視頻檔案(提供預設轉碼參數)在拼接列表中的序號,預設為0(對齊拼接列表中第一個視頻檔案)。 |
adepth | int | 否 | 音頻採樣位深,取值為16或24。 說明 該參數僅在acodec為flac時有效 |
媒體分區參數
/segment:分區參數
參數 | 類型 | 是否必須 | 描述 |
f | string | 是 | 分區格式。取值:
|
t | int | 是 | 分區長度,單位為毫秒。取值範圍:0~3600000。 |
媒體分區僅支援mp4與ts容器。
相關API
視頻拼接為mp4
拼接資訊
拼接前視頻名稱:pre.mov、example.mkv、sur.mov
拼接時間長度與順序:
視頻名稱
順序
時間長度
pre.mov
1
整段視頻
example.mkv
2
第10秒到結尾
sur.mov
3
開頭到第十秒
轉碼完成訊息通知:發送MNS訊息
拼接後視頻資訊
視頻格式:h264
視訊框架率:25fps
視頻碼率:1 Mbps
音頻格式:aac
音頻配置:48kHz採樣率,雙聲道
音頻碼率:96 Kbps
檔案儲存體路徑
mp4檔案:oss://outbucket/outobj.mp4
處理樣本
// 對檔案example.mkv進行視頻拼接。
POST /example.mkv?x-oss-async-process HTTP/1.1
Host: video-demo.oss-cn-hangzhou.aliyuncs.com
Date: Fri, 28 Oct 2022 06:40:10 GMT
Authorization: OSS4-HMAC-SHA256 Credential=LTAI********************/20250417/cn-hangzhou/oss/aliyun_v4_request,Signature=a7c3554c729d71929e0b84489addee6b2e8d5cb48595adfc51868c299c0c218e
x-oss-async-process=video/concat,ss_10000,f_mp4,vcodec_h264,fps_25,vb_1000000,acodec_aac,ab_96000,ar_48000,ac_2,align_1/pre,o_cHJlLm1vdgo/sur,o_c3VyMS5hYWMK,t_10000|sys/saveas,b_b3V0YnVja2V0,o_b3V0b2JqLnthdXRvZXh0fQo/notify,topic_QXVkaW9Db252ZXJ0許可權說明
阿里雲帳號預設擁有全部許可權。阿里雲帳號下的RAM使用者或RAM角色預設沒有任何許可權,需要阿里雲帳號或帳號管理員通過RAM Policy或Bucket Policy授予操作許可權。
API | Action | 說明 |
GetObject |
| 下載Object。 |
| 下載Object時,如果通過versionId指定了Object的版本,則需要授予此操作的許可權。 | |
| 下載Object時,如果Object的中繼資料套件含X-Oss-Server-Side-Encryption: KMS,則需要此操作的許可權。 |
API | Action | 說明 |
HeadObject |
| 擷取某個Object的中繼資料。 |
API | Action | 說明 |
PutObject |
| 上傳Object。 |
| 上傳Object時,如果通過x-oss-tagging指定Object的標籤,則需要此操作的許可權。 | |
| 上傳Object時,如果Object的中繼資料套件含X-Oss-Server-Side-Encryption: KMS,則需要這兩個操作的許可權。 | |
|
API | Action | 說明 |
CreateMediaConvertTask |
| 使用IMM進行媒體轉碼的許可權。 |
計費說明
在視頻拼接過程中,由於調用了 IMM 服務,會同時在 OSS 和 IMM 兩側產生計費項目。具體說明如下:
OSS 側: 需要調用 GetObject 介面添加 x-oss-async-process 參數進行視頻拼接,同時調用 HeadObject 介面以擷取 Object的中繼資料。拼接完成後,再通過 PutObject 介面將產生的視頻上傳至Bucket,將產生以下計費項目,詳細定價請參見OSS產品定價:
API
計費項目
說明
GetObject
GET 類型請求
根據成功的請求次數計算請求費用。
外網流出流量費用
如果是通過外網Endpoint(樣本值oss-cn-hangzhou.aliyuncs.com)或者傳輸加速Endpoint(樣本值oss-accelerate.aliyuncs.com)調用GetObject介面時,會產生外網流出流量費用,根據資料容量大小計費。
低頻訪問資料取回容量
如果取回的資料是低頻訪問資料,會產生低頻訪問資料取回容量的費用,按資料取回量計費。
歸檔直讀資料取回容量
如果讀取的是歸檔的Object且Bucket開啟了歸檔直讀,會產生歸檔直讀資料取回容量費用,根據取回的資料容量大小計費。
傳輸加速
如果開啟了傳輸加速功能且使用傳輸加速網域名稱訪問您的Bucket會產生傳輸加速費用,根據資料容量大小計費。
API
計費項目
說明
PutObject
PUT類型請求
根據成功的請求次數計算請求費用。
儲存費用
根據Object的儲存類型、大小和時間長度收取儲存費用。
API
計費項目
說明
HeadObject
GET 類型請求
根據成功的請求次數計算請求費用。
IMM 側: 將產生以下計費項目,詳細定價請參見IMM計費項目:
API
計費項目
說明
CreateMediaConvertTask
ApsaraVideo for Media Processing費用
根據拼接後視頻的清晰度和實際時間長度計算ApsaraVideo for Media Processing費用(以秒為單位)。
注意事項
視頻拼接僅支援非同步處理(x-oss-async-process處理方式)。
不支援匿名訪問。
當使用預設採樣率或聲道數進行轉碼時,拼接可能由於目標視頻容器的相容性而失敗。
進行視頻拼接時,最大支援的視頻數量為 11 個。