Todos os produtos
Search
Central de documentação

Intelligent Media Services:Primeiros passos

Última atualização: Jun 28, 2026

Este tópico descreve como usar o IMS SDK para produzir vídeos em lote chamando a API SubmitMediaProducingJob.

Conceitos principais

Produção em lote de vídeos

A produção em lote de vídeos gera vários vídeos exclusivos ao combinar um pequeno conjunto de clipes de áudio e vídeo com diferentes variações de narração.

Casos de uso

Plataformas de vídeos curtos frequentemente utilizam algoritmos de deduplicação para evitar roubo de conteúdo. Para executar uma campanha de marketing em vários canais ou contas, crie variações exclusivas dos seus anúncios em vídeo. O recurso de produção em lote de vídeos automatiza esse processo. Ao personalizar o parâmetro timeline na chamada da API SubmitMediaProducingJob, gere diferentes saídas de vídeo conforme suas necessidades.

Faturamento

O envio de um trabalho de edição e produção pode gerar cobranças referentes a vários itens faturáveis. Para mais informações, consulte produção inteligente.

Como funciona

  • Combine clipes de vídeo, áudio, imagem e legenda em um vídeo finalizado enviando trabalhos de edição com diferentes configurações do parâmetro timeline por meio da API SubmitMediaProducingJob.

  • A timeline é o local onde você organiza os clipes e projeta efeitos para o seu projeto de vídeo. Ela consiste em três objetos principais: faixas, clipes e efeitos. Para mais informações, consulte Configuração da timeline.

  • O recurso de produção inteligente oferece suporte a edição e produção, renderização de efeitos e produção baseada em modelos para transmissões ao vivo, vídeo sob demanda (VOD) e clipes do OSS. Para mais detalhes, visualize a Visão geral da produção inteligente.

Antes de começar

Etapa 1: Criar um bucket do OSS

Faça login no console do OSS e clique em Buckets > Create Bucket. Na region, selecione China (Shanghai). Anote o nome do bucket, pois ele é obrigatório para o código de exemplo e servirá como destino de saída para os vídeos editados.

No modo de criação, selecione Custom Creation.

Etapa 2: Executar o código de produção em lote de vídeos

  1. Configure seu ambiente:

    • Sistema operacional: Windows 8.1 ou superior, macOS ou Linux.

    • IntelliJ IDEA: 2020.1 ou superior.

    • JDK: 1.8 ou superior.

  2. Crie um novo projeto Maven para executar o código.

  3. Importe as dependências de terceiros necessárias.

    Nota

    A versão do SDK do lado do servidor no código de exemplo abaixo serve apenas como referência. Para obter a versão mais recente, consulte o SDK do lado do servidor.

    <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. Configure seu AccessKey ID e AccessKey Secret. Para mais informações, consulte Gerenciar credenciais. Para outros métodos de autenticação, visualize Gerenciar credenciais.

    Nota

    Para conhecer outras formas de gerenciar suas credenciais, consulte Gerenciar credenciais.

  5. Crie uma nova classe Java e cole o seguinte código de exemplo.

    Expandir para visualizar o código de exemplo

    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. Substitua o espaço reservado bucket no código pelo nome do bucket criado na Etapa 1.

  7. Execute o código para gerar os vídeos. O código realiza o seguinte fluxo de trabalho:

    Gerar uma timeline > enviar um trabalho de produção de vídeo > consultar o status do trabalho > imprimir logs no 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. Quando o status do trabalho mudar para Success, o campo outputMediaUrl fornecerá a URL do vídeo gerado. Como o bucket é privado, não é possível abrir essa URL diretamente. Copie uma URL assinada no console do OSS para visualizar o vídeo.

    Na lista Buckets, selecione seu bucket. Escolha File Management > File List e abra o diretório ice_output/. Selecione o arquivo .mp4 desejado. No painel de detalhes, ative HTTPS, defina um tempo de expiração e clique em Copy Object URL para obter a URL assinada.

  9. A variável produceCount especifica a quantidade de vídeos a serem gerados. Modifique esse valor de produceCount para produzir um número diferente de vídeos. Também é possível substituir o texto e os clipes de vídeo de exemplo pelo seu próprio conteúdo. Para mais informações, consulte a documentação sobre Configuração da timeline.

Referências

Próximas etapas