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

ApsaraVideo VOD:全画面モードでの高速読み込み再生

最終更新日:Jan 29, 2026

ApsaraVideo Player SDK のプリロードやビデオサムネイルなどの機能を利用することで、起動時間をミリ秒単位まで短縮できます。これにより、ショートビデオ再生時に発生しがちな長い起動時間や再生のカクつきといった問題を解決し、読み込みを体感させないスムーズな再生体験を提供します。このトピックでは、ApsaraVideo Player を使用して全画面モードで高速読み込みを実現する方法について説明します。

ソリューション概要

ビデオを再生する際、読み込みに時間がかかり黒い画面が表示されることがあります。起動時間を短縮するために、ApsaraVideo Player のプリロード機能を有効にしてビデオリソースを事前に読み込むことができます。また、ビデオサムネイルを指定し、ビデオコンテンツが読み込まれる前にサムネイルを表示することもできます。これにより、黒い画面の表示を防ぎます。ビデオの先頭フレームをサムネイルとして設定すると、ビデオが実際に再生される前に先頭フレームが表示されます。これにより、素早くシームレスな再生体験が実現します。

このソリューションを使用すると、Wi-Fi 環境での平均起動時間を約 300 ミリ秒に短縮できます。

制限事項

  • 全画面モードでの高速読み込みは、ApsaraVideo Player SDK for Android および iOS のみでサポートされています。

  • 一度にプリロードできるファイルは、MP4、MP3、FLV、HLS のいずれか 1 つのみです。

  • プリロードしたビデオは UrlSource を使用してのみ再生できます。VidAuth や VidSts を使用してプリロード済みのビデオを再生することはできません。

前提条件

ステップ 1:ApsaraVideo Player SDK でプリロード機能を有効にする

ApsaraVideo Player SDK でプリロード機能を有効にすると、ビデオデータが事前にローカルデバイスに読み込まれます。これにより、起動時間が短縮されます。

制限事項

  • 現在、MP4、MP3、FLV、HLS などの単一メディアファイルの読み込みをサポートしています。

Android プレーヤーの設定

  1. ローカルキャッシュ機能を有効にします。

    ローカルキャッシュ機能を有効にするには、/app/src/main/java/com/aliyun/alivcsolution/MutiApplication.java ファイルで AliPlayerGlobalSettings.enableLocalCache を呼び出します。

    public class MutiApplication extends Application {
    
        @Override
        protected void attachBaseContext(Context base) {
            super.attachBaseContext(base);
            MultiDex.install(this);
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            // ローカルキャッシュ機能を有効にします。キャッシュが保存されるパスは絶対パスである必要があります。例:/tmp。次のサンプルコードの maxBufferMemoryKB パラメーターは、ApsaraVideo Player SDK V5.4.7.1 以降では非推奨となり、効果はありません。
            AliPlayerGlobalSettings.enableLocalCache(true,10240,"/tmp");
    
          
        }
    
    }
  2. プリロードインスタンスを作成します。インスタンスの初期化中に、プリロードステータスのコールバックを設定します。

    これは /AliyunListPlayer/src/main/java/com/aliyun/player/aliyunlistplayer/AliyunListPlayerActivity.java で定義されています。

    public class AliyunListPlayerActivity extends AppCompatActivity {
    
        private AliyunListPlayerView mListPlayerView;
        private NetWatchdog mNetWatchDog;
        private String mUserToken;
        private boolean mIsLoadMore = false;
        private int mLastVideoId = -1;
        private ImageView mBackImageView;
        
        // プリロード用のシングルトンを作成します。
        private MediaLoader medialoader=MediaLoader.getInstance();
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_aliyun_list_player);
            mUserToken = getIntent().getStringExtra("list_player_user_token");
    
            initView();
            initSts(true);
            initListener();
    
    
            // 読み込みステータスのコールバックを設定します。
            medialoader.setOnLoadStatusListener(new MediaLoader.OnLoadStatusListener() {
                @Override
                public void onError(String url, int code, String msg) {
                    // 読み込み中にエラーが発生しました。
                }
    
                @Override
                public void onCompleted(String s) {
                    // 読み込みが完了しました。
                }
    
                @Override
                public void onCanceled(String s) {
                    // 読み込みがキャンセルされました。
                }
            });
        }
        ...
  3. データリクエストに応答する際、load 関数を呼び出してデータをプリロードし、指定されたディスクパスに保存します。

    private void getDatas(int id){
            GetVideoInfomation getVideoInfomation = new GetVideoInfomation();
            getVideoInfomation.getListPlayerVideoInfos(this, "1", mUserToken, id, new GetVideoInfomation.OnGetListPlayerVideoInfosListener() {
                private SparseArray<String> mSparseArray;
                @Override
                public void onGetSuccess(Request request, String result) {
                    // デモのリストプレーヤーは、ビデオ ID のみを使用してビデオデータをリクエストします。
                    // ただし、ビデオのプリロードは URL を使用してのみ可能で、ビデオ ID ではできません。
                    // 次のコードは、ビデオの URL を取得した後に medialoader を使用してビデオをプリロードする方法の例です。
                    String url="";// ビデオの URL を取得済みと仮定します。
                    medialoader.load(url,10000);// データをプリロードし、指定されたディスクパスに保存します。読み込み時間は 10,000 ミリ秒です。
    
                    Gson gson = new Gson();
                    AliyunVideoListBean aliyunVideoListBean = gson.fromJson(result, AliyunVideoListBean.class);
                    
                    ...

ApsaraVideo Player SDK for iOS の設定

  1. ローカルキャッシュ機能を有効にし、インスタンスの初期化中にプリロードステータスのコールバックを設定します。

    - (AliPlayer *)aliPlayer{
        if (!_aliPlayer && UIApplicationStateActive == [[UIApplication sharedApplication] applicationState]) {
            _aliPlayer = [[AliPlayer alloc] init];
            _aliPlayer.scalingMode =  AVP_SCALINGMODE_SCALEASPECTFIT;
            _aliPlayer.rate = 1;
            _aliPlayer.delegate = self;
            _aliPlayer.playerView = self.playerView;
    
            // ローカルキャッシュを有効にします。ローカルキャッシュファイルのパスはサンドボックスパスである必要があります。maxBufferMemoryKB パラメーターは v5.4.7.1 以降では非推奨となり、効果はありません。
            NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
            [AliPlayerGlobalSettings enableLocalCache:YES maxBufferMemoryKB:10*1024 localCacheDir:[docDir stringByAppendingPathComponent:@"alivcCache"]];
            [AliPlayerGlobalSettings setCacheFileClearConfig:30*60*24 maxCapacityMB:20480 freeStorageMB:0];
            // プリロード URL と再生 URL がパラメーターの変更により不一致になることで発生するプリロードの失敗を防ぐため、URL コールバックメソッドを設定します。
            [AliPlayerGlobalSettings setCacheUrlHashCallback:hashCallback];
            
            // コールバックデリゲートを設定します。
            [[AliMediaLoader shareInstance] setAliMediaLoaderStatusDelegate:self];
    
        }
        return _aliPlayer;
    }
    
    // URL コールバックメソッド。
    NSString* hashCallback(NSString* url){
        NSString *md5Str = [NSString aliyun_MD5:url];
        return md5Str;
    }
    
    // プリロードのコールバックメソッド。
    #pragma mark -- AliMediaLoaderStatusDelegate
    /**
     @brief エラーコールバック。
     @param url 読み込む URL。
     @param code エラーコード。
     @param msg エラーの説明。
     */
    - (void)onError:(NSString *)url code:(int64_t)code msg:(NSString *)msg {
        
    }
    
    /**
     @brief 完了コールバック。
     @param url 読み込まれた URL。
     */
    - (void)onCompleted:(NSString *)url {
        
    }
    
    /**
     @brief キャンセルコールバック。
     @param url 読み込みがキャンセルされた URL。
     */
    - (void)onCanceled:(NSString *)url {
        
    }

  2. データソースを設定する際に load 関数を呼び出して、データを指定のディスクパスにプリロードします。

    NSString *urlString = @"<URL>";
    AVPUrlSource *urlSource = [[AVPUrlSource alloc] urlWithString:urlString];
    [_aliPlayer setUrlSource:urlSource];
    [[AliMediaLoader shareInstance] load:urlString duration:10000];// プリロードされたデータを指定のディスクパスに保存します。読み込み時間は 10,000 ミリ秒に設定されています。

ステップ 2:ビデオの先頭フレームをサムネイルとして設定

ビデオの先頭フレームをサムネイルとして設定することで、素早くシームレスな再生体験を提供できます。

説明

ApsaraVideo Player を使用してリスト内のビデオを再生する場合、次のロジックを使用して、素早い再生体験を提供し、トラフィック使用量を削減できます。

  • ユーザーが素早くビデオを切り替える場合、ビデオサムネイルのみがリクエストされます。

  • 次のビデオのビューの半分が表示されると、プリフェッチされたビデオサムネイルが表示されます。

コンソールでの設定

  1. スナップショットテンプレートを作成して、ビデオの先頭フレームをキャプチャします。

    1. ApsaraVideo VOD コンソールにログインします。

    2. 左側のナビゲーションウィンドウで、[設定管理] > [メディア処理] > [スナップショットテンプレート] を選択します。

    3. スナップショットテンプレートの追加 をクリックし、先頭フレームのスナップショットテンプレートのパラメーターを設定します。

      テンプレート名 をカスタム名に設定し、スクリーンショットの方法通常のスクリーンショット に設定します。開始時間 を 00:00:00 に、スクリーンショットの数: を 1 に設定します。他のパラメーターは必要に応じて設定できます。スナップショットテンプレートのパラメーターの詳細については、「スナップショットテンプレート」をご参照ください。首帧截图1.png

    4. 保存 をクリックして、スナップショットテンプレートを作成します。

  2. スナップショットタスクを開始して、ビデオの先頭フレームをキャプチャします。

    説明
    • コンソールでスナップショットタスクを開始するには、ワークフローが必要です。まず、動画スクリーンショット ノードを含むワークフローを作成します。次に、スナップショットテンプレートを先頭フレームのスナップショットテンプレートに設定します。ワークフローの作成方法の詳細については、「ワークフロー管理」をご参照ください。

    • スナップショットタスクを開始する前に、ApsaraVideo VOD のイベント通知を設定します。SnapshotComplete イベントの通知を設定します。これにより、タスク完了後にタスクのステータスとスナップショットの URL を取得できます。イベント通知の設定方法の詳細については、「コールバック設定」をご参照ください。

    • シナリオ 1:ビデオアップロード中にスナップショットをキャプチャする

      1. ApsaraVideo VOD コンソールの左側のナビゲーションウィンドウで、メディアファイル > [音声/動画] を選択します。

      2. [オーディオ/ビデオのアップロード] をクリックし、次に [オーディオ/ビデオの追加] をクリックします。

      3. アップロード方法とストレージの場所を設定し、ビデオを追加します。次に、ワークフローでの処理 を選択し、先頭フレームのスナップショットタスクを含む事前に作成したワークフローを選択します。

      4. アップロード をクリックします。

    • シナリオ 2:ビデオアップロード後にスナップショットをキャプチャする

      1. ApsaraVideo VOD コンソールで、左側のナビゲーションウィンドウのメディアファイル > [音声/動画]を選択します。

      2. [オーディオとビデオ] ページで、対象のビデオの行にある ApsaraVideo Media Processing をクリックします。

      3. 処理タイプワークフローでの処理 に設定します。ワークフロー パラメーターで、先頭フレームのスナップショットタスクを含む事前に作成したワークフローを選択します。

      4. OK をクリックします。

    • スナップショットの結果を取得する

      • ApsaraVideo VOD で SnapshotComplete イベントのイベント通知を設定している場合、コールバックイベントからタスクのステータスとスナップショットの URL を取得できます。

      • イベント通知を設定していない場合は、ポーリングを使用して ListSnapshots 操作を呼び出し、タスクのステータスとスナップショットの URL をクエリできます。

  3. ビデオサムネイルを先頭フレームのスナップショットに変更します。

    説明

    コンソールを使用してビデオサムネイルを変更できるのは、ビデオがアップロードされた後のみです。まず、前のステップで取得した先頭フレームのスナップショットをローカルコンピューターに保存して、アップロードの準備をします。

    1. ApsaraVideo VOD コンソールの左側のナビゲーションウィンドウで、メディアファイル > [オーディオ/ビデオ] を選択します。

    2. [オーディオとビデオのリスト] ページで、対象のビデオの行にある 管理 をクリックします。

    3. 基本情報 タブで、動画情報の編集 をクリックします。

    4. アップロード をクリックし、コンピューターから先頭フレームのスナップショットを選択して、[開く] をクリックします。

    5. 保存 をクリックして、ビデオサムネイルを設定します。

      設定が完了したら、オーディオとビデオのリストページでサムネイルが更新されていることを確認できます。

OpenAPI を使用した設定

説明

このトピックでは、Java 用 Alibaba Cloud SDK を例として、ApsaraVideo VOD OpenAPI 操作の呼び出し方法を説明します。

手順

  1. スナップショットテンプレートを作成して、ビデオの先頭フレームをキャプチャします。

    AddVodTemplate 操作を呼び出して、先頭フレームをキャプチャするためのスナップショットテンプレートを作成します。次のサンプルコードは、操作の呼び出し方法を示しています:

    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.vod.model.v20170321.AddVodTemplateRequest;
    import com.aliyuncs.vod.model.v20170321.AddVodTemplateResponse;
    
    
    /**
     * 説明:
     * 1. このデモは、先頭フレームのスナップショットテンプレートを作成する方法を示しています。出力は 1 つのイメージです。
     * 2. ApsaraVideo VOD コンソールでスナップショットテンプレートを作成する方が便利です。
     */
    public class AddSnapshotTemplate {
    
        // Alibaba Cloud アカウントの AccessKey ペアは、すべての API 操作に対する権限を持っています。RAM ユーザーを使用して API 操作を呼び出すか、日常の O&M を実行してください。
        // AccessKey ID と AccessKey Secret をプロジェクトコードに保存しないでください。保存すると、AccessKey ペアが漏洩し、アカウント内のすべてのリソースのセキュリティが脅かされる可能性があります。
        // この例では、環境変数から AccessKey ペアを読み取って ID を検証する方法を示します。サンプルコードを実行する前に、ALIBABA_CLOUD_ACCESS_KEY_ID および ALIBABA_CLOUD_ACCESS_KEY_SECRET 環境変数を設定してください。
        public static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        public static String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
    
        public static void main(String[] args) {
    
            try{
                DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);
                AddVodTemplateResponse response = addSnapshotTemplate(vodClient);
                System.out.println("RequestId is:" + response.getRequestId());
                System.out.println("TemplateId is:" + response.getVodTemplateId());
            }catch (Exception e){
    
            }
        }
    
        public static AddVodTemplateResponse addSnapshotTemplate(DefaultAcsClient vodClient) throws ClientException {
            AddVodTemplateRequest request = new AddVodTemplateRequest();
            request.setName("FirstFrameSnapshotTemplate");
            request.setTemplateType("Snapshot");
            request.setTemplateConfig("{\"SnapshotType\":\"NormalSnapshot\",\"SnapshotConfig\":{\"FrameType\":\"normal\",\"Count\":1,\"Interval\":1,\"SpecifiedOffsetTime\":0}}");
    
            return vodClient.getAcsResponse(request);
        }
    
        public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
            // ApsaraVideo VOD が有効化されているリージョン。
            String regionId = "cn-shanghai";  
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
    
            return client;
        }
    }
    
  2. スナップショットタスクを開始して、ビデオの先頭フレームをキャプチャします。

    SubmitSnapshotJob 操作を呼び出して、スナップショットタスクを開始します。次のサンプルコードは、操作の呼び出し方法を示しています:

    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.vod.model.v20170321.*;
    
    /**
     * 説明:
     * 1. このデモは、先頭フレームのスナップショットテンプレートを作成した後に、先頭フレームのスナップショットタスクを送信する方法を示しています。
     * 2. 新しくアップロードされたビデオの場合、MediaProcessFinished イベントが成功した後にこのステップを実行します。Normal 状態の既存のビデオの場合、独自のプロセスを設計してください。
     * 3. スナップショットは非同期タスクです。SnapshotComplete イベントが成功するのを待って、スナップショット URL を取得します。
     * 4. コールバックイベントの SnapshotRegular パラメーターからスナップショットの出力 URL を推測できます。詳細については、SnapshotComplete トピックのスナップショット URL 生成ルールをご参照ください。
     * 5. コールバックサービスがない場合は、ListSnapshots 操作を呼び出して結果をクエリすることもできます。デフォルトでは、この操作は最新のスナップショット結果のみを返します。詳細については、ListSnapshots トピックをご参照ください。
     */
    public class SubmitSnapshotJob {
    
        // Alibaba Cloud アカウントの AccessKey ペアは、すべての API 操作に対する権限を持っています。RAM ユーザーを使用して API 操作を呼び出すか、日常の O&M を実行してください。
        // AccessKey ID と AccessKey Secret をプロジェクトコードに保存しないでください。保存すると、AccessKey ペアが漏洩し、アカウント内のすべてのリソースのセキュリティが脅かされる可能性があります。
        // この例では、環境変数から AccessKey ペアを読み取って ID を検証する方法を示します。サンプルコードを実行する前に、ALIBABA_CLOUD_ACCESS_KEY_ID および ALIBABA_CLOUD_ACCESS_KEY_SECRET 環境変数を設定してください。
        public static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        public static String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
    
        public static void main(String[] args) {
    
            try{
                DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);
                SubmitSnapshotJobResponse response = submitSnapshotJob(vodClient);
                System.out.println("RequestId is:" + response.getRequestId());
                System.out.println("JobId is:" + response.getSnapshotJob().getJobId());
            }catch (Exception e){
    
            }
        }
    
        public static SubmitSnapshotJobResponse submitSnapshotJob(DefaultAcsClient vodClient) throws ClientException {
            SubmitSnapshotJobRequest request = new SubmitSnapshotJobRequest();
            request.setVideoId("a42b**********633b79f0102");
            request.setSnapshotTemplateId("1f27a7**********eba2756");
            // カスタムのパススルーパラメーター。コールバックで利用可能で、オプションです。サムネイル用の先頭フレームスナップショットを区別するために使用されます。
            request.setUserData("{\"Extend\":{\"SnapshotType\":\"FirstFrame\",\"VideoId\":\"a42bf540********33b79f0102\"}}");
            return vodClient.getAcsResponse(request);
        }
    
        public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
            // ApsaraVideo VOD が有効化されているリージョン。
            String regionId = "cn-shanghai";  
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
    
            return client;
        }
    
        // ListSnapshots: スナップショットのクエリ
        public static ListSnapshotsResponse listSnapshots(DefaultAcsClient vodClient) throws ClientException {
            ListSnapshotsRequest request = new ListSnapshotsRequest();
            request.setVideoId("a42bf540b1b371ed804a6633b79****");
            request.setSnapshotType("NormalSnapshot");
    
            ListSnapshotsResponse response = vodClient.getAcsResponse(request);
            System.out.println("RequestId is:" + response.getRequestId());
            System.out.println("SnapshotUrl is:" + response.getMediaSnapshot().getSnapshots().get(0).getUrl());
            return vodClient.getAcsResponse(request);
        }
    
    }
    
  3. ビデオサムネイルを先頭フレームのスナップショットに変更します。

    このセクションでは、アップロード後に単一のビデオのサムネイルを変更する方法の例を示します。他のシナリオの詳細については、「ビデオアップロード中にサムネイルを設定する」および「ビデオアップロード後にサムネイルを更新する」をご参照ください。

    UpdateVideoInfo 操作を呼び出し、CoverURL パラメーターを渡してビデオサムネイルを指定します。次のサンプルコードは、操作の呼び出し方法を示しています:

    package com.alibaba.cloud.test.transcode;
    
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.vod.model.v20170321.UpdateVideoInfoRequest;
    import com.aliyuncs.vod.model.v20170321.UpdateVideoInfoResponse;
    
    /**
     * 説明:
     * 1. このデモは、単一のビデオのサムネイルを変更する方法を示しています。他のビデオパラメーターを変更するには、UpdateVideoInfo トピックをご参照ください。
     * 2. サムネイルを変更する際は、使用するイメージ URL が有効であることを確認してください。
     */
    public class UpdateVideoInfo {
    
        // Alibaba Cloud アカウントの AccessKey ペアは、すべての API 操作に対する権限を持っています。RAM ユーザーを使用して API 操作を呼び出すか、日常の O&M を実行してください。
        // AccessKey ID と AccessKey Secret をプロジェクトコードに保存しないでください。保存すると、AccessKey ペアが漏洩し、アカウント内のすべてのリソースのセキュリティが脅かされる可能性があります。
        // この例では、環境変数から AccessKey ペアを読み取って ID を検証する方法を示します。サンプルコードを実行する前に、ALIBABA_CLOUD_ACCESS_KEY_ID および ALIBABA_CLOUD_ACCESS_KEY_SECRET 環境変数を設定してください。
        public static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        public static String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
    
        public static void main(String[] args) {
    
            try{
                DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);
                UpdateVideoInfoResponse response = updateVideoInfo(vodClient);
                System.out.println("RequestId is:" + response.getRequestId());
            }catch (Exception e){
    
            }
        }
    
        public static UpdateVideoInfoResponse updateVideoInfo(DefaultAcsClient vodClient) throws ClientException {
            UpdateVideoInfoRequest request = new UpdateVideoInfoRequest();
            request.setVideoId("a42b***********33b79f0102");
            // 先頭フレームのサムネイルを設定する場合、CoverURL は先頭フレームのスナップショットタスクが成功した後に返されるイメージ URL です。
            request.setCoverURL("http://demo.aliyuncdn.com/a42bf5******40b1b37/snapshots/normal/41B7AF54-18672BB301D-1748-0984-309-112420****.jpg");
    
            return vodClient.getAcsResponse(request);
        }
    
        public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
            // ApsaraVideo VOD が有効化されているリージョン。
            String regionId = "cn-shanghai";  
            DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);
            return client;
        }
    }
    

完全な例

package com.alibaba.cloud.test.transcode;


import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.*;
import org.apache.commons.lang3.StringUtils;

/**
 * 説明:
 * 1. このデモは、スナップショットの取得とサムネイルの変更の完全なロジックを示しています。ビジネスロジックに基づいて一部のコードを変更する必要があります。
 * 2. このデモは直接使用できません。一部のロジックを自分で追加する必要があります。
 * 3. このデモは参照用であり、唯一の実装方法を表すものではありません。
 */
public class SnapshotAndUpdateCover {

    // Alibaba Cloud アカウントの AccessKey ペアは、すべての API 操作に対する権限を持っています。RAM ユーザーを使用して API 操作を呼び出すか、日常の O&M を実行してください。
    // AccessKey ID と AccessKey Secret をプロジェクトコードに保存しないでください。保存すると、AccessKey ペアが漏洩し、アカウント内のすべてのリソースのセキュリティが脅かされる可能性があります。
    // この例では、環境変数から AccessKey ペアを読み取って ID を検証する方法を示します。サンプルコードを実行する前に、ALIBABA_CLOUD_ACCESS_KEY_ID および ALIBABA_CLOUD_ACCESS_KEY_SECRET 環境変数を設定してください。
    public static String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
    public static String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");

    public static void main(String[] args) {


        try{
            DefaultAcsClient vodClient = initVodClient(accessKeyId, accessKeySecret);
            // ビデオ ID
            String videoId = "a42bf540b1b37*******b79f0102";

            // シナリオ 1:コールバックサービスまたは MNS がある場合。
            // 新しくアップロードされたビデオのサムネイルを設定する場合、まずメディア解析成功イベントを取得する必要があります。
            // 既存のビデオのサムネイルを設定する場合、このステップからスナップショットタスクの送信を開始できます。
            submitSnapshotJob(vodClient,videoId);

            // ビデオスナップショット成功イベントを取得し、スナップショットタイプを判断し、必要なイメージ URL を取得します。
            JSONObject callBackMessage = new JSONObject();  // これをコールバックサービスで受信したメッセージに置き換えます。
            String snapshotType = callBackMessage.getJSONObject("UserData").getJSONObject("Extend").getString("SnapshotType");
            if("FirstFrame".equals(snapshotType)){

                // ここでのスナップショットパスのロジックは、カスタムのスナップショットパスのロジックに置き換える必要があります。
                String coverUrl = callBackMessage.getJSONArray("SnapshotInfos").getJSONObject(0).getString("SnapshotRegular").replace("{SnapshotCount}","00001");
                // ビデオサムネイルを変更します。
                updateVideoInfo(vodClient,videoId,coverUrl);
            }

            // シナリオ 2:コールバックサービスまたは MNS がない場合。
            // 新しくアップロードされたビデオのサムネイルを設定する場合、アップロード後にビデオのステータスをポーリングします。
            String videoStatus = "";
            while(!"Normal".equals(videoStatus)){
                videoStatus = getVideoInfo(vodClient,videoId);
                Thread.sleep(1000);
            }

            // 既存のビデオのサムネイルを設定する場合、このステップからスナップショットタスクの送信を開始できます。
            submitSnapshotJob(vodClient,videoId);

            // スナップショットの結果をポーリングします。
            String coverUrl = "";
            while(StringUtils.isBlank(coverUrl)){
                coverUrl = listSnapshots(vodClient,videoId);
                Thread.sleep(1000);
            }

            // ビデオサムネイルを変更します。
            updateVideoInfo(vodClient,videoId,coverUrl);
        }catch (Exception e){

        }
    }

    /**
     * スナップショットタスクを送信します。
     */
    public static SubmitSnapshotJobResponse submitSnapshotJob(DefaultAcsClient vodClient, String vid) throws ClientException {
        SubmitSnapshotJobRequest request = new SubmitSnapshotJobRequest();
        request.setVideoId(vid);
        request.setSnapshotTemplateId("1f27a7f*********70eba2756");
        // カスタムのパススルーパラメーター。コールバックで利用可能で、オプションです。サムネイル用の先頭フレームスナップショットを区別するために使用されます。
        request.setUserData("{\"Extend\":{\"SnapshotType\":\"FirstFrame\",\"VideoId\":\"a42bf540********33b79f0102\"}}");

        return vodClient.getAcsResponse(request);
    }

    /**
     * ビデオサムネイルを変更します。
     */
    public static UpdateVideoInfoResponse updateVideoInfo(DefaultAcsClient vodClient, String vid, String coverUrl) throws ClientException {
        UpdateVideoInfoRequest request = new UpdateVideoInfoRequest();
        request.setVideoId(vid);
        // 先頭フレームのサムネイルを設定する場合、CoverURL は先頭フレームのスナップショットタスクが成功した後に返されるイメージ URL です。
        request.setCoverURL(coverUrl);

        return vodClient.getAcsResponse(request);
    }

    /**
     * SDK インスタンスを初期化します。
     */
    public static DefaultAcsClient initVodClient(String accessKeyId, String accessKeySecret) throws ClientException {
        // ApsaraVideo VOD が有効化されているリージョン。
        String regionId = "cn-shanghai";  
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);

        return client;
    }

    /**
     * スナップショットをクエリします。
     */
    public static String listSnapshots(DefaultAcsClient vodClient, String vid) throws ClientException {
        ListSnapshotsRequest request = new ListSnapshotsRequest();
        request.setVideoId(vid);
        request.setSnapshotType("NormalSnapshot");

        ListSnapshotsResponse response = vodClient.getAcsResponse(request);
        String coverUrl = "";
        System.out.println("RequestId is:" + response.getRequestId());
        try{
            coverUrl = response.getMediaSnapshot().getSnapshots().get(0).getUrl();
            System.out.println("SnapshotUrl is:" + response.getMediaSnapshot().getSnapshots().get(0).getUrl());
        }catch (NullPointerException e){

        }
        return coverUrl;
    }

    /**
     * 単一のビデオをクエリします。
     */
    public static String getVideoInfo(DefaultAcsClient vodClient, String vid) throws ClientException {
        GetVideoInfoRequest request = new GetVideoInfoRequest();
        request.setVideoId(vid);

        GetVideoInfoResponse response = vodClient.getAcsResponse(request);
        System.out.println("RequestId is:" + response.getRequestId());
        String videoStatus = "";
        try{
            videoStatus = response.getVideo().getStatus();
            System.out.println("Video Status is:" + response.getVideo().getStatus());
        }catch (NullPointerException e){

        }

        return videoStatus;
    }
}

ステップ 3:(オプション) ビデオリソースのプリフェッチ

プリフェッチ機能により、ApsaraVideo VOD はオリジンサーバーからビデオリソースを事前に取得し、Alibaba Cloud CDN の POP (Point of Presence) にキャッシュすることができます。これにより、ユーザーはオリジンサーバーからリソースを取得することなく、POP から最新のリソースを取得できます。これにより、ビデオ再生が高速化され、ApsaraVideo Player でのビデオのプリロードが容易になります。

説明

更新/プリフェッチ機能を使用すると、オリジントラフィックに対して課金されます。ビデオの人気度に基づいてプリフェッチ機能を使用できます。

コンソールでの設定

  1. ApsaraVideo VOD コンソールにログインします。

  2. 左側のナビゲーションウィンドウで、[設定管理] > [CDN 設定] > [更新/プリフェッチ] を選択します。

  3. キャッシュのリフレッシュ タブで、プリフェッチ情報を設定します。

    • [操作タイプ] で、プッシュ を選択します。

    • パージタイプ:このパラメーターは URL に固定されています。

    • URL:プリフェッチしたいビデオリソースの URL を入力します。各 URL は http:// または https:// で始まる必要があります。1 日あたり最大 500 の URL からリソースをプリフェッチできます。1 回のリクエストで最大 100 の URL を指定できます。

  4. 送信 をクリックして、プリフェッチ設定を完了します。

OpenAPI を使用した設定

  1. PreloadVodObjectCaches 操作を呼び出して、ビデオリソースをプリフェッチします。

ステップ 4:ApsaraVideo Player を使用したビデオ再生

ApsaraVideo Player を使用して、UrlSource に基づいてビデオを再生します。