全部產品
Search
文件中心

Object Storage Service:視頻單幀截取

更新時間:Aug 06, 2025

當您需要擷取視頻封面、提取視頻主要畫面格映像進行視頻編輯,或者提取視頻中特定情境幀映像用於視頻監控時,可以將視頻上傳至OSS儲存空間,通過視頻截幀提取主要畫面格圖片。

注意事項

  • 僅支援對視頻編碼格式為H264和H265的視頻檔案進行視頻截幀。

  • OSS預設不儲存視頻截幀的圖片,視頻截幀的圖片需手動下載並儲存至本地。

  • 使用視頻截幀時,按視頻截幀截取的圖片數量計費。有關計費詳情的更多資訊,請參見資料處理費用

如何使用

前提條件

已在OSS中建立儲存空間(Bucket),上傳需要進行截幀的視頻至Bucket中。

視頻截幀

在OSS中,當您攜帶?x-oss-process=video/snapshot,parame_value參數時,OSS會即時處理並返回處理後的結果。video/snapshot表示進行視頻截幀處理;parame為支援的參數,value為參數取值。對於參數的詳細說明在下文參數說明中給出,且支援多個參數間的組合使用。

對於公用讀取的視頻,您可以直接在檔案URL後添加處理參數,以允許任何人永久匿名訪問處理後的檔案URL。如果您的視頻為私人類型,您需要調用SDK攜帶簽名資訊處理視頻。

公用讀取檔案

以下是公用讀取檔案URL添加?x-oss-process=video/snapshot,parame_value參數的操作說明,您只需要根據您的業務需求將parame_value替換為具體的參數和值。

原始URL

添加處理參數後的URL

https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/video.mp4

https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/video.mp4?x-oss-process=video/snapshot,t_7000,f_jpg,w_800,h_600,m_fast

私人檔案

您可以使用OSS SDK產生帶有處理參數的簽名URL,允許持有該URL的使用者臨時訪問處理後的視頻。使用SDK為私人視頻產生帶?x-oss-process=video/snapshot_value參數的簽名URL的樣本如下:

Java

package com.aliyun.oss.demo;
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 {
        // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";
        // 填寫視頻檔案的完整路徑。若視頻檔案不在Bucket根目錄,需攜帶檔案訪問路徑,例如examplefolder/videotest.mp4。
        String objectName = "examplefolder/videotest.mp4";
        // 填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為cn-hangzhou。
        String region = "cn-hangzhou";

        // 建立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 {
            // 使用精確時間模式截取視頻17s處的內容,輸出為JPG格式的圖片,寬度為800,高度為600。
            String style = "video/snapshot,t_17000,f_jpg,w_800,h_600";
            // 指定簽名URL到期時間
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L );
            GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
            req.setExpiration(expiration);
            req.setProcess(style);
            URL signedUrl = ossClient.generatePresignedUrl(req);
            System.out.println(signedUrl);
        } 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();
            }
        }
    }
}

Python

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# 填寫Bucket名稱
bucket = 'examplebucket'

# 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例
endpoint = 'https://oss-cn-hangzhou.aliyuncs.com'

# 填寫阿里雲通用Region ID
region = 'cn-hangzhou'
bucket = oss2.Bucket(auth, endpoint, bucket, region=region)

# 填寫視頻檔案的完整路徑。若視頻檔案不在Bucket根目錄,需攜帶檔案訪問路徑,例如examplefolder/videotest.mp4。
key = 'examplefolder/videotest.mp4'

# 指定到期時間,單位秒
expire_time = 3600

# 使用精確時間模式截取視頻17s處的內容,輸出為JPG格式的圖片,寬度為800,高度為600。
image_process = 'video/snapshot,t_17000,f_jpg,w_800,h_600'

# 產生簽名URL,帶上處理參數
url = bucket.sign_url('GET', key, expire_time, params={'x-oss-process': image_process}, slash_safe=True)

# 列印簽名URL
print(url)

PHP

<?php

if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;

// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "yourEndpoint";
// 填寫Bucket名稱,例如examplebucket。
$bucket= "examplebucket";
// 填寫視頻檔案的完整路徑。若視頻檔案不在Bucket根目錄,需攜帶檔案訪問路徑,例如examplefolder/videotest.mp4。
$object = "examplefolder/videotest.mp4";

$config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
        "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
        "region"=> "cn-hangzhou"
    );
    $ossClient = new OssClient($config);

// 產生一個帶處理參數的簽名的URL,有效期間是3600秒,可以直接使用瀏覽器訪問。
$timeout = 3600;

$options = array(
    // 使用精確時間模式截取視頻17s處的內容,輸出為JPG格式的圖片,寬度為800,高度為600。
    OssClient::OSS_PROCESS => "video/snapshot,t_17000,f_jpg,w_800,h_600");

$signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "GET", $options);
print("url: \n" . $signedUrl);

Go

package main

import (
	"fmt"
	"os"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func HandleError(err error) {
	fmt.Println("Error:", err)
	os.Exit(-1)
}

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填寫Bucket所在地區,以華東1(杭州)為例,填寫為cn-hangzhou。其它Region請按實際情況填寫。
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// 設定簽名版本
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		HandleError(err)
	}

	// 指定圖片所在Bucket的名稱,例如examplebucket。
	bucketName := "examplebucket"
	bucket, err := client.Bucket(bucketName)
	if err != nil {
		HandleError(err)
	}
	// 填寫視頻檔案的完整路徑。若視頻檔案不在Bucket根目錄,需攜帶檔案訪問路徑,例如examplefolder/videotest.mp4。
	ossName := "examplefolder/videotest.mp4"
	// 產生帶簽名的URL,並指定到期時間為3600s。
	// 使用精確時間模式截取視頻17s處的內容,輸出為JPG格式的圖片,寬度為800,高度為600。
	signedURL, err := bucket.SignURL(ossName, oss.HTTPGet, 3600, oss.Process("video/snapshot,t_17000,f_jpg,w_800,h_600"))
	if err != nil {
		HandleError(err)
	} else {
		fmt.Println(signedURL)
	}
}

Node.js

const OSS = require("ali-oss");

const client = new OSS({
  // yourregion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
  region: "oss-cn-hangzhou",
  // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  authorizationV4: true,
  // yourbucketname填寫儲存空間名稱。
  bucket: "examplebucket",
});
// 處理樣式"video/snapshot,t_17000,f_jpg,w_800,h_600"。
const signUrl = client.signatureUrl("examplefolder/videotest.mp4", {
  expires: 3600,
  process: "video/snapshot,t_17000,f_jpg,w_800,h_600",
});
console.log("signUrl=" + signUrl);

.NET

using Aliyun.OSS;
using Aliyun.OSS.Common;

// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID"); 
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 指定視頻所在Bucket的名稱,例如examplebucket。
var bucketName = "examplebucket";
// 指定名稱。如果視頻不在Bucket根目錄,需攜帶檔案完整路徑。
var objectName = "examplefolder/videotest.mp4";
// 填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。
const string region = "cn-hangzhou";

// 建立ClientConfiguration執行個體,按照您的需要修改預設參數。
var conf = new ClientConfiguration();

// 設定v4簽名。
conf.SignatureVersion = SignatureVersion.V4;

// 建立OssClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
client.SetRegion(region);
try
{
    // 視頻截幀。
    var process = "video/snapshot,t_17000,f_jpg,w_800,h_600";
    var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Get)
    {
        Expiration = DateTime.Now.AddHours(1),
        Process = process
    };
    // 產生帶有簽名的URI。
    var uri = client.GeneratePresignedUri(req);
    Console.WriteLine("Generate Presigned Uri:{0} with process:{1} succeeded ", uri, process);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}

C

#include "oss_api.h"
#include "aos_http_io.h"
/* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
const char *endpoint = "yourEndpoint";
/* 填寫Bucket名稱,例如examplebucket。*/
const char *bucket_name = "examplebucket";
/* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱。*/
const char *object_name = "examplefolder/videotest.mp4";
/* yourRegion填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。*/
const char *region = "yourRegion";
void init_options(oss_request_options_t *options)
{
    options->config = oss_config_create(options->pool);
    /* 用char*類型的字串初始化aos_string_t類型。*/
    aos_str_set(&options->config->endpoint, endpoint);
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
    aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
    //需要額外配置以下兩個參數
    aos_str_set(&options->config->region, region);
    options->config->signature_version = 4;
    /* 是否使用了CNAME。0表示不使用。*/
    options->config->is_cname = 0;
    /* 設定網路相關參數,比如逾時時間等。*/
    options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
    /* 在程式入口調用aos_http_io_initialize方法來初始化網路、記憶體等全域資源。*/
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }
    /* 用於記憶體管理的記憶體池(pool),等價於apr_pool_t。其實現代碼在apr庫中。*/
    aos_pool_t *pool;
    /* 重新建立一個記憶體池,第二個參數是NULL,表示沒有繼承其它記憶體池。*/
    aos_pool_create(&pool, NULL);
    /* 建立並初始化options,該參數包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全域配置資訊。*/
    oss_request_options_t *oss_client_options;
    /* 在記憶體池中分配記憶體給options。*/
    oss_client_options = oss_request_options_create(pool);
    /* 初始化Client的選項oss_client_options。*/
    init_options(oss_client_options);
    /* 初始化參數。*/
    aos_string_t bucket;
    aos_string_t object;
    aos_table_t *params = NULL;
    aos_http_request_t *req;
    char *url_str;
    apr_time_t now;
    int64_t expire_time; 
    aos_str_set(&bucket, bucket_name);
    aos_str_set(&object, object_name);
    params = aos_table_make(pool, 1);
    apr_table_set(params, OSS_PROCESS, "video/snapshot,t_17000,f_jpg,w_800,h_600");
    req = aos_http_request_create(pool);
    req->method = HTTP_GET;
    req->query_params = params;
    /* 指定到期時間(expire_time),單位為秒。*/
    now = apr_time_now();
    expire_time = now / 1000000 + 10 * 60;
    /* 產生簽名url。*/
    url_str = oss_gen_signed_url(oss_client_options, &bucket, &object, expire_time, req);
    printf("url: %s\n", url_str);
    /* 釋放該記憶體池,相當於釋放了請求過程中各資源分派的記憶體。*/
    aos_pool_destroy(pool);
    /* 釋放之前分配的全域資源。*/
    aos_http_io_deinitialize();
    return 0;
}

C++

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS帳號資訊。*/
            
    /* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* yourRegion填寫Bucket所在地區對應的Region。以華東1(杭州)為例,Region填寫為cn-hangzhou。*/
    std::string Region = "yourRegion";
    /* 填寫視頻所在的Bucket名稱,例如examplebucket。*/
    std::string BucketName = "examplebucket";
    /* 指定視頻名稱。如果圖片不在Bucket根目錄,需攜帶檔案完整路徑。*/
    std::string ObjectName = "examplefolder/videotest.mp4";

    /* 初始化網路等資源。*/
    InitializeSdk();

    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);


    /* 產生帶處理參數的檔案簽名URL。*/
    std::string Process = "video/snapshot,t_17000,f_jpg,w_800,h_600";
    GeneratePresignedUrlRequest request(BucketName, ObjectName, Http::Get);
    request.setProcess(Process);
    auto outcome = client.GeneratePresignedUrl(request);
	
    if (outcome.isSuccess()) {
    std::cout << "Generated presigned URL: " << outcome.result() << std::endl;
    } else {
    std::cout << "Failed to generate presigned URL. Error code: " << outcome.error().Code()
              << ", Message: " << outcome.error().Message()
              << ", RequestId: " << outcome.error().RequestId() << std::endl;
    }
    
    /* 釋放網路等資源。*/
    ShutdownSdk();
    return 0;
}

產生的簽名URL樣本如下:

https://examplebucket.oss-cn-hangzhou.aliyuncs.com/examplefolder/videotest.mp4?x-oss-process=video%2Fsnapshot%2Ct_17000%2Cf_jpg%2Cw_800%2Ch_600&x-oss-date=20250311T083843Z&x-oss-expires=3600&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI********************%2F20241111%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-signature=6fd07a2ba50bf6891474dc56aed976b556b6fbcd901cfd01bcde5399bf4802cb

參數說明

操作名稱:video/snapshot

參數

描述

取值範圍

t

指定截圖時間。如果設定的截圖時間t超過了視頻時間長度,則返回視頻的最後一個主要畫面格。

說明

如果需要截取視頻封面,則t設定為0。

[0,視頻時間長度]

單位:ms

w

指定截圖寬度,如果指定為0,則根據截圖高度與源視頻高度比例自動計算。

[0,視頻寬度]

單位:像素(px)

h

指定截圖高度,如果指定為0,則根據截圖寬度與源視頻寬度的比例自動計算;如果w和h都為0,則輸出為原視頻寬高。

[0,視頻高度]

單位:像素(px)

m

指定截圖模式,不指定則為預設模式,根據時間精確截圖。如果指定為fast,則截取該時間點之前的最近的一個主要畫面格。

枚舉值:fast

f

指定輸出圖片的格式。

枚舉值:jpgpng

ar

指定是否根據視頻資訊自動旋轉圖片。

枚舉值:autohw

各枚舉值說明如下:

  • auto:指定在截圖產生之後根據視頻資訊進行自動旋轉。

  • h:指定在截圖產生之後根據視頻資訊強制按高大於寬的模式旋轉。

  • w:指定在截圖產生之後根據視頻資訊強制按寬大於高的模式旋轉。

使用樣本

使用預設模式截取圖片

以下是添加?x-oss-process=video/snapshot,t_17000,f_jpg,w_800,h_600參數使用預設的精確時間模式截取視頻17s處的內容,輸出為JPG格式的圖片,寬度為800,高度為600:

原始URL

添加處理參數後的URL

https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/video.mp4

https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/video.mp4?x-oss-process=video/snapshot,t_17000,f_jpg,w_800,h_600

擷取到截幀後的圖片如下:

2

使用fast模式截取圖片

以下是添加?x-oss-process=video/snapshot,t_7000,f_jpg,w_800,h_600,m_fast參數使用fast模式截取視頻7s處的內容,輸出寬度為800,高度為600的JPG格式的圖片:

原始URL

添加處理參數後的URL

https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/video.mp4

https://oss-console-img-demo-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/video.mp4?x-oss-process=video/snapshot,t_7000,f_jpg,w_800,h_600,m_fast

擷取到截幀後的圖片如下:

1

常見問題

私人檔案能否通過連結拼接參數進行檔案處理?

不可以。對於不允許匿名訪問的私人視頻檔案,不支援通過檔案URL直接添加參數的方式處理視頻,您需要通過SDK的方式將視頻處理操作加入簽名URL中。

如何查看OSS中視頻的長寬尺寸?

您可以使用視頻資訊提取功能,擷取視頻的長寬尺寸。

視頻截幀得到的圖片出現失真

目前暫不支援對杜比視界的源視頻進行視頻截幀。

OSS上面視頻的封面可以通過視頻截幀擷取嗎,如何使它永久化?

可以,在擷取到該封面後,可以通過網路流的方式將其上傳至OSS,OSS將產生一個截圖檔案,此時該檔案即可實現永久儲存。