Intelligent Media Services (IMS) は、プロフェッショナルなオンラインビデオ編集機能を提供します。IMS は、自動化されたインテリジェントな編集、共同ビデオ制作、およびタイムラインでのクラウドベースの編集をサポートしています。このトピックでは、ビデオ編集 Web SDK を統合する方法について説明します。
使用上の注意
このトピックの情報は、ビデオ編集 Web SDK V5.2.2 に基づいています。V5.0.0 以降、ビデオ編集 Web SDK を使用するにはライセンスが必要です。最新のバージョン情報については、「ビデオ編集プロジェクトのヘルプ情報」をご参照ください。
ライセンスを申請するには、チケットを送信できます。
手順
ビデオ編集 Web SDK をインポートします。
プロジェクトのフロントエンドページファイルの
<head>タグに、次のようにビデオ編集 Web SDK の CSS ファイルをインポートします:<head> <link rel="stylesheet" href="https://g.alicdn.com/thor-server/video-editing-websdk/5.2.2/index.css"> </head><body>タグに、エディターインターフェイスをマウントするための<div>ノードを追加します。<body>タグの最後に、Web SDK の JS ファイルと、Web SDK を呼び出すための<script>ノードを追加します。<body> <div id="aliyun-video-editor" style="height:700px"></div> // 必要に応じてコンテナーの高さを変更できます。 <script src="https://g.alicdn.com/thor-server/video-editing-websdk/5.2.2/index.js"></script> <script> // SDK を呼び出すコードをここに配置します。 </script> </body>ビデオ編集 Web SDK を初期化します。
window.AliyunVideoEditor.init(config);configパラメーターはオブジェクトです。オブジェクトのプロパティの詳細については、「config プロパティ」をご参照ください。init()初期化関数のサンプルコードについては、「init() サンプルコード」をご参照ください。
config プロパティ
config パラメータ
パラメータ | タイプ | 必須 | 説明 | 導入バージョン |
locale | string | いいえ | ユーザーインターフェース(UI)の言語。有効な値:
| 3.0.0 |
container | Element | はい | Web SDK が UI をマウントする Document Object Model (DOM) ノード。 | 3.0.0 |
defaultAspectRatio | いいえ | ビデオプレビューのデフォルトの縦横比。デフォルト値は 16:9 です。 | 3.4.0 | |
defaultSubtitleText | string | いいえ | デフォルトの字幕コンテンツ。値は最大 20 文字です。デフォルト値は「Alibaba Cloud Editor」です。 | 3.6.0 |
useDynamicSrc | boolean | いいえ | リソース情報を動的に取得するかどうかを指定します。 | 3.0.0 |
getDynamicSrc | (mediaId: string, mediaType: 'video' | 'audio' | 'image' | 'font', mediaOrigin?:'private' | 'public', inputUrl?: string) => Promise<string>; | いいえ | リソース情報を動的に取得します。useDynamicSrc が true に設定されている場合、このパラメーターは必須です。返される Promise オブジェクトは、新しいリソース情報を解決する必要があります。 | 3.10.0 |
getEditingProjectMaterials | () => Promise<InputMedia[]>; | はい | プロジェクトに関連付けられている素材を取得します。返される Promise オブジェクトは、すべての素材タイプの配列を解決する必要があります。 | 3.0.0 |
searchMedia | (mediaType: 'video' | 'audio' | 'image') => Promise<InputMedia[]>; | はい | 素材ライブラリの [素材のインポート] ボタンに対応する関数。[素材のインポート] をクリックすると、システムはメディアアセット情報を検索し、メディアアセットライブラリから素材ライブラリにメディアアセットをインポートします。返される Promise オブジェクトは、新しい素材の配列を解決する必要があります。 重要 新しいマテリアルをプロジェクトに関連付けるには、AddEditingProjectMaterials を呼び出す必要があります。 | 3.0.0 |
deleteEditingProjectMaterials | (mediaId: string, mediaType: 'video' | 'audio' | 'image') => Promise<void>; | はい | プロジェクトから素材を切り離します。返された Promise オブジェクトを解決する必要があります。 | 3.0.0 |
submitASRJob | (mediaId: string, startTime: string, duration: string) => Promise<ASRResult[]>; | いいえ | インテリジェント字幕認識タスクを送信します。返された Promise オブジェクトは、認識結果の ASRResult 配列を解決する必要があります。 | 3.1.0 AsrConfig の使用を推奨します。AsrConfig を使用すると、submitASRJob メソッドが上書きされます。 |
submitAudioProduceJob | (text: string, voice: string, voiceConfig?: VoiceConfig) => Promise<InputMedia>; | いいえ | 音声合成タスクを送信します。パラメーターは、字幕コンテンツ、音声効果の値、および音声構成です。返された Promise オブジェクトは、生成された音声データを解決する必要があります。 | 4.3.5 TTSConfig の使用を推奨します。TTSConfig を使用すると、submitAudioProduceJob メソッドが上書きされます。 |
licenseConfig | はい | Web SDK を使用するには、ライセンスを設定する必要があります。ライセンスを設定した後にのみ、本番環境で Web SDK を使用できます。ライセンスを設定しない場合、Web SDK は localhost ドメイン名でのみ使用できます。この場合、localhost ドメイン名で Web SDK を使用するとウォーターマークが表示され、本番環境でビデオをプレビューすると黒い画面が表示されます。 | 5.0.1 | |
dynamicSrcQps | number | いいえ | dynamicSrc のリクエストの周波数を制限します。 | 4.13.0 |
getTimelineMaterials | (params: TimelineMaterial[]) => Promise<InputMedia[]> | いいえ | タイムラインにあるマテリアルのメディアアセット情報を取得します。これは、getEditingProjectMaterials に登録されていないサードパーティのメディアアセットなどのメディアアセットを取得するために使用されます。 | 4.13.4 |
asrConfig | いいえ | インテリジェントな字幕タスクを送信するための構成です。 | 4.13.0 | |
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 | いいえ | 公開素材ライブラリの構成。 | 4.13.0 | |
subtitleConfig | いいえ | 字幕の背景グラデーションおよびその他の設定の構成。 | 4.13.0 | |
getStickerCategories | () => Promise<StickerCategory[]>; | いいえ | ステッカーカテゴリを取得します。このパラメーターが渡されない場合、ステッカーはカテゴリ分類されません。返される Promise オブジェクトは、ステッカーカテゴリの配列を解決する必要があります。 | 3.0.0 |
getStickers | (config: {categoryId?: string; page: number; size: number}) => Promise<StickerResponse>; | いいえ | ステッカーを取得します。ステッカーがカテゴリ分けされていない場合、categoryId は空です。返された Promise オブジェクトは、ステッカーの総数とステッカー配列を解決する必要があります。 | 3.0.0 |
getEditingProject | () => Promise<{timeline?: Timeline; projectId?: string; modifiedTime?: string}>; | はい | プロジェクトのタイムラインを取得します。返された Promise オブジェクトは、Timeline データ、プロジェクト ID、および最終更新時間を解決する必要があります。 | 3.0.0 |
updateEditingProject | (data: {coverUrl: string; duration: number; timeline: Timeline; isAuto: boolean}) => Promise<{projectId: string}>; | はい | プロジェクトのタイムラインを保存します。パラメーターは、プロジェクトのサムネイル URL、秒単位の期間、タイムラインデータ、および自動保存するかどうかです。プロジェクトは 1 分に 1 回自動保存されます。返される Promise オブジェクトは、プロジェクト ID を解決する必要があります。 | 3.0.0 |
produceEditingProjectVideo | (data:{ coverUrl: string; duration: number; aspectRatio: PlayerAspectRatio; mediaMarks: MediaMark[]; timeline: Timeline; recommend: IProduceRecommend; }) => Promise<void>; | はい | ビデオを生成します。パラメーターは、プロジェクトのサムネイル URL、秒単位の期間、ビデオの縦横比、メディアアセットマーク、Timeline データ、および推奨データです。推奨データには、ビデオ制作に推奨される解像度とビットレートが含まれています。返された Promise オブジェクトは解決する必要があります。 | 4.4.0 |
customTexts | {importButton?:string;updateButton?:string;produceButton?:string;backButton?:string;logoUrl?:string;} | いいえ | 一部のテキストをカスタマイズします。パラメーターは、ビデオ編集 UI 上の [素材のインポート]、[保存]、[ビデオのエクスポート]、[戻る] ボタン、および左上のロゴのテキストに対応します。 | 3.7.0 |
customFontList | Array<string | CustomFontItem>; | いいえ | カスタムフォントの種類。 | 3.10.0 |
customVoiceGroups | いいえ | カスタム音声オプション。 | 4.3.5 | |
getPreviewWaterMarks | () => Promise<Array<{ url?: string; mediaId?:string; width?: number; height?: number; x?: number; y?: number; xPlusWidth?: number; yPlusHeight?: number; opacity?: number; }>>; | いいえ | プレビューエリアにウォーターマークを追加して、スクリーンショットを防止します。ウォーターマークは本番環境では表示されません。パラメーターは次のとおりです。
| 4.3.5 |
exportVideoClipsSplit | (data: Array<{ coverUrl: string; duration: number; aspectRatio: PlayerAspectRatio; mediaMarks: MediaMark[]; timeline: Timeline; recommend?: IProduceRecommend; }>) => Promise<void>; | いいえ | 選択したタイムラインから複数の独立したクリップを別のタイムラインに分割してエクスポートします。パラメーターは、デフォルトのサムネイル、エクスポートされたタイムラインのデュレーション、エクスポートの縦横比、メディアアセットマーク、エクスポートされたタイムラインクリップ、およびビデオ制作の解像度またはビットレートの推奨データです。 | 4.4.0 |
exportFromMediaMarks | (data: Array<{coverUrl: string; duration: number; aspectRatio: PlayerAspectRatio; mediaMarks: MediaMark[]; timeline:Timeline; recommend?: IProduceRecommend;}>,) => Promise<void>; | いいえ | 選択したタイムラインから複数のマークされたクリップを、それぞれ別のタイムラインに分割してエクスポートします。パラメーターは、デフォルトのサムネイル、エクスポートされるタイムラインの長さ、エクスポートの縦横比、メディアアセットのマーク、エクスポートされるタイムラインクリップ、およびビデオ制作の解像度またはビットレートの推奨データです。 | 4.4.5 |
exportVideoClipsMerge | (data: { coverUrl: string; duration: number; aspectRatio: PlayerAspectRatio; mediaMarks: MediaMark[]; timeline: Timeline; recommend?:IProduceRecommend; }) => Promise<void>; | いいえ | 選択したタイムラインの同じトラックから複数の独立したクリップを 1 つのタイムラインに結合してエクスポートします。パラメーターは、デフォルトのサムネイル、エクスポートされたタイムラインのデュレーション、エクスポートの縦横比、メディアアセットマーク、エクスポートされたタイムラインクリップ、およびビデオ制作の解像度またはビットレートの推奨データです。 | 4.4.0 |
getAudioByMediaId | (mediaId: string) =>Promise<string>; | いいえ | ビデオの音声波形グラフの描画速度を向上させるために、音声 URL を取得します。渡されるパラメーターは、ビデオ素材 ID です。このパラメーターが初期化時に渡されると、SDK は返された音声 URL を優先的に使用して、ビデオの音声波形を解析します。返された Promise オブジェクトは、音声 URL を解決する必要があります。 | 4.3.5 |
hasTranscodedAudio | boolean | いいえ | プロジェクトにインポートされたすべてのビデオにプロキシオーディオ (トランスコードされたオーディオ) があるかどうかを指定します。有効な値:
| 4.3.6 |
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; // 表示名。指定しない場合は、キーが使用されます。 url: string; // フォントの URL。 // フロントエンドとバックエンドでフォントのレンダリングの一貫性を保つために使用されます。ページ上でレンダリングされるテキストサイズは、設定したフォントサイズにこの係数を掛けたものになります。 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; // サンプル音声の URL。 demoMediaId?: string; // サンプル音声の再生 URL。 voiceType: VoiceType; // タイプ。 voice: string; // 音声キー。 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; // デジタルヒューマンビデオデモの URL。 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; // オーディオトラックを分離するためのプロキシオーディオの URL。useDynamicUrl が true に設定されている場合、agentAudioSrc は空のままにできます。 marks?: MediaMark[];// ビデオマーク。 }; }LicenseConfig
// ライセンス構成。 type LicenseConfig = { rootDomain?: string; // ライセンスのルートドメイン名。たとえば、ドメイン名が 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>; // エディターのタイムラインを設定します。 getProjectTimeline: () => any; // エディターのタイムラインを取得します。 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 は UI インタラクションのみを担当し、リクエストを開始しません。Web SDK を使用してリクエストロジックを呼び出す必要があります。リクエストはまずサーバーに送信する必要があります。サーバーは、AccessKey 情報 (AccessKey ID と AccessKey Secret) に基づいて、関連する Alibaba Cloud OpenAPI にリクエストを転送します。
// 注: Web SDK はリクエストメソッドを提供しません。これはデモンストレーションのみを目的としています。axios など、お好みのネットワークリクエストライブラリを使用できます。
window.AliyunVideoEditor.init({
container: document.getElementById('aliyun-video-editor'),
locale: 'zh-CN',
licenseConfig: {
rootDomain: "", // ライセンスのルートドメイン名。例: abc.com。
licenseKey: "", // リクエストされた licenseKey。licenseKey が設定されていない場合、プレビュー中にウォーターマークが表示されます。ライセンスがない場合、localhost ドメインでのみプレビューできます。
},
useDynamicSrc: true, // デフォルトでは、メディアアセットライブラリの再生 URL は有効期限が切れます。したがって、動的に取得する必要があります。
getDynamicSrc: (mediaId, mediaType) => new Promise((resolve, reject) => {
request('GetMediaInfo', { // https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-getmediainfo
MediaId: mediaId
}).then((res) => {
if (res.code === '200') {
// 注: これはデモンストレーションのみを目的としています。実際には、FileInfoList が空の配列である場合のエラーなど、例外を防ぐためにエラーを適切に処理してください。
resolve(res.data.MediaInfo.FileInfoList[0].FileBasicInfo.FileUrl);
} else {
reject();
}
});
}),
getEditingProjectMaterials: () => {
if (projectId) { // projectId がない場合は、Intelligent Media Services コンソールでビデオ編集プロジェクトを作成して取得します。
return request('GetEditingProjectMaterials', { // https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-geteditingprojectmaterials
ProjectId: projectId
}).then((res) => {
const data = res.data.MediaInfos;
return transMediaList(data); // データを変換する必要があります。詳細については、以降のセクションをご参照ください。
});
}
return Promise.resolve([]);
},
searchMedia: (mediaType) => { // mediaType は現在の素材タブ (ビデオ、オーディオ、またはイメージ) を示します。このパラメーターを使用して、同じタイプの追加可能な素材を表示できます。
return new Promise((resolve) => {
// 呼び出し元は、メディアアセットを表示、選択、追加するためのインターフェイスを実装する必要があります。ここでの callDialog は単なる例であり、Web SDK では提供されていません。
// メディアアセットの表示方法については、https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-listmediabasicinfos をご参照ください。
callDialog({
onSubmit: async (materials) => {
if (!projectId) { // projectId がない場合は、まずプロジェクトを作成します。projectId が存在することを確認できる場合、このステップは不要です。
const addRes = await request('CreateEditingProject', { // https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-createeditingproject
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', { // https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-addeditingprojectmaterials
ProjectId: projectId,
MaterialMaps: valueObj,
});
if (res.code === '200') {
return resolve(transMediaList(res.data.MediaInfos));
}
resolve([]);
}
});
});
},
deleteEditingProjectMaterials: async (mediaId, mediaType) => {
const res = await request('DeleteEditingProjectMaterials', { // https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-deleteeditingprojectmaterials
ProjectId: projectId,
MaterialType: mediaType,
MaterialIds: mediaId
});
if (res.code === '200') return Promise.resolve();
return Promise.reject();
},
getStickerCategories: async () => {
const res = await request('ListAllPublicMediaTags', { // https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-listallpublicmediatags
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); // https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-listpublicmediabasicinfos
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', { // https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-geteditingproject
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', { // https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-updateeditingproject
ProjectId: projectId,
CoverURL: coverUrl,
Duration: duration,
Timeline: JSON.stringify(timeline)
}).then((res) => {
if (res.code === '200') {
// Web SDK は自動保存を実行します。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}`;
// Web SDK によって渡されたプレビューの縦横比に基づいて、制作の幅と高さを決定します。
const width = aspectRatio === '16:9' ? 640 : 360;
const height = aspectRatio === '16:9' ? 360 : 640;
// ビデオおよびイメージ素材の幅、高さ、ビットレートデータが渡された場合、この関数から返される recommend データには、使用されたビデオとイメージに基づいて計算された推奨解像度とビットレートが含まれます。
// recommend データ構造については、IProduceRecommend をご参照ください。
// 推奨データを送信インターフェイスに表示するか、送信 API パラメーターで直接使用できます。
const res = await request('SubmitMediaProducingJob', { // https://www.alibabacloud.com/help/en/ims/developer-reference/api-ice-2020-11-09-submitmediaproducingjob
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();
}
});
});
}
});
/**
* サーバーからの素材情報を Web SDK が要求するフォーマットに変換します。
*/
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];
}
}