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

Intelligent Media Services:はじめに

最終更新日:Jun 22, 2026

このトピックでは、IMS SDK を使用して SubmitMediaProducingJob API を呼び出し、バッチビデオ制作を実行する方法について説明します。

基本概念

バッチビデオ制作

バッチビデオ制作は、少数のオーディオクリップとビデオクリップを、さまざまなナレーションのバリエーションと組み合わせることで、複数のユニークなビデオを生成します。

利用シーン

ショートビデオプラットフォームでは、コンテンツの盗用を防ぐために重複排除アルゴリズムがよく使用されます。複数のチャンネルやアカウントでマーケティングキャンペーンを実施するには、ビデオ広告のユニークなバリエーションを作成する必要があります。バッチビデオ制作機能は、このプロセスを自動化します。SubmitMediaProducingJob API 呼び出しで タイムラインパラメーターをカスタマイズすることで、ニーズに合わせてさまざまなビデオ出力を生成できます。

課金

編集・制作ジョブを送信すると、複数の課金項目で料金が発生する場合があります。詳細については、「インテリジェント制作」をご参照ください。

仕組み

  • SubmitMediaProducingJob API を使用して、さまざまな タイムラインパラメーター設定で編集ジョブを送信することにより、ビデオ、オーディオ、画像、字幕クリップを完成したビデオに結合します。

  • タイムラインは、ビデオプロジェクトのクリップを配置し、エフェクトをデザインする場所です。タイムラインは、トラック、クリップ、エフェクトの 3 つの主要なオブジェクトで構成されます。詳細については、「タイムライン設定」をご参照ください。

  • インテリジェント制作機能は、ライブストリーム、ビデオオンデマンド (VOD)、および Object Storage Service (OSS) クリップの編集と制作、エフェクトレンダリング、テンプレートベースの制作をサポートします。詳細については、「インテリジェント制作の概要」をご参照ください。

事前準備

  • IMS を有効化済みであること。

  • Resource Access Management (RAM) ユーザーを作成し、その AccessKey ペアを取得済みであること。詳細については、「RAM ユーザーの作成と権限付与」をご参照ください。

ステップ 1: OSS バケットの作成

OSS コンソールにログインし、[バケット] > [バケットの作成] をクリックします。[リージョン][中国 (上海)] を選択します。バケット名はサンプルコードで必須であり、編集済みビデオの出力先として機能するため、メモしておいてください。

作成モードは [カスタム作成] を選択します。

ステップ 2: バッチビデオ制作コードの実行

  1. 環境をセットアップします。

    • オペレーティングシステム:Windows 8.1 以降、macOS、または Linux。

    • IntelliJ IDEA:2020.1 以降。

    • JDK:1.8 以降。

  2. 新しい Maven プロジェクトを作成してコードを実行します。

  3. 必要なサードパーティの依存関係をインポートします。

    説明

    以下のサンプルコードのサーバー側 SDK のバージョンは参考用です。最新バージョンを取得するには、「サーバー側 SDK」をご参照ください。

    <dependencies>
      <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>ice20201109</artifactId>
        <version>2.3.0</version>
      </dependency>
      <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.9</version>
      </dependency>
    </dependencies>
  4. ご利用の AccessKey IDAccessKey Secret を設定します。詳細については、「認証情報の管理」をご参照ください。その他の認証方式については、「認証情報の管理」をご参照ください。

    説明

    認証情報を管理するその他の方法については、「認証情報の管理」をご参照ください。

  5. 新しい Java クラスを作成し、以下のサンプルコードを貼り付けます。

    クリックしてサンプルコードを展開

    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import com.aliyun.ice20201109.Client;
    import com.aliyun.ice20201109.models.*;
    import com.aliyun.teaopenapi.models.Config;
    
    import java.util.*;
    
    // 正常に生成されたビデオのサンプル URL
    // http://oushu-test-shanghai.oss-cn-shanghai.aliyuncs.com/ice_output/46b29eb5775f4f758846171ab79bfca7.mp4
    
    /**
     *  以下の Maven 依存関係が必要です:
     *   <dependency>
     *      <groupId>com.aliyun</groupId>
     *      <artifactId>ice20201109</artifactId>
     *      <version>2.1.0</version>
     *  </dependency>
     *  <dependency>
     *      <groupId>com.alibaba</groupId>
     *      <artifactId>fastjson</artifactId>
     *      <version>1.2.9</version>
     *  </dependency>
     */
    public class BatchProduceAlignment {
    
        static final String regionId = "cn-shanghai";
        // ステップ 1 で作成したバケットの名前に置き換えます。
        static final String bucket = "your-bucket-name";
        private Client iceClient;
        
        public static void main(String[] args) {
            try {
                BatchProduceAlignment batchProduce = new BatchProduceAlignment();
                batchProduce.initClient();
                batchProduce.run();
            } catch (Exception e) {
                System.out.println("Produce failed. Exception: " + e.toString());
            }
        }
    
        public void initClient() throws Exception {
    
            // Alibaba Cloud アカウント (root ユーザー) の AccessKey ペアは、すべての API に対する権限を持っています。API アクセスや日常の O&M には、RAM ユーザーを使用することを推奨します。
            // この例では、AccessKey ID と AccessKey Secret を環境変数に格納する方法を示します。設定手順については、https://www.alibabacloud.com/help/sdk/developer-reference/v2-manage-access-credentials をご参照ください。
            com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
            Config config = new Config();
            config.setCredential(credentialClient);
    
            // 認証情報をハードコーディングする場合は、次のコードを使用します。ただし、AccessKey ID と AccessKey Secret をプロジェクトコードに保存しないことを強く推奨します。認証情報をハードコーディングすると、セキュリティリスクにつながる可能性があります。
            // config.accessKeyId = <your-accesskey-id>;
            // config.accessKeySecret = <your-accesskey-secret>;
            config.endpoint = "ice." + regionId + ".aliyuncs.com";
            config.regionId = regionId;
            iceClient = new Client(config);
        }
    
        public void run() throws Exception {
            // 音声合成用のテキストコンテンツ
            String text = "人々は人生を様々な味で表現します。なぜなら、味はすべての心に大切にされる感情であることを知っているからです。この時代、誰もが多くの痛みと喜びを経験します。人々は苦味を隠し、幸せを食事に変え、四季を通じて食卓に並べる傾向があります。";
            // ビデオクリップ
            String[] videoArray = new String[]{
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f1.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f2.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f3.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f4.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f5.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f6.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f7.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f8.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f9.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f10.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f11.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f12.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f13.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f14.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f15.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f16.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f17.mp4",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/food/f18.mp4"
            };
            // BGM クリップ
            String[] bgMusicArray = new String[]{
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/music/m1.wav",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/music/m2.wav",
                    "https://ice-document-materials.oss-cn-shanghai.aliyuncs.com/test_media/music/m3.wav"
            };
            // ビデオタイトル
            String title = "美味の一口";
            // 生成するビデオの数
            int produceCount = 3;
    
            // ジョブをバッチで送信
            List<String> jobIds = new ArrayList<String>();
            for (int i = 0; i < produceCount; i++) {
                String jobId = produceSingleVideo(title, text, videoArray, bgMusicArray);
                jobIds.add(jobId);
            }
            // すべてのジョブが完了するまでジョブステータスをポーリング
            System.out.println("waiting job finished...");
            while (true) {
                Thread.sleep(3000);
                boolean allFinished = true;
                for (int i = 0; i < jobIds.size(); i++) {
                    String jobId = jobIds.get(i);
                    GetMediaProducingJobRequest req = new GetMediaProducingJobRequest();
                    req.setJobId(jobId);
                    GetMediaProducingJobResponse response = iceClient.getMediaProducingJob(req);
                    GetMediaProducingJobResponseBody.GetMediaProducingJobResponseBodyMediaProducingJob mediaProducingJob = response.getBody().getMediaProducingJob();
                    String status = mediaProducingJob.getStatus();
                    System.out.println("jobId: " + mediaProducingJob.getJobId() + ", status:" + status);
                    if ("Failed".equalsIgnoreCase(status)) {
                        System.out.println("jobfailed. jobInfo: " + JSONObject.toJSONString(mediaProducingJob));
                        throw new Exception("Produce failed. jobid: " + mediaProducingJob.getJobId());
                    }
                    if (!"Success".equalsIgnoreCase(status)) {
                        allFinished = false;
                        break;
                    }
                }
                if (allFinished) {
                    System.out.println("all job finished.");
                    break;
                }
            }
        }
    
        public String produceSingleVideo(String title, String text, String[] videoArray, String[] bgMusicArray) throws Exception {
            text = text.replace(",", "。");
            text = text.replace("\n", "。");
            String[] sentenceArray = text.split("。");
    
            JSONArray videoClipArray = new JSONArray();
            JSONArray audioClipArray = new JSONArray();
    
            List<String> videoList = Arrays.asList(videoArray);
            Collections.shuffle(videoList);
    
            for (int i = 0; i < sentenceArray.length; i++) {
                String sentence = sentenceArray[i];
                String clipId = "clip" + i;
                String videoUrl = videoList.get(i);
                String videoClip = "{\"MediaURL\":\""+videoUrl+"\",\"ReferenceClipId\":\""+clipId+"\",\"Effects\":[{\"Type\":\"Background\",\"SubType\":\"Blur\",\"Radius\":0.1}]}";
                videoClipArray.add(JSONObject.parseObject(videoClip));
                String audioClip = "{\"Type\":\"AI_TTS\",\"Content\":\"" + sentence + "\",\"Voice\":\"zhichu\",\"ClipId\":\""+clipId+"\",\"Effects\":[{\"Type\":\"AI_ASR\",\"Font\":\"Alibaba PuHuiTi\",\"Alignment\":\"TopCenter\",\"Y\":0.75,\"FontSize\":55,\"FontColor\":\"#ffffff\",\"AdaptMode\":\"AutoWrap\",\"TextWidth\":0.8,\"Outline\":2,\"OutlineColour\":\"#000000\"}]}";
                audioClipArray.add(JSONObject.parseObject(audioClip));
            }
    
            String subtitleTrack = "{\"SubtitleTrackClips\":[{\"Type\":\"Text\",\"Font\":\"HappyZcool-2016\",\"Content\":\""+title+"\",\"FontSize\":80,\"FontColor\":\"#ffffff\",\"Y\":0.15,\"Alignment\":\"TopCenter\",\"EffectColorStyle\":\"CS0004-000005\",\"FontFace\":{\"Bold\":true,\"Italic\":false,\"Underline\":false}}]}";
    
            int bgMusicIndex = (int)(Math.random() * bgMusicArray.length);
            String bgMusicUrl = bgMusicArray[bgMusicIndex];
            String timeline = "{\"VideoTracks\":[{\"VideoTrackClips\":"+videoClipArray.toJSONString()+"}],\"AudioTracks\":[{\"AudioTrackClips\":"+audioClipArray.toJSONString()+"},{\"AudioTrackClips\":[{\"MediaURL\":\""+bgMusicUrl+"\"}]}],\"SubtitleTracks\":[" + subtitleTrack + "]}";
    
            //
            String targetFileName = UUID.randomUUID().toString().replace("-", "");
            String outputMediaUrl = "http://" + bucket + ".oss-" + regionId + ".aliyuncs.com/ice_output/" + targetFileName + ".mp4";
            int width = 720;
            int height = 1280;
            String outputMediaConfig = "{\"MediaURL\":\"" + outputMediaUrl + "\",\"Width\":"+width+",\"Height\":"+height+"}";
    
            SubmitMediaProducingJobRequest request = new SubmitMediaProducingJobRequest();
            request.setTimeline(timeline);
            request.setOutputMediaConfig(outputMediaConfig);
            SubmitMediaProducingJobResponse response = iceClient.submitMediaProducingJob(request);
            System.out.println("start job. jobid: " + response.getBody().getJobId() + ", outputMediaUrl: " + outputMediaUrl);
            return response.getBody().getJobId();
        }
    
    }
    
  6. コード内の bucket プレースホルダーを、ステップ 1 で作成したバケットの名前に置き換えます。

  7. コードを実行してビデオを生成します。コードは次のワークフローを実行します。

    タイムラインの生成 > ビデオ制作ジョブの送信 > ジョブステータスのポーリング > コンソールへのログ出力。

    public static void main(String[] args) throws Exception {
        BatchProduce batchProduce = new BatchProduce();
        batchProduce.initClient();
        batchProduce.run();
    }
    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
    start job. jobid: 150de5f285c942b0894f1150ad5e6d50, outputMediaUrl: http://oushu-test-shanghai.oss-cn-shanghai.aliyuncs.com/ice_output/e0852f92dd2041e19e0739f4a7cee064.mp4
    waiting job finished...
    jobId: 150de5f285c942b0894f1150ad5e6d50, status:Init
    jobId: 150de5f285c942b0894f1150ad5e6d50, status:Init
    jobId: 150de5f285c942b0894f1150ad5e6d50, status:Init
    jobId: 150de5f285c942b0894f1150ad5e6d50, status:Init
    jobId: 150de5f285c942b0894f1150ad5e6d50, status:Init
    jobId: 150de5f285c942b0894f1150ad5e6d50, status:Init
    jobId: 150de5f285c942b0894f1150ad5e6d50, status:Processing
    jobId: 150de5f285c942b0894f1150ad5e6d50, status:Processing
    jobId: 150de5f285c942b0894f1150ad5e6d50, status:Processing
    jobId: 150de5f285c942b0894f1150ad5e6d50, status:Success
    all job finished.
    Process finished with exit code 0

  8. ジョブのステータスが [Success] に変わると、outputMediaUrl は生成されたビデオの URL を提供します。バケットは非公開のため、この URL を直接開くことはできません。代わりに、OSS コンソールから署名付き URL をコピーしてビデオをプレビューする必要があります。

    [バケット] リストからご利用のバケットを選択します。[ファイル管理] > [ファイルリスト] を選択し、ice_output/ ディレクトリを開きます。対象の .mp4 ファイルを選択します。詳細パネルで、HTTPS を有効にし、有効期限を設定し、[オブジェクト URL のコピー] をクリックして署名付き URL を取得します。

  9. produceCount 変数は、生成するビデオの数を指定します。この produceCount の値を変更して、異なる数のビデオを出力します。サンプルテキストやビデオクリップを独自のコンテンツに置き換えることもできます。詳細については、「タイムライン設定」ドキュメントをご参照ください。

参考

次のステップ