すべてのプロダクト
Search
ドキュメントセンター

Intelligent Media Management:ストリーミング中のトランスコード

最終更新日:Jun 19, 2026

ストリーミング同時トランスコードは、オンラインビデオ再生向けのリアルタイムトランスコーディング機能で、アップロード直後から再生が始まり、視聴中のセグメントのみをトランスコードします。

概要

アップロード後に動画全体のトランスコーディング完了を待ってから再生を開始する必要がある ApsaraVideo Media Processing とは異なり、ストリーミングトランスコードはソース動画のアップロード完了後すぐに再生を開始します。再生に必要な動画セグメントのみをトランスコードします。このアプローチには、以下の特長があります:

  • 再生中のトランスコーディング — 待機は不要です。

  • 1 秒未満の起動とシーク時間を実現する最適化されたトランスコーディング — ローカル再生に近い体験。

  • 再生がない場合はトランスコードされません。トランスコードされたファイルが削除されても、オンデマンドで再生成できます — トランスコーディングとストレージのコストの大幅な削減。

  • 数十のトランスコーディングパラメーターをサポート — 高度にカスタマイズ可能な設定。

  • 高い互換性 — 300 種類以上のオーディオとビデオのフォーマットに対応。

説明

ストリーミングトランスコードは匿名再生をサポートしていません。

ワークフロー

  1. ビデオファイルを Object Storage Service (OSS) にアップロードします。

  2. GenerateVideoPlaylist API を使用して、メディアプレイリストファイルを迅速に生成します。OSS の署名機能を使用してプレイリストに署名し、署名済みプレイリスト URL を取得します。

  3. プレーヤーは署名済みプレイリストを取得して再生を開始します。再生中に、ストリーミング中のトランスコード機能が自動的に作動します。

image

シナリオ

  • クラウドストレージ:ユーザーは動画をクラウドドライブにアップロードします。クライアントはネットワーク状況に基づき、再生に適した解像度を即座に選択します。これにより、リアルタイム再生とクロスデバイス互換性が確保されます。クラウドストレージ内の動画の大半はアクセス頻度が低い (「コールド」) ため、ストリーミング中のトランスコードでは未再生コンテンツをトランスコードしないことで、トランスコーディングコストとストレージコストを大幅に削減します。

  • チャットアプリの動画プレビュー:インスタントメッセージ (IM) やソーシャルプラットフォームでは、送信者がアップロードを完了 (サーバーがファイルを受信) すると、受信者はすぐに再生を開始できます。これにより、リアルタイムコミュニケーションが向上します。長期間視聴されていない過去メッセージのトランスコード済みファイルは、ストレージコストを抑えるために定期的にクリーンアップできます。また、再アクセス時も即座に再生できます。

  • オンラインフォーラムとブログ:ユーザーが共有用のソース動画をアップロードすると、ほかのユーザーはトランスコード済みバージョンをすぐに再生できます。これにより、スムーズな再生、高画質、幅広いフォーマットへの互換性が確保されます。

機能

次の表で、追加の機能について説明します。

機能

説明

標準化

  • 標準の HTTP Live Streaming (HLS) プロトコルをサポートします。

  • メディアプレイリストとマスタープレイリストの生成をサポートします。

  • マルチビデオストリーム、マルチオーディオストリーム、マルチキャプションストリームの再生をサポートします。

  • 主要な HLS プレーヤーと互換性があります。

  • 300 種類以上の主要なオーディオおよびビデオフォーマットをサポートします。

低コスト

  • 再生されていない動画やセグメントはトランスコードされないため、トランスコードコストが削減されます。

  • トランスコード済みの動画セグメントを削除して、ストレージコストを節約できます。再再生時には、システムが自動的に新しいトランスコードをトリガーし、シームレスな再生を維持します。

高効率

  • 大規模クラスターがリアルタイムトランスコードをサポートします。

  • さまざまなネットワーク条件に適応し、スムーズな再生を確保するために、解像度とビットレートが異なる複数のビデオストリームを提供します。

  • プレイリスト生成後、完全なトランスコードを待つ必要なく、すぐに再生が開始されます。

  • ビデオヘッダーに対応するアダプティブセグメントサイズにより、初期ロードが高速化されます。

  • インテリジェントな事前トランスコード。

対応オーディオおよびビデオフォーマット

ストリーミング中のトランスコードは、300 種類以上のオーディオおよびビデオフォーマットをサポートしています。次の表に、一般的にサポートされているフォーマットの一部を示します。

入力ビデオフォーマット

avi、mov、flv、mkv、webm、mpeg、wmv、rm、vob、ts、およびその他すべての主流フォーマット

入力オーディオフォーマット

mp3、wav、aac、flac、wma、およびその他すべての主流フォーマット

出力コンテナフォーマット

ts

前提条件

  1. AccessKey を作成し、取得します

  2. Object Storage Service (OSS) を有効化し、バケットを作成してファイルをアップロードします。 詳細については、「コンソールでのクイックスタート」をご参照ください。

  3. Intelligent Media Management (IMM) を有効化し、プロジェクトを作成します。 詳細については、「サービスの有効化」および「プロジェクトの作成」をご参照ください。

    説明

    CreateProject API を呼び出してプロジェクトを作成することもできます。

    ListProjects API を呼び出して、指定したリージョン内のすべてのプロジェクトを一覧表示できます。

  4. Resource Access Management (RAM) ユーザーに、IMM 操作に必要な権限を付与します。

  5. ストリーミング中のトランスコードを使用する前に、IMM プロジェクトをバインドします。 コンソールまたは API でのバインド手順については、「クイックスタート」および「OSS バケットのバインド」をご参照ください。

  6. ソース動画または出力動画を含むバケットでホットリンク保護が有効になっている場合、ホットリンク保護ポリシーが empty Referer を許可することを確認してください。

  7. プレーヤーが OSS へのクロスドメインアクセスを必要とする場合は、ターゲットバケットに対して OSS のオリジン間リソース共有 (CORS) を有効にしてください。 「CORS 設定」をご参照ください。

使用方法

メディアプレイリストの例

トランスコーディング設定

  • ソースビデオ情報

    • フォーマット:AVI

    • ソース URI:oss://your-oss-bucket-name/test.avi

  • ターゲットビデオ

    • セグメント期間:10 秒

    • 先行トランスコード期間:36 秒

    • ビデオコーデック:H.264

    • 解像度:1280×720

    • フレームレート:25 fps

    • ビデオビットレート:2 Mbps

    • オーディオコーデック:AAC

    • オーディオビットレート:128 Kbps

    • 出力パスプレフィックス:oss://your-oss-bucket-name/output/media

ステップ 1:プレイリストの生成

説明

ライブトランスコーディングプレイリストの生成 API ドキュメントをご参照ください。

  • リクエストの例

    {
      "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 を使用してクライアントを初期化します。
            @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 と 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 = 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]
            )
            # リクエストを出力します。
            print(json.dumps(req.to_map(), indent=4))
            # リクエストを送信します。
            response = client.generate_video_playlist(req)
            # レスポンスを出力します。
            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(128000),
    				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)
    	}
    	// レスポンスを出力します。
    	fmt.Println("Response:", *res.Body)
    }
    // このファイルは自動生成されたものです。編集しないでください。ありがとうございます。
    package com.aliyun.sample;
    import com.aliyun.tea.*;
    public class Sample {
        /**
         * description:
         * <p>AK & SK を使用してクライアントを初期化します</p>
         * @return Client
         * 
         * @throws Exception
         */
        public static com.aliyun.teaopenapi.Client createClient() throws Exception {
            // 認証情報が漏洩すると、アカウント内のすべてのリソースが危険にさらされる可能性があります。この例は参照用です。
            // セキュリティを向上させるために 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"));
            // エンドポイント: https://api.aliyun.com/product/imm
            config.endpoint = "imm.cn-beijing.aliyuncs.com";
            return new com.aliyun.teaopenapi.Client(config);
        }
        /**
         * description:
         * <p>API 情報</p>
         * 
         * @param path string パスパラメーター
         * @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()
                    // API 名
                    .setAction("GenerateVideoPlaylist")
                    // API バージョン
                    .setVersion("2020-09-30")
                    // プロトコル
                    .setProtocol("HTTPS")
                    // HTTP メソッド
                    .setMethod("POST")
                    .setAuthType("AK")
                    .setStyle("RPC")
                    // パス
                    .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();
            // クエリパラメーター
            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\":2400000,\"FrameRate\":25,\"Resolution\":\"1280x\"}},\"Audio\":{\"TranscodeAudio\":{\"SampleRate\":44100,\"Codec\":\"aac\",\"Bitrate\":128000}},\"Duration\":10,\"InitialSegments\":[2,2,2],\"InitialTranscode\":36,\"URI\":\"oss://your-oss-bucket-name/output/media\"}]");
            // ランタイムオプション
            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 レスポンスを実行して出力します。
            // レスポンスは、ボディ、ヘッダー、およびステータスコードを含むマップです。
            client.callApi(params, request, runtime);
        }
    }

ステップ 2:プレイリストへの署名

# -*- coding: utf-8 -*-
import os
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# 環境変数から認証情報を取得します。実行前に設定してください。
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())
# バケットが属するリージョンのエンドポイント。
endpoint = 'yourEndpoint'
# リージョン ID (例:cn-hangzhou)。
region = 'cn-hangzhou'
# バケット名。
bucket_name = 'your-oss-bucket-name'
# プレイリスト名。
key = 'output/media.m3u8'
# バケットインスタンスを作成します。
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)
	}
	// OSS クライアントを作成します。
	// yourEndpoint: 例:中国 (杭州) の場合は https://oss-cn-hangzhou.aliyuncs.com。
	// yourRegion: 例: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, 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 秒 (2 時間)。
	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)
	}
	// プレーヤーで使用するフォーマット。
	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 {
        // エンドポイントの例: https://oss-cn-beijing.aliyuncs.com。ご使用のリージョンに合わせて調整してください。
        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();
        // バケット名。
        String bucketName = "test-project";
        // オブジェクトパス (バケット名を除く)。
        String objectKey = "output/media.m3u8";
        // OSS クライアントを作成します。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();
        // URL の有効期限を設定します (2 時間)。
        Date expiration = new Date(new Date().getTime() + 7200 * 1000);
        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.shutdown();         
        try {
            // 例:1 時間の有効期限。
            URL url = ossClient.generatePresignedUrl(bucketName, objectKey, expiration);
            System.out.println(url);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException. Request reached OSS but was rejected.");
            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 a ClientException. Client encountered a serious internal issue.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

ステップ 3:ビデオの再生

ステップ 2:プレイリストへの署名」で取得した署名付き URL を HLS プレーヤーに直接貼り付けます。

  • Mac の Safari で再生

    macOS の Safari は HLS 再生をサポートしています。URL をアドレスバーに貼り付けます。

  • Aliplayer で再生

    Alibaba Cloud Aliplayer を開き、URL をアドレスバーに貼り付けます。

    説明

    ApsaraVideo Player SDK をアプリケーションに統合することもできます。「Web プレーヤーの概要」をご参照ください。

  • HLS プレーヤーで再生

    署名付き URL を HLS 互換のプレーヤーに貼り付けます。

マスタープレイリストの例

トランスコーディング設定

  • ソースビデオ

    • フォーマット:AVI

    • ソース URI:oss://your-oss-bucket-name/test.avi

  • マスタープレイリスト URI:oss://your-oss-bucket-name/output/master.m3u8

  • ターゲットビデオ 1

    • セグメント期間:10 秒

    • 先行トランスコード期間:36 秒

    • ビデオコーデック:H.264

    • 解像度:1920×1080

    • フレームレート:25 fps

    • オーディオコーデック:AAC

    • オーディオビットレート:128 Kbps

    • 出力パスプレフィックス:oss://your-oss-bucket-name/output/1080p/1080p

  • ターゲットビデオ 2

    • セグメント期間:10 秒

    • 先行トランスコード期間:36 秒

    • ビデオコーデック:H.264

    • 解像度:1280×720

    • フレームレート:25 fps

    • オーディオコーデック:AAC

    • オーディオビットレート:96 Kbps

    • 出力パスプレフィックス:oss://your-oss-bucket-name/output/720p/720p

  • ターゲットビデオ 3

    • セグメント期間:10 秒

    • 先行トランスコード期間:36 秒

    • ビデオコーデック:H.264

    • 解像度:720×406

    • フレームレート:25 fps

    • オーディオコーデック:AAC

    • オーディオビットレート:64 Kbps

    • 出力パスプレフィックス:oss://your-oss-bucket-name/output/540p/540p

ステップ 1:プレイリストの生成

  • リクエストの例

    {
      "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 を使用してクライアントを初期化します。
            @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 と 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_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_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_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]
            )
            # リクエストを出力します。
            print(json.dumps(req.to_map(), indent=4))
            # リクエストを送信します。
            response = client.generate_video_playlist(req)
            # レスポンスを出力します。
            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)
    	}
    	// レスポンスを出力します。
    	fmt.Println("Response:", *res.Body)
    }
    

ステップ 2:プレイリストへの署名

返されたマスタープレイリストの URL に OSS 署名を行います。「ステップ 2:プレイリストへの署名」をご参照ください。

ステップ 3:ビデオの再生

再生手順については、「ステップ 3:ビデオの再生」をご参照ください。

よくある質問

カスタムプレーヤーは必要ですか。

いいえ。ストリーミング中のトランスコードは、標準の HLS プロトコルをサポートしています。標準の HLS 互換プレーヤー (Alibaba Cloud 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 を使用したストリーミング中のトランスコードの高速化」をご参照ください。