Tous les produits
Search
Centre de documentation

Intelligent Media Services:Prise en main

Dernière mise à jour :Aug 11, 2026

Cette rubrique explique comment utiliser le SDK IMS pour réaliser une production vidéo par lot en appelant l'API SubmitMediaProducingJob.

Concepts clés

Production vidéo par lot

La production vidéo par lot génère plusieurs vidéos uniques en combinant un petit ensemble de clips audio et vidéo avec différentes variations de voix off.

Cas d'utilisation

Les plateformes de vidéos courtes utilisent souvent des algorithmes de déduplication pour prévenir le vol de contenu. Pour lancer une campagne marketing sur plusieurs canaux ou comptes, vous devez créer des variantes uniques de vos publicités vidéo. La fonctionnalité de production vidéo par lot automatise ce processus. En personnalisant le paramètre de timeline dans votre appel d'API SubmitMediaProducingJob, vous pouvez générer différentes sorties vidéo répondant à vos besoins.

Facturation

La soumission d'une tâche de montage et de production peut entraîner des frais pour plusieurs éléments facturables. Pour plus d'informations, consultez la rubrique production intelligente.

Fonctionnement

  • Combinez des clips vidéo, audio, image et sous-titres en une vidéo finale en soumettant des tâches de montage avec différentes configurations du paramètre de timeline à l'aide de l'API SubmitMediaProducingJob.

  • Une timeline est l'espace où vous organisez les clips et concevez les effets pour votre projet vidéo. Elle se compose de trois objets principaux : les pistes, les clips et les effets. Pour plus d'informations, consultez la rubrique Configuration de la timeline.

  • La fonctionnalité de production intelligente prend en charge le montage et la production, le rendu des effets et la production basée sur des modèles pour les flux en direct, la vidéo à la demande (VOD) et les clips OSS. Pour plus d'informations, consultez la rubrique Présentation de la production intelligente.

Avant de commencer

Étape 1 : Créer un bucket OSS

Connectez-vous à la console OSS et cliquez sur Buckets > Create Bucket. Pour la region, sélectionnez China (Shanghai). Notez le nom du bucket, car il est requis pour l'exemple de code et servira de destination de sortie pour les vidéos montées.

Pour le mode de création, sélectionnez Custom Creation.

Étape 2 : Exécuter le code de production vidéo par lot

  1. Configurez votre environnement :

    • Système d'exploitation : Windows 8.1 ou version ultérieure, macOS ou Linux.

    • IntelliJ IDEA : version 2020.1 ou ultérieure.

    • JDK : version 1.8 ou ultérieure.

  2. Créez un nouveau projet Maven pour exécuter le code.

  3. Importez les dépendances tierces requises.

    Remarque

    La version du SDK côté serveur dans l'exemple de code suivant est fournie à titre indicatif. Pour obtenir la dernière version, consultez le SDK côté serveur.

    <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. Configurez votre AccessKey ID et AccessKey Secret. Pour plus d'informations, consultez la rubrique Gérer les identifiants. Pour d'autres méthodes d'authentification, consultez la rubrique Gérer les identifiants.

    Remarque

    Pour découvrir d'autres façons de gérer vos identifiants, consultez la rubrique Gérer les identifiants.

  5. Créez une nouvelle classe Java et collez l'exemple de code suivant.

    Développer pour afficher l'exemple de code

    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.*;
    
    // Sample URL of a successfully generated video
    // http://oushu-test-shanghai.oss-cn-shanghai.aliyuncs.com/ice_output/46b29eb5775f4f758846171ab79bfca7.mp4
    
    /**
     *  The following Maven dependencies are required:
     *   <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";
        // Replace with the name of the bucket you created in Step 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 {
    
            // An AccessKey pair of an Alibaba Cloud account has permissions on all APIs. We recommend that you use a RAM user for API access or routine O&M.
            // This example shows how to store the AccessKey ID and AccessKey Secret in environment variables. For configuration instructions, see: https://www.alibabacloud.com/help/en/sdk/developer-reference/v2-manage-access-credentials
            com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client();
            Config config = new Config();
            config.setCredential(credentialClient);
    
            // If you want to hardcode your credentials, use the following code. However, we strongly recommend that you do not store your AccessKey ID and AccessKey Secret in your project code. Hardcoding credentials can lead to security risks.
            // 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 {
            // Text content for text-to-speech
            String text = "People describe life with mixed flavors because they know that taste is a sentiment cherished in every heart. In this era, everyone experiences much pain and joy. People tend to hide the bitterness and turn happiness into food, presenting it on the dining table throughout the seasons.";
            // Video clips
            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"
            };
            // Background music clips
            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"
            };
            // Video title
            String title = "A Bite of Delicacy";
            // Number of videos to generate
            int produceCount = 3;
    
            // Submit jobs in a batch
            List<String> jobIds = new ArrayList<String>();
            for (int i = 0; i < produceCount; i++) {
                String jobId = produceSingleVideo(title, text, videoArray, bgMusicArray);
                jobIds.add(jobId);
            }
            // Poll job status until all jobs are complete
            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. Remplacez l'espace réservé bucket dans le code par le nom du bucket que vous avez créé à l'étape 1.

  7. Exécutez le code pour générer les vidéos. Le code effectue le workflow suivant :

    Générer une timeline > soumettre une tâche de production vidéo > interroger le statut de la tâche > imprimer les journaux dans la console. 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. Lorsque le statut de la tâche passe à Success, le champ outputMediaUrl fournit l'URL de la vidéo générée. Étant donné que le bucket est privé, vous ne pouvez pas ouvrir cette URL directement. Vous devez plutôt copier une URL signée depuis la console OSS pour prévisualiser la vidéo.

    Dans la liste Buckets, sélectionnez votre bucket. Choisissez File Management > File List et ouvrez le répertoire ice_output/. Sélectionnez le fichier .mp4 cible. Dans le panneau des détails, activez HTTPS, définissez une durée d'expiration et cliquez sur Copy Object URL pour obtenir l'URL signée.

  9. La variable produceCount spécifie le nombre de vidéos à générer. Modifiez cette valeur produceCount pour produire un nombre différent de vidéos. Vous pouvez également remplacer le texte et les clips vidéo de l'exemple par votre propre contenu. Pour plus d'informations, consultez la documentation relative à la Configuration de la timeline.

Références

Étapes suivantes