日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

接入視頻剪輯Web SDK

智能生產制作提供專業在線的視頻剪輯能力,針對自動化、智能化剪輯以及多人協作視頻制作需求,您可以基于時間線進行云剪輯。通過閱讀本文,您可以了解如何接入視頻剪輯Web SDK。

使用說明

本文中引入的視頻剪輯Web SDK的版本號5.2.2(僅供參考),從5.0.0開始,你需要申請License授權才能使用剪輯Web SDK。獲取最新的版本信息,請參見視頻剪輯工程——幫助信息

License授權方式有2種:

方式1(推薦):購買企業標準版(售價3萬元,支持進行官網價5萬元的IMS任意功能消費抵扣)及以上訂閱資源包,會贈送webSDK License,購買說明請參見:計費概述

方式2:其他訂閱方式,您可以單獨購買webSDK license,定價2萬/年,可工單聯系官方獲取購買鏈接;

操作步驟

  1. 引入視頻剪輯Web SDK。

    在項目前端頁面文件中的<head>標簽處引入視頻剪輯Web SDK的CSS文件,如下所示:

    <head>
      <link rel="stylesheet" >
    </head>

    <body>標簽處添加一個用以掛載剪輯界面的<div>節點,并在<body>標簽末尾添加引入Web SDK的JS文件,同時添加一個用以調用Web SDK的<script>節點。

    <body>
      <div id="aliyun-video-editor" style="height:700px"></div> // 您可以根據需要改變 container 高度
      <script src="https://g.alicdn.com/thor-server/video-editing-websdk/5.2.2/index.js"></script>
      <script>
        // 調用 SDK 的代碼放在這里
      </script>
    </body>
  2. 初始化視頻剪輯Web SDK。

    window.AliyunVideoEditor.init(config);

config屬性說明

config參數

參數

類型

必填

描述

引入版本

locale

string

界面語言,取值:

  • zh-CN(默認值):中文。

  • en-US:英文。

3.0.0

container

Element

Web SDK生成界面掛載的DOM節點。

3.0.0

defaultAspectRatio

PlayerAspectRatio

默認的視頻預覽比例,默認為16∶9。

3.4.0

defaultSubtitleText

string

默認的字幕內容,不超過20個字符,默認為“阿里云剪輯”。

3.6.0

useDynamicSrc

boolean

是否動態獲取資源信息。

3.0.0

getDynamicSrc

(mediaId: string, mediaType: 'video' | 'audio' | 'image' | 'font', mediaOrigin?:'private' | 'public', inputUrl?: string) => Promise<string>;

動態獲取資源信息,必填與否與參數useDynamicSrc一致。返回的Promise對象需要resolve資源新的信息。

3.10.0

getEditingProjectMaterials

() => Promise<InputMedia[]>;

獲取工程關聯的素材。返回的Promise對象需要resolve所有素材類型的數組。

3.0.0

searchMedia

(mediaType: 'video' | 'audio' | 'image') => Promise<InputMedia[]>;

資源庫導入素材按鈕相應函數。單擊導入素材后會搜索媒資信息,將媒資庫媒資導入到資源庫中。返回的Promise對象需要resolve新增素材的數組。

重要

您需要調用AddEditingProjectMaterials將新增的素材與工程關聯起來。

3.0.0

deleteEditingProjectMaterials

(mediaId: string, mediaType: 'video' | 'audio' | 'image') => Promise<void>;

解綁工程與素材。返回的Promise對象需要resolve。

3.0.0

submitASRJob

(mediaId: string, startTime: string, duration: string) => Promise<ASRResult[]>;

提交智能識別字幕任務。返回的Promise對象需要resolve識別的結果ASRResult數組。

3.1.0

推薦使用AsrConfig,使用AsrConfig會覆蓋submitASRJob方法。

submitAudioProduceJob

(text: string, voice: string, voiceConfig?: VoiceConfig) => Promise<InputMedia>;

提交文字轉語音任務,參數依次為:字幕內容、語音效果voice值和語音配置。返回的Promise對象需要resolve生成語音的數據。

4.3.5

推薦使用TTSConfig,使用TTSConfig會覆蓋submitAudioProduceJob方法。

licenseConfig

LicenseConfig

WebSDK的使用需要進行license配置。只有配置了license,才能在線上環境中使用WebSDK,如果沒有配置license,只能在localhost域名下使用,在沒有配置license的情況下,在localhost使用會出現水印,而在在線上環境中進行預覽時會出現黑屏情況。

5.0.1

dynamicSrcQps

number

限制dynamicSrc的請求頻率。

4.13.0

getTimelineMaterials

(params: TimelineMaterial[]) => Promise<InputMedia[]>

獲取timeline中的素材媒資信息,以用于獲取在getEditingProjectMaterials中未注冊的媒資,例如:第三方媒資。

4.13.4

asrConfig

AsrConfig

提交智能字幕任務的配置。

4.13.0

ttsConfig

TTSConfig

提交智能配音任務的配置。

5.0.1

disableAutoJobModal

boolean

關閉項目出現AI任務時自動打開的彈窗。

5.0.1

disableGreenMatting

boolean

關閉綠幕摳圖入口。

4.13.0

disableRealMatting

boolean

關閉實景摳圖入口。

4.13.0

disableDenoise

boolean

關閉降噪入口。

4.13.0

audioWaveRenderDisabled

boolean

關閉波形圖渲染。

4.13.0

publicMaterials

PublicMaterialLibrary

公共素材庫配置。

4.13.0

subtitleConfig

SubtitleConfig

字幕背景漸變等配置。

4.13.0

getStickerCategories

() => Promise<StickerCategory[]>;

獲取貼紙分類,如果不傳,則不分類。返回的Promise對象需要resolve貼紙的分類數組。

3.0.0

getStickers

(config: {categoryId?: string; page: number; size: number}) => Promise<StickerResponse>;

獲取貼紙,如果貼紙沒有分類,則categoryId 為空。返回的Promise對象需要resolve貼紙的總量和貼紙數組。

3.0.0

getEditingProject

() => Promise<{timeline?: Timeline; projectId?: string; modifiedTime?: string}>;

獲取工程的時間線。返回的Promise對象需要resolve時間線Timeline數據、項目ID和最后修改時間。

3.0.0

updateEditingProject

(data: {coverUrl: string; duration: number; timeline: Timeline; isAuto: boolean}) => Promise<{projectId: string}>;

保存工程的時間線,參數依次為:工程的封面圖地址、時長(單位:秒)、Timeline數據和是否自動保存(當前每分鐘自動保存1次)。返回的Promise對象需要resolve項目ID。

3.0.0

produceEditingProjectVideo

(data:{ coverUrl: string; duration: number; aspectRatio: PlayerAspectRatio; mediaMarks: MediaMark[]; timeline: Timeline; recommend: IProduceRecommend; }) => Promise<void>;

生成視頻,參數依次為:工程的封面圖地址、時長(單位:秒)、視頻比例、媒資標記、Timeline數據和recommend (視頻合成的分辨率、碼率的推薦數據)。返回的Promise對象需要resolve。

4.4.0

customTexts

{importButton?:string;updateButton?:string;produceButton?:string;backButton?:string;logoUrl?:string;}

自定義部分文案,參數依次對應視頻剪輯界面的導入素材保存導出視頻返回按鈕的文案和左上角Logo。

3.7.0

customFontList

Array<string | CustomFontItem>;

自定義字體類型。

3.10.0

customVoiceGroups

VoiceGroup[]

自定義語音選項。

4.3.5

getPreviewWaterMarks

() => Promise<Array<{ url?: string; mediaId?:string; width?: number; height?: number; x?: number; y?: number; xPlusWidth?: number; yPlusHeight?: number; opacity?: number; }>>;

預覽區添加水印,防止截屏(合成時沒有水印),參數如下所示:

  • url:水印圖片地址,與水印媒資ID二選一。

  • mediaId:水印媒資ID,與水印圖片地址二選一。

  • width:圖片的寬縮放百分比,范圍:(0,1],默認值為1,表示自適應預覽區。

  • height:圖片的高縮放百分比,范圍:(0,1],默認值為1,表示自適應預覽區。

  • x:圖片相對預覽區的x坐標值,范圍:[0~1]。

  • y:圖片相對預覽區的y坐標值,范圍:[0~1]。

  • xPlusWidth:圖片定位的左右偏移參數,例如:圖片左右居中,則x=0.5,xPlusWidth=-0.5。

  • yPlusHeight:圖片定位的上下偏移參數,例如:圖片左右居中,則y=0.5,yPlusHeight=-0.5。

  • opacity:圖片透明度。

4.3.5

exportVideoClipsSplit

(data: Array<{ coverUrl: string; duration: number; aspectRatio: PlayerAspectRatio; mediaMarks: MediaMark[]; timeline: Timeline; recommend?: IProduceRecommend; }>) => Promise<void>;

將選中Timeline的多個獨立片段拆分為不同Timeline并導出,參數依次為:默認封面圖、導出Timeline的時長、導出比例、媒資標記、導出的Timeline片段、視頻合成的分辨率或碼率的推薦數據。

4.4.0

exportFromMediaMarks

(data: Array<{coverUrl: string; duration: number; aspectRatio: PlayerAspectRatio; mediaMarks: MediaMark[]; timeline:Timeline; recommend?: IProduceRecommend;}>,) => Promise<void>;

將選中Timeline的多個標記片段拆分為不同Timeline并導出,參數依次為:默認封面圖、導出Timeline的時長、導出比例、媒資標記、導出的Timeline片段、視頻合成的分辨率或碼率的推薦數據。

4.4.5

exportVideoClipsMerge

(data: { coverUrl: string; duration: number; aspectRatio: PlayerAspectRatio; mediaMarks: MediaMark[]; timeline: Timeline; recommend?:IProduceRecommend; }) => Promise<void>;

將選中Timeline同一軌道的多個獨立片段合成為一個Timeline并導出,參數依次為:默認封面圖、導出Timeline的時長、導出比例、媒資標記、導出的Timeline片段、視頻合成的分辨率或碼率的推薦數據。

4.4.0

getAudioByMediaId

(mediaId: string) =>Promise<string>;

獲取音頻地址,用于提升視頻的音頻波形圖繪制速度。傳入的參數為視頻素材ID,初始化時傳入該參數,SDK會優先使用其返回的音頻地址解析出視頻的音頻波形。返回的Promise對象需要resolve音頻地址URL。

4.3.5

hasTranscodedAudio

boolean

導入工程中的所有視頻是否有代理音頻(轉碼后的音頻),取值:

  • true:所有導入工程中的視頻素材都有代理音頻,SDK對于視頻分離音頻軌操作不會限制視頻素材原始時長。

    重要

    為了提升視頻分離音頻軌的性能,如果使用動態資源地址,則接口getDynamicSrc根據mediaType返回相應類型的資源信息;如果使用靜態資源地址,則在Media.video.agentAudioSrc聲明視頻素材的代理音頻地址。

  • false:視頻分離音頻軌操作僅對原始時長不超過30分鐘的視頻素材開放。

4.3.6

avatarConfig

AvatarConfig

數字人接入配置。

4.10.0

disableAutoAspectRatio

boolean

是否關閉根據素材分辨率切換比例彈窗。

4.12.2

videoTranslation

VideoTranslation

視頻翻譯相關配置

5.1.0

數據結構說明

  • PlayerAspectRatio

    enum PlayerAspectRatio {
      w1h1 = '1:1',
      w2h1 = '2:1',
      w4h3 = '4:3',
      w3h4 = '3:4',
      w9h16 = '9:16',
      w16h9 = '16:9',
      w21h9 = '21:9',
    }
  • VoiceConfig

    interface VoiceConfig {
      volume: number; // 音量,取值0~100,默認值50
      speech_rate: number; // 語速,取值范圍:-500~500,默認值:0
      pitch_rate: number; // 語調,取值范圍:-500~500,默認值:0
      format?: string; // 輸出文件格式,支持:PCM/WAV/MP3
    }
  • InputMedia

     type InputMedia = (InputVideo | InputAudio | InputImage)
    
    interface InputSource {
      sourceState?: 'ready' | 'loading' | 'fail';
    }
    
    type MediaIdType = 'mediaId' | 'mediaURL';
    
    interface SpriteConfig {
      num: string;
      lines: string;
      cols: string;
      cellWidth?: string;
      cellHeight?: string;
    }
    
    interface MediaMark {
      startTime: number;
      endTime: number;
      content: string;
    }
    
    interface InputVideo extends InputSource {
      mediaId: string;
      mediaIdType?: MediaIdType;
      mediaType: 'video';
      video: {
        title: string;
        coverUrl?: string;
        duration: number;
        format?: string;
        src?: string;
        snapshots?: string[];
        sprites?: string[];
        spriteConfig?: SpriteConfig;
        width?: number;
        height?: number;
        rotate?: number;
        bitrate?: number;
        fps?: number;
        hasTranscodedAudio?: true;
        agentAudioSrc?: string;
        marks?: MediaMark[];
        codec?: string;
      };
    }
     interface InputAudio extends InputSource {
      mediaId: string;
      mediaIdType?: MediaIdType;
      mediaType: 'audio';
      audio: {
        title: string;
        duration: number;
        coverUrl?: string;
        src?: string;
        marks?: MediaMark[];
        formatNames?: string[];
      };
    }
     interface InputImage extends InputSource {
      mediaId: string;
      mediaIdType?: MediaIdType;
      mediaType: 'image';
      image: {
        title: string;
        coverUrl?: string;
        src?: string;
        width?: number;
        height?: number;
        rotate?: number;
      };
    }
    
    type TimelineMaterial = { mediaIdType: MediaIdType; mediaId: string; mediaType: MediaType };
  • MediaMark

    interface MediaMark {
      startTime: number;
      endTime: number;
      content: string;
    }
  • ASRResult

    interface ASRResult {
      content: string; // 字幕的內容
      from: number; // 字幕的開始相對于識別素材的開始的時間偏移量
      to: number; // 字幕的結束相對于識別素材的開始的時間偏移量
    }
  • StickerCategory

    interface StickerCategory {
      id: string; // 分類的 id
      name: string; // 分類的名稱,調用者自行切換語言
    }
  • StickerResponse

    interface Sticker {
      mediaId: string;
      src: string;
    }
      
    interface StickerResponse {
      total: number;
      stickers: Sticker[];
    }
  • IProduceRecommend

    interface IProduceRecommend {
      width?: number;
      height?: number;
      bitrate?: number;
    }
  • CustomFontItem

    interface CustomFontItem {
      key: string; // 字體唯一標識
      name?: string; // 展示的名字,沒有用key
      url: string; // 字體地址
      // 用于前、后端字體渲染保持一致,頁面文字渲染大小是您設置的字體大小乘以這個倍數
      fontServerScale?: {
        // 普通字幕字體倍數
        common: number;
        // 花字字體倍數
        decorated: number;
      };
    }
  • VoiceGroup

    export interface VoiceGroup {
      type: string; // 分類
      category:string; // 主分類
      voiceList?: Voice[];
      emptyContent?: {
        description: string;
        linkText: string;
        link: string;
      };
      getVoiceList?: (page: number, pageSize: number) => Promise<{ items: Voice[]; total: number }>;
      getVoice?: (voiceId: string) => Promise<Voice | null>;
      getDemo?: (mediaId: string) => Promise<{ src: string }>;
    }
  • Voice

    export interface Voice {
      voiceUrl?: string; // 示例音頻地址
      demoMediaId?: string; // 示例音頻的播放地址
      voiceType: VoiceType; // 類型
      voice: string; // 人聲 key
      name: string; // “人名”
      desc: string; // 簡介
      tag?: string; // 標簽
      remark?: string; // 備注支持的語言等信息
      custom?: boolean; // 是否專屬人聲
    }
  • VoiceType

    enum VoiceType {
      Male = 'Male', // 男聲
      Female = 'Female', // 女聲
      Boy = 'Boy', // 男孩童聲
      Girl = 'Girl', // 女孩童聲
    }
  • AvatarConfig

    // 數字人配置說明
    interface AvatarConfig {
    // 數字人列表
      getAvatarList: () => DigitalHumanList[];
    
      // 提交數字人任務
      submitAvatarVideoJob: <T extends keyof DigitalHumanJobParamTypes>(
        job: DigitalHumanJob<T>,
      ) => Promise<DigitalHumanJobInfo>;
    
      // 獲取數字人任務結果
      getAvatarVideoJob: (jobId: string) => Promise<DigitalHumanJobResult>;
    
      // 任務輪詢時間
      refreshInterval: number;
      // 數字人輸出視頻配置
      outputConfigs: Array<{
        width: number;
        height: number;
        bitrates: number[];
      }>;
    
      filterOutputConfig?: (
        item: DigitalHuman,
        config:  Array<{
        width: number;
        height: number;
        bitrates: number[];
      }>,
      ) =>  Array<{
        width: number;
        height: number;
        bitrates: number[];
      }>;
    
    }
    
    // 數字人詳細類型說明
    
    // 數字人參數
    interface DigitalHuman {
      avatarId: string; // 數字人ID
      avatarName: string; // 數字人名稱
      coverUrl: string; // 數字人封面
      videoUrl?: string; // 數字人視頻demo地址
      outputMask?: boolean; // 是否輸出遮罩
      transparent?: boolean; // 是否背景透明
    }
    // 數字人列表
    interface DigitalHumanList {
      default: boolean;
      id: string;
      name: string;
      getItems: (pageNo: number, pageSize: number) => Promise<{ total: number; items: DigitalHuman[] }>;
    }
    // 數字人提交任務返回的信息
    interface DigitalHumanJobInfo {
      jobId: string;
      mediaId: string;
    }
    
    // 數字人任務參數類型
     type DigitalHumanJobParamTypes = {
      text: {//文字驅動
        text?: string;
        params?: DigitalHumanTextParams;
        output?: DigitalHumanOutputParams;
      };
      audio: {//音頻文件驅動
        mediaId?: string;
        params?: DigitalHumanAudioParams;
        output?: DigitalHumanOutputParams;
      };
    };
    
    // text|audio
    type DigitalHumanJobType = keyof DigitalHumanJobParamTypes;
    
    // 數字人文字驅動任務參數
    type DigitalHumanTextParams = {
      voice: string;
      volume: number;
      speechRate: number;
      pitchRate: number;
      autoASRJob?: boolean;
    };
    
    // 數字人音頻文件驅動任務參數
    type DigitalHumanAudioParams = {
      title: string;
      autoASRJob?: boolean;
    };
    // 數字人輸出視頻其他參數
     type DigitalHumanOutputParams = {
      bitrate: number;
      width: number;
      height: number;
    };
    // 生成數字人字幕切片類型
    type SubtitleClip = { from: number; to: number; content: string };
    
    // 數字人任務運行輪詢結果
    interface DigitalHumanJobResult {
      jobId: string;
      mediaId: string;
      done: boolean;
      errorMessage?: string;
      job?: DigitalHumanJob<any>;
      video?: InputVideo;
      subtitleClips?: SubtitleClip[];
    }
    
    // 數字人任務
    type DigitalHumanJob<T extends DigitalHumanJobType> = {
      type: T;
      title: string;
      avatar: DigitalHuman;
      data: DigitalHumanJobParamTypes[T];
    };
    
    // 數字人生成視頻
    interface InputVideo {
      mediaId: string;
      mediaType: 'video';
      video: {
        title: string;
        coverUrl?: string;
        duration: number;
        src?: string; // 當 useDynamicUrl 為 true 時,src 可以不傳
        snapshots?: string[];
        sprites?: string[];
        spriteConfig?: SpriteConfig;//精靈圖
        width?: number; // 視頻源的寬度
        height?: number; // 視頻源的高度
        rotate?: number; // 視頻源的旋轉角度
        bitrate?: number; // 視頻源的碼率
        fps?: number; // 視頻源的幀率
        hasTranscodedAudio?: true; // 是否含有轉碼后的音頻流
        agentAudioSrc?: string; // 代理的音頻地址(用于分離音頻軌),當 useDynamicUrl 為 true 時,agentAudioSrc 可以不傳
        marks?: MediaMark[];// 視頻標記
      };
    }
  • LicenseConfig

    // license的配置
    type LicenseConfig = {
        rootDomain?: string; // license使用的根域名,例如使用的域名是 editor.abc.com,這里填的值就是abc.com
        licenseKey?: string; // 申請的licenseKey,參考頂部使用說明在控制臺中申請
     }
  • AsrConfig

    // 智能生成字幕的配置
    type AsrConfig = {
        interval?: number; // 輪詢時長,單位:毫秒
        defaultText?: string; // 默認的文案
        maxPlaceHolderLength?: number; // 默認的文案最大長度
        submitASRJob: (mediaId: string, startTime: string, duration: string) => Promise<ASRJobInfo>;
        getASRJobResult?: (jobId: string) => Promise<ASRJobInfo>;
     }
    interface ASRJobInfo {
      jobId?: string;
      jobDone: boolean;
      jobError?: string;
      result?: ASRResult[];
    }
  • TTSConfig

    // 智能配音任務的配置
    type TTSConfig = {
        interval?: number;  // 輪詢時長,單位:毫秒
        submitAudioProduceJob: (text: string, voice: string, voiceConfig?: VoiceConfig) => Promise<TTSJobInfo>;
        getAudioJobResult?: (jobId: string) => Promise<TTSJobInfo>;
     }
    interface VoiceConfig {
      volume: number;
      speech_rate: number;
      pitch_rate: number;
      format?: string;
      custom?: boolean;
    }
    
    interface TTSJobInfo {
      jobId?: string;
      jobDone: boolean;
      jobError?: string;
      asr?: AudioASRResult[];
      result?: InputAudio | null;
    }
    
    interface AudioASRResult {
      begin_time?: string;
      end_time?: string;
      text?: string;
      content?: string;
      from?: number;
      to?: number;
    }
  • PublicMaterialLibrary

    // 公共媒資庫的配置
    type PublicMaterialLibrary = {
      getLists: () => Promise<MaterialList[]>;
      name?: string;
      pageSize?: number; // 單頁展示數量
    };
     type MaterialList = {
      name?: string; 
      key: string;
      tag?: string;
      mediaType: 'video' | 'audio' | 'image';
      styleType?: 'video' | 'audio' | 'image' | 'background';
      getItems: (
        pageIndex: number,
        pageSize: number,
      ) => Promise<{
        items: InputMedia[];
        end: boolean;
      }>;
    };
  • SubtitleConfig

    type SubtitleConfig = {
         // 自定義紋理列表
        customTextures?: {  
          list: () => Promise<
            Array<{
              key: string;
              url: string;
            }>
          >;
          // 添加自定義紋理
          onAddTexture: () => Promise<{
            key: string;
            url: string;
          }>;
          // 刪除自定義紋理
          onDeleteTexture: (key: string) => Promise<void>;
        };
    }
  • AliyunVideoEditor

    // AliyunVideoEditor 實例方法
    type AliyunVideoEditor = {
        init: (config: IConfig) => void; // 初始化編輯器
        destroy: (keepState?: boolean) => boolean; // 銷毀編輯器
        version: string | undefined; // 獲取編輯器版本
        setCurrentTime: (currentTime: number) => void; // 設置編輯器預覽時間
        getCurrentTime: () => number; // 獲取編輯器預覽時間
        getDuration: () => number; // 獲取編輯器時長
        addProjectMaterials: (materials: InputMedia[]) => void; // 添加項目素材到編輯器
        setProjectMaterials: (materials: InputMedia[]) => void; // 設置項目素材到編輯器
        updateProjectMaterials: (update: (materials: InputMedia[]) => InputMedia[]) => void; // 更新編輯器當前項目素材
        deleteProjectMaterial: (mediaId: string) => void; // 刪除編輯器項目素材
        setProjectTimeline: ({ VideoTracks, AudioTracks, AspectRatio }: CustomTimeline) => Promise<void>; // 設置編輯器的timeline
        getProjectTimeline: () => any; // 獲取編輯器的timeline
        getEvents: (eventType?: 'ui' | 'player' | 'error' | 'websdk' | 'timeline') => IObservable<EventData<any>>; // 獲取編輯器的事件
        importSubtitles: (type: 'ass' | 'srt' | 'clip' | 'asr', config: string) => void; // 批量導入字幕到編輯器
    }
  • VideoTranslation

    type VideoTranslation = {
      language?: {
        // 源語言
        source: Array<{
          value: string;
          label: string;
        }>;
        // 目標語言
        target: Array<{
          value: string;
          label: string;
        }>;
      };
      // 視頻翻譯
      translation?: {
        interval?: number;
        submitVideoTranslationJob: (params: TranslationJobParams) => Promise<TranslationJobInfo>;
        getVideoTranslationJob: (jobId: string) => Promise<TranslationJobInfo>;
      };
      // 字幕擦除
      detext?: {
        interval?: number;
        submitDetextJob: (param: DetextJobParams) => Promise<DetextJobInfo>;
        getDetextJob: (jobId: string) => Promise<DetextJobInfo>;
      };
      // 字幕提取
      captionExtraction?: {
        interval?: number;
        submitCaptionExtractionJob: (param: CaptionExtractionJobParams) => Promise<CaptionExtractionJobInfo>;
        getCaptionExtractionJob: (jobId: string) => Promise<CaptionExtractionJobInfo>;
      };
    };
    
     interface TranslationJobParams {
        type: 'Video' | 'Text' | 'TextArray';
        mediaId?: string;
        mediaIdType?: MediaIdType;
        text?: string;
        textArray?: string[];
        editingConfig: {
            SourceLanguage: string;
            TargetLanguage: string;
            DetextArea?: string;
            SupportEditing?: boolean;
            SubtitleTranslate?: {
                TextSource: 'OCR' | 'SubtitleFile';
                OcrArea?: string;
                SubtitleConfig?: string;
            };
        };
    }
    
    interface TranslationJobInfo {
        jobId?: string;
        jobDone: boolean;
        jobError?: string;
        result?: {
            video?: InputVideo;
            timeline?: string;
            text?: string;
            textArray?: Array<{
                Target: string;
                Source: string;
            }>;
        };
    }
    
    interface DetextJobParams {
        mediaId: string;
        mediaIdType: MediaIdType;
        box?: 'auto' | Array<[number, number, number, number]>;
    }
    
    interface DetextJobInfo {
        jobId?: string;
        jobDone: boolean;
        jobError?: string;
        result?: {
            video?: InputVideo;
        };
    }
    
    interface CaptionExtractionJobParams {
        mediaId: string;
        mediaIdType: MediaIdType;
        box?: 'auto' | Array<[number, number, number, number]>;
    }
    
    interface CaptionExtractionJobInfo {
        jobId?: string;
        jobDone: boolean;
        jobError?: string;
        result?: {
            srtContent?: string;
        };
    }

init()示例代碼

重要

Web SDK只負責界面交互,不會發起請求,您需要通過Web SDK調用請求邏輯。請求本身應該先發送給您自己的服務端,您自己的服務端再根據AccessKey信息(AccessKey ID和AccessKey Secret)轉發給相關的阿里云OpenAPI。

// 注意,WebSDK 本身并不提供 request 這個方法,這里僅作為示例,您可以使用您喜歡的網絡請求庫,如 axios 等

window.AliyunVideoEditor.init({
  container: document.getElementById('aliyun-video-editor'),
  locale: 'zh-CN',
  licenseConfig: {
     rootDomain: "", // license使用的根域名,例如abc.com
     licenseKey: "", // 申請的licenseKey,沒有配置licenseKey,在預覽時會出現水印,沒有配置license的情況下,只能在localhost的域名下預覽
  },
  useDynamicSrc: true, // 媒資庫默認情況下播放地址會過期,所以需要動態獲取
  getDynamicSrc: (mediaId, mediaType) => new Promise((resolve, reject) => {
    request('GetMediaInfo', { // http://bestwisewords.com/document_detail/197842.html
      MediaId: mediaId
    }).then((res) => {
      if (res.code === '200') {
        // 注意,這里僅作為示例,實際中建議做好錯誤處理,避免如 FileInfoList 為空數組時報錯等異常情況
        resolve(res.data.MediaInfo.FileInfoList[0].FileBasicInfo.FileUrl);
      } else {
        reject();
      }
    });
  }),
  getEditingProjectMaterials: () => {
    if (projectId) { // 如果沒有 projectId,需要先在智能媒體服務控制臺創建剪輯工程,獲取projectId。
      return request('GetEditingProjectMaterials', { // http://bestwisewords.com/document_detail/209068.html
        ProjectId: projectId
      }).then((res) => {
        const data = res.data.MediaInfos;
        return transMediaList(data); // 需要做一些數據變換,具體參考后文
      });
    }
    return Promise.resolve([]);
  },
  searchMedia: (mediaType) => { // mediaType 為用戶當前所在的素材 tab,可能為 video | audio | image,您可以根據這個參數對應地展示同類型的可添加素材
    return new Promise((resolve) => {
      // 調用方需要自己實現展示媒資、選擇媒資添加的界面,這里的 callDialog 只是一種示例,WebSDK 本身并不提供
      // 關于展示媒資,請參考:http://bestwisewords.com/document_detail/197964.html
      callDialog({
        onSubmit: async (materials) => {
          if (!projectId) { // 如果沒有 projectId,需要先創建工程,如果能確保有 projectId,則不需要該步
            const addRes = await request('CreateEditingProject', { // http://bestwisewords.com/document_detail/197834.html
              Title: 'xxxx',
            });
            projectId = addRes.data.Project.ProjectId;
          }

          // 組裝數據
          const valueObj = {};
          materials.forEach(({ mediaType, mediaId }) => {
            if (!valueObj[mediaType]) {
              valueObj[mediaType] = mediaId;
            } else {
              valueObj[mediaType] += mediaId;
            }
          })
          const res = await request('AddEditingProjectMaterials', { // http://bestwisewords.com/document_detail/209069.html
            ProjectId: projectId,
            MaterialMaps: valueObj,
          });
          if (res.code === '200') {
            return resolve(transMediaList(res.data.MediaInfos));
          }
          resolve([]);
        }
      });
    });
  },
  deleteEditingProjectMaterials: async (mediaId, mediaType) => {
    const res = await request('DeleteEditingProjectMaterials', { // http://bestwisewords.com/document_detail/209067.html
      ProjectId: projectId,
      MaterialType: mediaType,
      MaterialIds: mediaId
    });
    if (res.code === '200') return Promise.resolve();
    return Promise.reject();
  },
  getStickerCategories: async () => {
    const res = await request('ListAllPublicMediaTags', { // http://bestwisewords.com/document_detail/207796.html
      BusinessType: 'sticker',
      WebSdkVersion: window.AliyunVideoEditor.version
    });

    const stickerCategories = res.data.MediaTagList.map(item => ({
      id: item.MediaTagId,
      name: myLocale === 'zh-CN' ? item.MediaTagNameChinese : item.MediaTagNameEnglish // myLocale 是您期望的語言
    }));
    return stickerCategories;
  },
  getStickers: async ({ categoryId, page, size }) => {
    const params = {
      PageNo: page,
      PageSize: size,
      IncludeFileBasicInfo: true,
      MediaTagId: categoryId
    };

    const res = await request('ListPublicMediaBasicInfos', params); // http://bestwisewords.com/document_detail/207797.html

    const fileList = res.data.MediaInfos.map(item => ({
      mediaId: item.MediaId,
      src: item.FileInfoList[0].FileBasicInfo.FileUrl
    }));

    return {
      total: res.data.TotalCount,
      stickers: fileList
    };
  },
  getEditingProject: async () => {
    if (projectId) {
      const res = await request('GetEditingProject', { // http://bestwisewords.com/document_detail/197837.html
        ProjectId: projectId
      });
      
      const timelineString = res.data.Project.Timeline;
   
      return {
        projectId,
        timeline: timelineString ? JSON.parse(timelineString) : undefined,
        modifiedTime: res.data.Project.ModifiedTime,
        title:res.data.Project.Title // 項目標題
      };
    }
    return {};
  },
  updateEditingProject: ({ coverUrl, duration, timeline, isAuto }) => new Promise((resolve, reject) => {
    request('UpdateEditingProject', { // http://bestwisewords.com/document_detail/197835.html
      ProjectId: projectId,
      CoverURL: coverUrl,
      Duration: duration,
      Timeline: JSON.stringify(timeline)
    }).then((res) => {
      if (res.code === '200') {
        // WebSDK 本身會進行自動保存,isAuto 則是告訴調用方這次保存是否自動保存,調用方可以控制只在手動保存時才展示保存成功的提示
        !isAuto && Message.success('保存成功');
        resolve();
      } else {
        reject();
      }
    });
  }),
  produceEditingProjectVideo: ({ coverUrl, duration = 0, aspectRatio, timeline, recommend }) => {
    return new Promise((resolve) => {
      callDialog({ // 調用方需要自己實現提交合成任務的界面,這里的 callDialog 只是一種示例
        onSubmit: async ({ fileName, format, bitrate, description }) => { // 假設提交合成任務的界面讓你獲得了這些數據
          // 先根據 fileName 和 format 拼接出存儲的 mediaURL
          const mediaURL = `http://bucketName.oss-cn-hangzhou.aliyuncs.com/${fileName}.${format}`;
          // 根據 WebSDK 傳入的預覽比例來決定合成的寬高
          const width = aspectRatio === '16:9' ? 640 : 360;
          const height = aspectRatio === '16:9' ? 360 : 640;
          // 若視頻、圖片素材傳入的長寬、碼率等數據,那么該函數返回的數據中的 recommend 就會包含了根據所使用的視頻、圖片計算得到的推薦的分辨率和碼率
          // recommend 數據結構可以查看 IProduceRecommend
          // 你可以在提交界面上展示推薦數據或者直接使用在提交接口的參數里
          const res = await request('SubmitMediaProducingJob', { // http://bestwisewords.com/document_detail/197853.html
            OutputMediaConfig: JSON.stringify({
              mediaURL,
              bitrate: recommend.bitrate || bitrate,
              width: recommend.width || width,
              height: recommend.height || height
            }),
            OutputMediaTarget: 'oss-object',
            ProjectMetadata: JSON.stringify({ Description: description }),
            ProjectId: projectId,
            Timeline: JSON.stringify(timeline)
          });
          if (res.code === '200') {
            Message.success('生成視頻成功');
          }
          resolve();
        }
      });
    });
  }
});

/**
 * 將服務端的素材信息轉換成 WebSDK 需要的格式
 */
function transMediaList(data) {
  if (!data) return [];

  if (Array.isArray(data)) {
    return data.map((item) => {
      const basicInfo = item.MediaBasicInfo;
      const fileBasicInfo = item.FileInfoList[0].FileBasicInfo;
      const mediaId = basicInfo.MediaId;
      const result = {
        mediaId
      };
      const mediaType = basicInfo.MediaType
      result.mediaType = mediaType;

      if (mediaType === 'video') {
        result.video = {
          title: fileBasicInfo.FileName,
          duration: Number(fileBasicInfo.Duration),
          // 源視頻的寬高、碼率等數據,用于推薦合成數據,不傳入或是0時無推薦數據
          width: Number(fileBasicInfo.Width) || 0,
          height: Number(fileBasicInfo.Height) || 0,
          bitrate: Number(fileBasicInfo.Bitrate) || 0,
          coverUrl: basicInfo.CoverURL
        };
        const spriteImages = basicInfo.SpriteImages
        if (spriteImages) {
          try {
            const spriteArr = JSON.parse(spriteImages);
            const sprite = spriteArr[0];
            const config = JSON.parse(sprite.Config);
            result.video.spriteConfig = {
              num: config.Num,
              lines: config.SpriteSnapshotConfig?.Lines,
              cols: config.SpriteSnapshotConfig?.Columns,
              cellWidth: config.SpriteSnapshotConfig?.CellWidth,
              cellHeight: config.SpriteSnapshotConfig?.CellHeight
            };
            result.video.sprites = sprite.SnapshotUrlList;
          } catch (e) {
            console.log(e);
          }
        }
      } else if (mediaType === 'audio') {
        result.audio = {
          title: fileBasicInfo.FileName,
          duration: Number(fileBasicInfo.Duration),
          coverURL: '' // 您可以給音頻文件一個默認的封面圖
        }
      } else if (mediaType === 'image') {
        result.image = {
          title: fileBasicInfo.FileName,
          coverUrl: fileBasicInfo.FileUrl,
          // 圖片的寬高等數據,用于推薦合成數據,不傳入或是0時無推薦數據
          width: Number(fileBasicInfo.Width) || 0,
          height: Number(fileBasicInfo.Height) || 0,
        }
      }

      return result;
    });
  } else {
    return [data];
  }
}

相關參考

常見問題