インテリジェントプロダクションを使用して、オンライン編集プロジェクトのタイムラインをプレビューできます。タイムラインをプレビューするには、対応するファイルを HTML ドキュメントに追加して、プレビューコンポーネントを統合します。このトピックでは、Web 用ビデオ編集 SDK で提供されるプレビューコンポーネントを統合する方法について説明します。
使用上の注意
このトピックでは、Web V5.2.2 用ビデオ編集 SDK を使用します。 Web V5.0.0 以降のビデオ編集 SDK を使用する前に、ライセンスを申請する必要があります。 Web 用ビデオ編集 SDK の最新バージョンについては、インテリジェントメディアサービス(IMS)コンソールの [ビデオ編集プロジェクト] タブの注意事項を参照してください。
手順
プレビューコンポーネントを統合します。
プロジェクトの HTML ドキュメントの
<head>
タグの下に、プレビューコンポーネントの CSS ファイルをインポートします。<head> <link rel="stylesheet" href="https://g.alicdn.com/thor-server/video-editing-websdk/5.2.2/player.css"> </head>
<body>
タグの下に、プレビューウィンドウのマウントに使用する<div>
ノードを追加し、Web 用ビデオ編集 SDK の JavaScript ファイルをインポートしてから、Web 用ビデオ編集 SDK を呼び出す<script>
ノードを追加します。<body> <div id="player-wrapper" style="height:500px"></div> <!-- コンテナの高さをビジネス要件に基づいて変更します。 --> <script src="https://g.alicdn.com/thor-server/video-editing-websdk/5.2.2/player.js"></script> <script> <!-- Web 用ビデオ編集 SDK を呼び出すコードをここに配置します。 --> </script> </body>
プレビューコンポーネントを初期化します。
const player = new window.AliyunTimelinePlayer({ container: document.querySelector('#player-wrapper'), licenseConfig: { rootDomain: "", // ライセンスで使用されるルートドメイン名。例:abc.com。 licenseKey: "", // 適用されるライセンスキー。ライセンスキーが設定されていない場合、localhost ドメイン名でビデオをプレビューするとウォーターマークが表示されます。 }, timeline: { // オプション。 VideoTracks: [], // ビデオトラックを指定します。 AudioTracks: [], // オーディオトラックを指定します。 AspectRatio: '16:9', }, getMediaInfo: (mediaId) => { return Promise.resolve('https://example.com/url/for/this/media.mp4'); }, });
new window.AliyunTimelinePlayer(PlayerInitConfig)
を呼び出してプレビューコンポーネントを初期化する際にPlayerInitConfig
で設定する必要があるパラメータについて、次のセクションで説明します。interface PlayerInitConfig { licenseConfig?: { rootDomain?: string; licenseKey?: string; }; // ライセンス構成 getTimelineMaterials?: (params: TimelineMaterial[]) => Promise<InputMedia[]>; // タイムライン内のメディアアセット素材。 mode?: 'component' | 'player'; // プレーヤーコンポーネントのスタイル。コンポーネントは純粋なコンポーネントです。 componentClass?: string; container: Element; // プレビューコンポーネントのコンテナ。値は HTML 要素です。 locale?: Locales; // ユーザーインターフェース(UI)の言語。有効な値:zh-CN および en-US。デフォルト値:zh-CN。 controls?: boolean; // ビューの下部にコントロールバーを表示するかどうかを指定します。デフォルト値:true。 timeline?: AliyunTimeline; // Web 用ビデオ編集 SDK によって生成されたタイムラインオブジェクト。タイムラインは、API 操作によって生成されたタイムラインとは異なります。 playbackRate?: number; // プレビューコンポーネントが初期化された後の再生速度。デフォルト値:1。このパラメータの値の範囲は、ブラウザの playbackRate 構成によって異なります。 aspectRatio?: string; // プレビューコンポーネントが初期化された後のビデオのアスペクト比。デフォルト値:16:9。幅:高さの形式でカスタムアスペクト比を指定できます。AliyunTimeline に指定したアスペクト比を使用することをお勧めします。 minWidth?: number | string; // プレーヤーの最小幅。 customFontList?: CustomFontItem[]; // カスタムフォント。 getMediaInfo?: ( mediaId: string, mediaType: MediaType, mediaOrigin?: MediaOrigin | undefined, inputUrl?: string | undefined, ) => Promise<string | DynamicSrcObj>; }// Web 用ビデオ編集 SDK と統合する場合に使用する getDynamicSrc メソッドと同様に、mediaId から署名付き再生 URL を取得できます。getDynamicSrc メソッドの詳細については、「Web 用ビデオ編集 SDK と統合する」トピックを参照してください。
AliyunTimelinePlayer
クラスで定義されているメソッドについて、次のセクションで説明します。class AliyunTimelinePlayer { static getSubtitleEffectColorStyles(): Array<{ key: string; cover: string; }>; // ワードアートエフェクトのリストを取得します。 static getSubtitleBubbles(): Array<{ key: string; cover: string; }>;// バブルエフェクトのリストを取得します。 static setDefaultLocale(locale?: Locales): void; // デフォルトの言語を指定します。 static getDefaultFontList(): CustomFontItem[]; // デフォルトフォントのリストを取得します。 static getVideoEffects(): Array<{ subType: string; cover: string; name: string; title: string; category: string | undefined; }>; // 特殊効果のリストを取得します。 static getVideoFilters(): Array<{ subType: string; cover: string; name: string; title: string; category: string | undefined; }>;// フィルタのリストを取得します。 static getVideoTransitions(): Array<{ subType: string; cover: string; name: string; title: string; category: string | undefined; }>;// トランジションのリストを取得します。 static parseTimeline( timeline: string | IServerTimeline, // キャンバスのサイズを指定します。ほとんどの場合、タイムラインの FECanvas フィールドの Width と Height の値が使用されます。 options: { outputWidth: number; outputHeight: number } = { outputWidth: 800, outputHeight: 450 }, ):ParsedResult; // バックエンドのタイムラインをプレビュー用のフロントエンドのタイムラインに変換します。 constructor(config: PlayerInitConfig); play(): void; // 再生を開始します。 pause(): void; // 再生を一時停止します。 destroy(): void; // インスタンスを破棄します。 on(eventName: string, callback: Function): any; // イベントをリッスンします。 once(eventName: string, callback: Function): any; // イベントを一度だけリッスンします。 off(eventName: string): any; // イベントのリッスンを停止します。 get event$(): IObservable<EventData<any>>; // イベントストリームをクエリします。イベントストリームをサブスクライブすることで、すべてのイベントを取得できます。詳細については、RxJS サブスクリプションロジックを参照してください。 get version(): string | undefined; // バージョンをクエリします。 get duration(): number;// 再生時間をクエリします。 get timeline(): any;// 現在のタイムラインをクエリします。 set timeline(timeline: any); // 現在のタイムラインを設定します。 // シーンの幅をクエリします。これは、x 座標と y 座標の絶対値を計算するために使用できます。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 get stageWidth(): number; // シーンの高さをクエリします。これは、x 座標と y 座標の絶対値を計算するために使用できます。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 get stageHeight(): number; // タイムラインの自動解析を設定します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 setTimeline(timeline: any, autoParse?: boolean): Promise<void>; get currentTime(): number;// 再生進捗をクエリします。 set currentTime(currentTime: number); // 再生進捗を設定します。 get controls(): boolean; // 現在の制御の表示状態をクエリします。 set controls(show: boolean); // 現在の制御を非表示にします。 get aspectRatio(): string; // 現在のコンポーネントのアスペクト比をクエリします。 set aspectRatio(ratio: string); // 現在のコンポーネントのアスペクト比(例:16:9)を指定します。 get playbackRate(): number; // 再生速度をクエリします。 set playbackRate(speed: number); // 再生速度を設定します。 setFontList(value: CustomFontItem[]): Promise<void>; // カスタムフォントを設定します。 // トラックデータの変更を監視します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 watchTrack(handler?: (tracks: ExportTrack[]) => void): () => void; // 現在のトラックを削除します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 removeTrack(id: number): void; // トラック属性を設定します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 setTrack(id: number, options: { visible?: boolean; mainTrack?: boolean; }): void; // トラックを追加します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 addTrack(track: {id: number;type: TrackType; clips: ExportClip[];visible: boolean;mainTrack?: boolean;} ): void; // トラック内の素材を削除します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 removeClip(id: number): void; // トラック内の素材の詳細設定をクエリします。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 getClip(id: number): ServerClip; // トラックに素材を追加します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 addClip(clip: ServerClip): void; // 素材の開始点を設定します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 setClipTimelineIn(id: number, timelineIn: number): void; // 素材の終了点を設定します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 setClipTimelineOut(id: number, timelineOut: number): void; // 素材を更新します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 updateClip(id: number, handle: (clip: ServerClip) => ServerClip): void; // 素材の変更を監視します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 watchClip(id: number, handle: (clip: ServerClip | null) => void): () => void; // バックエンドのタイムラインに変換します。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 toBackendTimeline(): { duration: number; timeline: any; }; // トラックをクエリします。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 queryTracks(handler: (track: ExportTrack) => boolean): ExportTrack[]; // 素材をクエリします。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 queryClips(handler: (clip: ExportClip, track: ExportTrack) => boolean): ExportClip[]; // 素材をハイライト表示して、自由に移動できるようにします。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 focusClip(id: number, autoSeek?: boolean): void; // 素材のハイライト表示をキャンセルします。このメソッドは、Web V5.2.2 以降のビデオ編集 SDK でのみ機能します。 blurClip(): void; } // watchTrack メソッドからエクスポートされたクリップ素材。getClip メソッドを呼び出して、クリップ素材の属性をクエリできます。 interface ExportClip { id: number; type: MaterialType; timelineIn: number; timelineOut: number; } // watchTrack メソッドからエクスポートされたトラック。 interface ExportTrack { id: number; type: TrackType; clips: ExportClip[]; visible: boolean; mainTrack?: boolean; } // カスタムフォント。 interface CustomFontItem { key: string; // フォントの一意の識別子。 name?: string; // フォントの表示名。 url: string; // フォントの URL。 urlType?: 'dynamic' | 'static'; // フォント URL を getMedinfo メソッドを呼び出して動的に取得する必要がある場合は、このパラメータを dynamic に設定します。それ以外の場合は、このパラメータを static に設定します。 } // プレーヤーの状態。 enum PLAYER_STATE { PLAYING = 0, PAUSED = 1, STALLED = 2, ENDED = 3, BROKEN = 4 } // フロントエンドのタイムラインの解析結果。 interface ParsedResult { success: boolean; // 解析が成功したかどうかを示します。 logs: any[]; timeline: IServerTimeline; // タイムラインの解析結果。 toBackendTimeline: (fTimeline: IServerTimeline) => IServerTimeline; // フロントエンドのタイムラインをサーバーのタイムラインに変換します。 mediaMap: ParsedMediaMap; output: { width: number; height: number; }; fontList: Array<{ key: string; url: string }>; } type ParsedMediaMap = { [key: string]: { mediaType: string; mediaId: string; mediaUrl?: string; width?: number; height?: number; duration: number; }; } type InputMedia = (InputVideo | InputAudio | InputImage); interface InputVideo { mediaId: string; mediaIdType?: MediaIdType; mediaType: 'video'; video: { duration: number; }; } interface InputAudio { mediaId: string; mediaIdType?: MediaIdType; mediaType: 'audio'; audio: { duration: number; }; } interface InputImage { mediaId: string; mediaIdType?: MediaIdType; mediaType: 'image'; image: { coverUrl?: string; }; } type MediaIdType = 'mediaId' | 'mediaURL';
インスタンスを破棄します。
destroy
メソッドを呼び出して、インスタンスを破棄します。インスタンスが破棄されると、container パラメータは空になります。player.destroy();
サンプルコード
次のサンプルコードは、カスタムフォント、トランジション、エフェクトを使用してタイムラインベースのプレビュープレーヤーを作成し、字幕を編集できる例を示しています。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
rel="stylesheet"
href="https://g.alicdn.com/thor-server/video-editing-websdk/5.2.2/player.css"
/>
<script src="https://g.alicdn.com/thor-server/video-editing-websdk/5.2.2/player.js"></script>
<title>オンライン編集プレビュープレーヤー</title>
</head>
<body>
<div id="root" style="width: 820px;margin: 30px auto;" >
<div id="player" style="width: 800px; height: 450px"></div>
<div style="margin-top: 16px">
<div>
<label>ID</label> <br/>
<input id="subtitle" value="123" />
<br/>
<label>コンテンツ</label> <br/>
<textarea id="content" rows="4" >カスタム字幕</textarea>
</div>
<button id="addSubtitle">字幕を追加</button>
<button id="updateSubtitle">字幕を修正</button>
<button id="moveSubtitle">字幕を移動</button>
<button id="removeSubtitle">字幕を削除</button>
</div>
</div>
<script type="text/javascript">
const timelineDemo = {
Version: 1,
SdkVersion: "4.12.2",
VideoTracks: [
{
// ビデオトラック
Id: 1,
Type: "Video",
Visible: true,
Disabled: false,
Count: 1,
VideoTrackClips: [
{
// 画像
Id: 3,
TrackId: 1,
Type: "Image",
MediaURL:
"https://img.alicdn.com/imgextra/i4/O1CN01TDN7Gw1SCgVv61T4s_!!6000000002211-0-tps-1920-1046.jpg",
Title: "test.png",
X: 0,
Y: 0,
Width: 1,
Height: 1,
TimelineIn: 0,
TimelineOut: 5,
Duration: 5,
VirginDuration: 5,
},
{
// ビデオ
Id: 4,
TrackId: 1,
Type: "Video",
MediaURL:
"https://ice-pub-media.myalicdn.com/vod-demo/%E6%9C%80%E7%BE%8E%E4%B8%AD%E5%9B%BD%E7%BA%AA%E5%BD%95%E7%89%87-%E6%99%BA%E8%83%BD%E5%AD%97%E5%B9%95.mp4",
X: 0,
Y: 0,
Width: 1,
Height: 1,
TimelineIn: 4, // トランジションの開始点は、前のマテリアルの終了点よりも前である必要があります。
TimelineOut: 9,
Duration: 5,
VirginDuration: 5,
Effects: [
{
// トランジション
Type: "Transition",
Id: 13,
Name: "transitions.directional",
SubType: "directional",
Duration: 1, // トランジションの継続時間 = 前のマテリアルの終了点 - 現在のマテリアルの開始点
From: 3, // 前のマテリアルの ID。
},
],
},
],
},
{
// エフェクトトラック
Id: 2,
Type: "Effect",
Visible: true,
Disabled: false,
Count: 1,
VideoTrackClips: [
{
Type: "VFX",
Id: 2,
TrackId: 1,
SubType: "heartfireworks",
TimelineIn: 0,
TimelineOut: 5,
Duration: 5,
X: 0,
Y: 0,
Width: 0,
Height: 0,
},
],
},
],
AudioTracks: [],
SubtitleTracks: [
{
Id: 2,
Type: "Text",
Visible: true,
Disabled: false,
Count: 1,
SubtitleTrackClips: [
{
Id: 1,
TrackId: 2,
Type: "Text",
X: 0,
Y: 0,
TimelineIn: 0,
TimelineOut: 2,
Duration: 2,
VirginDuration: 2,
FontSize: 30,
FontColor: "#333333",
FontColorOpacity: 1,
Content: "FontUrl パラメータで指定されたカスタムフォントのテキスト",
Alignment: "BottomCenter",
// カスタムフォント
FontUrl:
"https://ice-pub-media.myalicdn.com/mts-fonts/%E7%AB%99%E9%85%B7%E6%96%87%E8%89%BA%E4%BD%93.ttf",
},
],
},
],
AspectRatio: "16:9",
From: "websdk",
FECanvas: {
Width: 800,
Height: 450,
},
FEConfig: {
AutoProportion: "681:383",
},
};
const player = new window.AliyunTimelinePlayer({
container: document.getElementById("player"),
getMediaInfo: async (mediaId, mediaType, mediaOri) => {
console.log(">>>", mediaId, mediaType, mediaOri);
// タイムラインの mediaUrl パラメータによって URL が指定されている場合、インターネット経由でアクセスできる場合は、URL を直接返すことができます。
return mediaId;
/**
URL を動的にリクエストする必要がある場合は、次のサンプルコードを参照してください。
* if (mediaType === "font") {
params.InputURL = InputURL;
delete params.MediaId;
}
if (mediaOrigin === "mediaURL") {
params.InputURL = mediaId;
delete params.MediaId;
}
const apiName =
mediaOrigin === "public" ? "GetPublicMediaInfo" : "GetMediaInfo";
return request(apiName, {
// https://www.alibabacloud.com/help/ja/ims/developer-reference/api-ice-2020-11-09-getmediainfo
MediaId: mediaId,
})
.then((res) => {
// 次のサンプルコードは参照用にのみ提供されています。エラーロジックを設定することをお勧めします。たとえば、FileInfoList が空の配列の場合に返されるエラーメッセージを設定できます。
const fileInfoList = get(res, "data.MediaInfo.FileInfoList", []);
let mediaUrl, maskUrl;
let sourceFile = fileInfoList.find((item) => {
return item?.FileBasicInfo?.FileType === "source_file";
});
if (!sourceFile) {
sourceFile = fileInfoList[0];
}
const maskFile = fileInfoList.find((item) => {
return (
item.FileBasicInfo &&
item.FileBasicInfo.FileUrl &&
item.FileBasicInfo.FileUrl.indexOf("_mask") > 0
);
});
if (maskFile) {
maskUrl = get(maskFile, "FileBasicInfo.FileUrl");
}
mediaUrl = get(sourceFile, "FileBasicInfo.FileUrl");
const codec = get(sourceFile, "VideoStreamInfoList[0].CodecName");
return {
url: mediaUrl,
codec,
maskUrl,
};
})
.catch((ex) => {
// 外部 URL のエラーロジック。
if (mediaOrigin === "mediaURL") {
return mediaId;
}
});
*
* **/
},
});
// フロントエンドでタイムラインをプレビューする場合、setTimeline メソッドを呼び出すと、MediaUrl パラメータとフォントファイルが自動的に解析されます。
player.setTimeline(timelineDemo);
// toBackendTimeline を使用して、フロントエンドのタイムラインをバックエンドのタイムラインに変換できます。
console.log("toBackendTimeline", player.toBackendTimeline());
document.getElementById("addSubtitle").addEventListener("click", () => {
player.addClip({
Id: Number(document.getElementById('subtitle').value),
TrackId: 2,
Type: "Text",
X: 0,
Y: 0,
TimelineIn: player.currentTime,
TimelineOut: player.currentTime + 2,
Duration: 2,
VirginDuration: 2,
FontSize: 30,
FontColor: "#333333",
FontColorOpacity: 1,
Content: document.getElementById('content').value,
Alignment: "TopCenter",
// カスタムフォント
FontUrl:
"https://ice-pub-media.myalicdn.com/mts-fonts/%E7%AB%99%E9%85%B7%E6%96%87%E8%89%BA%E4%BD%93.ttf",
});
});
document.getElementById("updateSubtitle").addEventListener("click", () => {
player.updateClip(Number(document.getElementById('subtitle').value),(item)=>{
return Object.assign({},item,{Content: document.getElementById('content').value})
});
});
document.getElementById("moveSubtitle").addEventListener("click", () => {
player.focusClip( Number(document.getElementById('subtitle').value));
});
document.getElementById("removeSubtitle").addEventListener("click", () => {
player.blurClip();
player.removeClip( Number(document.getElementById('subtitle').value));
});
// トラックの変更を監視します。
player.watchTrack((tracks)=>{
console.log('タイムラインの変更:');
console.log(JSON.stringify(tracks,null,4));
});
</script>
</body>
</html>
プレビューコンポーネントで複雑な操作(トラック、字幕、ビデオエフェクト、トランジション、位置、幅と高さの設定、プレーヤー UI のカスタマイズなど)を実行する方法の詳細については、オープンソースデモを参照してください。デモの実行方法については、Web 用ビデオ編集デモを実行するを参照してください。
FAQ
タイムラインを更新するにはどうすればよいですか?
AliyunTimelinePlayer
のインスタンスが作成された後、タイムラインに値を割り当てることでタイムラインを更新します。
player.timeline = {....}
キャッシュが原因で問題が発生した場合は、タイムラインに null 値を割り当て、タイムラインの内容をクリアしてから、タイムラインに別の値を割り当てます。
player.timeline = {} // タイムラインに null 値を割り当て、タイムラインの内容をクリアします。
プレビューされたビデオのフォントサイズが出力ビデオのフォントサイズと一致しません。なぜですか?
出力ビデオのフォントサイズが小さくなった場合は、タイムラインに FECanvas フィールドが含まれていることを確認してください。FECanvas
フィールドは、プレビュープレーヤーの解像度を指定します。ビデオ制作中に、サーバーはプレビュープレーヤーと出力ビデオの解像度に基づいてフォントをスケーリングします。次のサンプルコードは、プレビュープレーヤーの通常の解像度を示しています。
//16:9
FECanvas: {Width: 800, Height: 450}
//9:16
FECanvas: {Width: 253.125, Height: 450}
プレビュープレーヤーの組み込み素材を取得するにはどうすればよいですか?
// フォントのリストを取得します。
AliyunTimelinePlayer.getDefaultFontList();
// ワードアートエフェクトのリストを取得します。
AliyunTimelinePlayer.getSubtitleEffectColorStyles();
// バブルエフェクトのリストを取得します。
AliyunTimelinePlayer.getSubtitleBubbles();
// 特殊効果のリストを取得します。
AliyunTimelinePlayer.getVideoEffects();
// フィルタのリストを取得します。
AliyunTimelinePlayer.getVideoFilters();
// トランジションのリストを取得します。
AliyunTimelinePlayer.getVideoTransitions();
パラメータを指定するときは、スペースを保持する必要があります。例:"Font":"Alibaba PuHuiTi",
。
プレビュープレーヤーの複数のインスタンスはサポートされていますか?
いいえ。内部実装の制限により、プレビュープレーヤーの単一インスタンスのみがサポートされています。
次のエラーメッセージが表示された場合はどうすればよいですか? player.js:27 TypeError: Cannot read properties of undefined (reading 'GLctx')?
このエラーメッセージは、ブラウザでハードウェアアクセラレーションが無効になっている場合に表示されます。ブラウザのカーネルバージョンが Chrome で、ブラウザのバージョン番号が 80 より大きく、ブラウザでハードウェアアクセラレーションが有効になっていることを確認してください。
Web 用ビデオ編集 SDK は Chrome のみサポートしています。