すべてのプロダクト
Search
ドキュメントセンター

ApsaraVideo VOD:ビデオの編集

最終更新日:Sep 12, 2025

ショートビデオ SDK は、ビデオ編集およびエクスポート機能を提供します。ビデオ、画像、素材をインポートし、フィルター、ダビング、タイムエフェクトなどの効果をビデオに追加できます。

対応エディション

エディション

説明

Professional

すべての機能がサポートされています。

Standard

字幕、アニメーション ステッカー、ミュージックビデオ(MV)を除く機能がサポートされています。

Basic

サポートされていません。

関連クラス

機能

クラス

説明

初期化

AliyunIEditor

ビデオ編集を定義するコアクラス。

AliyunEditorFactory

ファクトリクラス。

ビデオ管理

AliyunIClipConstructor

ビデオソースを管理するために使用されるクラス。

AliyunImageClip

ビデオ編集で使用されるイメージを定義するクラスです。サポートされているイメージフォーマット: JPG、PNG、GIF。

AliyunVideoClip

ビデオ編集で使用されるビデオクリップを定義するクラスです。サポートされているビデオフォーマット: MP4、MOV、FLV。

ビデオ効果設定

EffectBean

フィルターと MV のモデル。

EffectFilter

アニメーションフィルターのモデル。

TransitionBase

トランジション効果のモデル。

ピクチャインピクチャ (PiP) 設定

AliyunIPipManager

PiP マネージャー。 PiP 効果の作成、変更、クエリ、削除ができます。

AliyunIPipController

PiP コントローラー。 PiP 効果の開始時刻と終了時刻を指定できます。

AliyunIPipTrack

トラック情報を取得するために使用されるクラス。

AliyunILayoutController

レイアウトコントローラーを定義するクラス。 PiP 効果の位置、スケール、回転、アルファなどの設定を構成できます。

AliyunIAnimationController

アニメーションコントローラーを定義するクラス。 PiP 効果にアニメーションを追加できます。

AliyunIAudioController

オーディオコントローラーを定義するクラス。音量、ノイズリダクション、効果音、フェードイン、フェードアウトなどのオーディオ設定を構成できます。

AliyunIAugmentationController

補強コントローラーを定義するクラス。彩度、輝度、コントラストなどの補強設定を構成できます。

字幕とアニメーション ステッカーの設定

AliyunPasterManager

字幕とアニメーション ステッカーを管理するために使用されるクラス。

AliyunPasterControllerCompoundCaption

字幕コントローラーを定義するクラス。

AliyunPasterController

アニメーション ステッカー コントローラーを定義するクラス。

ドラフトボックス

AliyunEditorProject

プロジェクト構成を定義するクラス。

AliyunDraftManager

ドラフトを管理するために使用されるクラス。

AliyunDraft

ドラフト構成を管理するために使用されるクラス。

AliyunDraftResourceLoader

リソースローダーを定義するクラス。

AliyunDraftResourceUploader

リソースアップローダーを定義するクラス。

AliyunDraftResourceDownloader

リソースダウンローダーを定義するクラス。

AliyunDraftResTask

ドラフトタスクを定義するクラス。

ビデオ編集プロセス

構成

ステップ

説明

サンプルコード

基本構成

1

エディターを作成して初期化する。

エディターの初期化

2

ビデオ編集中に、ビデオのトリミング、ビデオソースの変更、トランジション時間と効果の変更を行う。ビデオ編集のコアクラスは AliyunIEditor クラスです。

ビデオの管理

3

プレビューを構成する。

プレビューの構成

高度な構成

4

フィルター、トランジション、MV などの効果を構成する。

ビデオ効果の構成

5

BGM、ダビング、効果音を構成する。

音楽と効果音の構成

6

PiP を構成する。

PiP の構成

7

字幕、ワードアート、吹き出し、アニメーション ステッカーを構成する。

字幕とアニメーション ステッカーの構成

8

ドラフトボックスに保存されているビデオを編集するか、編集したビデオをドラフトボックスに保存する。

ドラフトボックス

9

タイムエフェクト、ウォーターマーク、落書きを構成する。

その他の設定

エディターの初期化

エディターを作成して初期化する。コードで使用されているパラメーターの詳細については、「関連クラス」をご参照ください。

// 1. エディターを作成します。
// configPath はインポートされたビデオの URL で、ドラフトボックスの URL、または AliyunIImport.generateProjectConfigure() を呼び出した後に生成される URL です。
Uri uri = Uri.parse(configPath); 

AliyunIEditor editor = AliyunEditorFactory.creatAliyunEditor(uri, null);

// 2: エディターを初期化します。
// エディターを初期化し、プレビューウィンドウを構成します。
editor.init(surfaceView, context);


// 3. エディターを使用する必要がなくなった場合は、onDestroy() を呼び出してインスタンスを破棄します。
editor.onDestroy()

ビデオの管理

AliyunIClipConstructor クラスを使用して、ビデオエディター内のビデオまたは画像を管理できます。 AliyunIClipConstructor を呼び出してビデオエディター内のビデオまたは画像を変更した後、AliyunIEditor.applySourceChange() を呼び出して変更を適用します。

コードで使用されているパラメーターの詳細については、「関連クラス」をご参照ください。

ビデオソース管理

// 1. ビデオソースマネージャーを取得します。
AliyunIClipConstructor contructor = AliyunIEditor.getSourcePartManager();


// 2. ビデオまたは画像を追加します。この手順はオプションです。

// タイムラインの最後にビデオまたは画像を追加します。 AliyunVideoClip を呼び出してビデオを追加するか、AliyunImageClip を呼び出して画像を追加できます。
contructor.addMediaClip(AliyunClip clip);

// 指定した位置にビデオまたは画像を追加します。 AliyunVideoClip を呼び出してビデオを追加するか、AliyunImageClip を呼び出して画像を追加できます。
contructor.addMediaClip(int index, AliyunClip clip);

// 3. ビデオまたは画像を削除します。この手順はオプションです。

// 最後のビデオまたは画像を削除します。
contructor.deleteMediaClip();

// 指定したビデオまたは画像を削除します。
contructor.deleteMediaClip(int index);

// 4. ビデオまたは画像を置き換えます。この手順はオプションです。
// 指定した位置にあるビデオまたは画像を置き換えます。
contructor.updateMediaClip(int index, AliyunClip clip);

// すべてのビデオまたは画像を置き換えます。
contructor.updateAllClips(List<AliyunClip> clips);


// 5. 更新を適用します。メディアファイルの構成が完了したら、次のメソッドを呼び出してこれらの更新を適用し、変更を有効にします。
AliyunIEditor.applySourceChange();

その他の操作

// メディアファイルの位置を調整します。    
contructor.swap(int pos1, int pos2);

// メディアファイルの数を取得します。    
contructor.getMediaPartCount();

// メディアファイルのリストを取得します。    
contructor.getAllClips();

プレビューの構成

ビデオ編集中に、ビデオの再生、一時停止、再生タイムラインの期間の取得などの操作を実行できます。コードで使用されているパラメーターの詳細については、「関連クラス」をご参照ください。

// 再生を開始します。    
AliyunIEditor.play();

// 再生を再開します。
AliyunIEditor.resume();

// 再生を一時停止します。
AliyunIEditor.pause();

// 指定した位置にシークします。
AliyunIEditor.seek(long time);

// 音声をミュートするかどうかを指定します。
AliyunIEditor.setAudioSilence(boolean silence);

// 音量を構成します。    
AliyunIEditor.setVolume(int volume);

// ビデオの表示モードを構成します。    
AliyunIEditor.setDisplayMode(VideoDisplayMode mode);

// スケーリングモードの背景色を構成します。
AliyunIEditor.setFillBackgroundColor(int color);

// タイムエフェクトの影響を受けない、ストリームの現在位置を取得します。
AliyunIEditor.getCurrentStreamPosition();

// タイムエフェクトの影響を受けない、再生タイムライン上の現在位置を取得します。
AliyunIEditor.getCurrentPlayPosition();

// タイムエフェクトの影響を受けない、ストリームの期間を取得します。
AliyunIEditor.getStreamDuration();

// タイムエフェクトの影響を受ける、合計再生期間を取得します。
AliyunIEditor.getDuration();

ビデオ効果の構成

フィルター、トランジション効果、MV などのカスタムビデオ効果を構成および作成できます。詳細については、「フィルターとトランジション効果」および「MV」をご参照ください。コードで使用されているパラメーターの詳細については、「関連クラス」をご参照ください。

  • フィルターには、ルックアップテーブル(LUT)フィルター、静的フィルター、アニメーションフィルターが含まれます。

    • LUT フィルター: ルックアップテーブルを使用してピクセルを置き換えます。

    • 静的フィルター: シェーディング言語を記述することでピクセルを計算します。アニメーション効果はサポートされていません。静的フィルターの Bean は EffectBean です。詳細については、EffectBean をご参照ください。

    • アニメーションフィルター: シェーディング言語を記述することでピクセルを計算します。アニメーション効果がサポートされています。アニメーションフィルターの Bean は EffectFilter です。詳細については、「EffectFilter」をご参照ください。

  • ショートビデオ SDK は、次のトランジション効果を提供します。TransitionCircle (アイリスラウンド)、TransitionFade (フェードインとフェードアウト)、TransitionFiveStar (スター)、TransitionShutter (ブラインド)、TransitionTranslate (スライド)。

LUT フィルター

LUTEffectBean bean = new LUTEffectBean();
bean.setPath("image_01.png");
bean.setIntensity(1.f);

// LUT フィルターを追加します。
mAliyunIEditor.applyLutFilter(bean);
// LUT フィルターを削除します。
mAliyunIEditor.applyLutFilter(null);

静的フィルター

EffectBean effect = new EffectBean();
effect.setId(id)
effect.setSource(new Souce(filePath));

// フィルターを追加します。
AliyunIEditor.applyFilter(effect);
// フィルターを削除します。
AliyunIEditor.applyFilter(new EffectBean());

アニメーションフィルター

EffectFilter effectFilter = new EffectFilter(new Souce(filePath));
effectFilter.setStartTime(startTime);
effectFilter.setDuration(duration);

// アニメーションフィルターを追加します。
AliyunIEditor.addAnimationFilter(effectFilter);

// アニメーションフィルターを削除します。
AliyunIEditor.removeAnimationFilter(effectFilter);
// すべてのアニメーションフィルターを削除します。
AliyunIEditor.clearAllAnimationFilter();

トランジション効果

// 1. トランジション効果を構成します。
// トランジション効果を構成します。 index は、トランジションが開始される再生タイムライン上の位置を指定します。 index が 0 に設定されている場合、トランジションは最初のビデオの終わりに開始されます。トランジションをキャンセルするには、パラメーターを null に設定します。
AliyunEditor.setTransition(int index, TransitionBase transition); 

// 一度に複数のトランジション効果を構成します。トランジションをキャンセルするには、パラメーターを null に設定します。
AliyunEditor.setTransition(Map<Integer, TransitionBase> transitions); // 複数のトランジション効果を構成します。


// 2. トランジション効果を更新します。
// 別のトランジション効果を使用して、トランジション効果を更新します。パラメーターを null に設定することはできません。
AliyunEditor.updateTransition(int index, TransitionBase transition); 

MV

カスタム MV を作成できます。詳細については、「MV」をご参照ください。

// MV を追加します。
AliyunIEditor.applyMV(EffectBean effect);

// MV を削除します。
AliyunIEditor.applyMV(null);

音楽と効果音の構成

音楽

音楽には、BGM とダビング音声があります。 BGM は、速度ランプ、ループ、逆再生などのタイムエフェクトの影響を受けません。ダブはタイムエフェクトの影響を受けます。コードで使用されているパラメーターの詳細については、「関連クラス」をご参照ください。

EffectBean musicBean = new EffectBean();
musicBean.setId(effectInfo.id);
musicBean.setSource(effectInfo.getSource());

                    
// 音楽を変更した後、シーク操作を呼び出して値を 0 に設定し、音楽キャッシュをクリアして、音楽が開始直後に停止しないようにする必要があります。
musicBean.setStartTime(startTime);
musicBean.setDuration(Integer.MAX_VALUE);// 期間を最大値に設定します。
musicBean.setStreamStartTime(streamStartTime);
musicBean.setStreamDuration(streamDuration);

int audioSteamId;
// 1. BGM またはダビング音声を追加します。
audioSteamId = AliyunIEditor.applyMusic (musicBean);// BGM を追加します。
AliyunIEditor.applyDub(EffectBean effect);// ダビング音声を追加します。

// 2. BGM またはダビング音声を削除します。
AliyunIEditor.removeMusic(EffectBean effect);// BGM を削除します。
AliyunIEditor.removeDub(EffectBean effect);// ダビング音声を削除します。

// 3. BGM またはダビングが元のオーディオとミキシングされている場合、BGM またはダビングの重みを調整します。
AliyunIEditor.applyMusicMixWeight(int audioSteamId, int weight);

// 4. 指定されたオーディオストリームの音量を調整します。
// BGM、ダビング音声、元のオーディオの詳細については、API リファレンスをご参照ください。
AliyunIEditor.applyMusicWeight(int audioSteamId, int weight);

// 5. 指定されたオーディオストリームでノイズリダクションを実行します。
AliyunIEditor.denoise(int audioSteamId, boolean needDenoise);

効果音

ショートビデオ SDK は、次の効果音を提供し、オーディオストリームに効果音を追加できます。

  • AudioEffectType.EFFECT_TYPE_LOLITA (活発な女性の声)

  • AudioEffectType.EFFECT_TYPE_REVERB (残響)

  • AudioEffectType.EFFECT_TYPE_UNCLE (ハスキーな男性の声)

  • AudioEffectType.EFFECT_TYPE_ECHO (エコー)

  • AudioEffectType.EFFECT_TYPE_ROBOT (ロボット)

  • AudioEffectType.EFFECT_TYPE_BIG_DEVIL (不吉な)

  • AudioEffectType.EFFECT_TYPE_MINIONS (ミニオン)

  • AudioEffectType.EFFECT_TYPE_DIALECT (中国の方言)

// 1. 効果音を構成します。
// AudioEffectType の詳細については、API リファレンスをご参照ください。
int audioEffect(int audioSteamId, AudioEffectType type, int weight);

// 2. 効果音を削除します。
// 効果音は互いに重複する可能性があります。新しい効果音を使用する前に、既存の効果音を削除してください。
int removeAudioEffect(int audioSteamId, AudioEffectType type);

PiP の構成

PiP 機能を使用すると、既存のメイントラックに 1 つ以上の PiP 効果を追加できます。

  • メイントラック: 編集ページのデフォルトトラック。メイントラックは 1 つだけ許可されます。メイントラックには複数のビデオストリームを含めることができます。

  • PiP: 複数の PiP 効果を追加し、位置、スケーリング、回転などの PiP 効果の設定を構成できます。デフォルトでは、PiP 効果を作成すると、PiP トラックが自動的に作成されます。 PiP 効果は、異なる PiP トラックで移動できます。

説明

ショートビデオ SDK は、PiP 効果の数を制限していません。ただし、同時に 3 つ以上の PiP 効果を追加しないことをお勧めします。 PiP 効果の最大数は、ユーザーが決定します。

コードで使用されているパラメーターの詳細については、「関連クラス」をご参照ください。

// AliyunIEditor で PiP マネージャーを取得します。
AliyunIPipManager pipManager = mAliyunIEditor.getPipManager();

// PiP 効果を追加します。
mAliyunIEditor.puase(); // ビデオを一時停止します。
long current = mAliyunIEditor.getCurrentPlayPosition(); // 再生タイムライン上の現在位置を取得します。
AliyunIPipManager pipManager = mAliyunIEditor.getPipManager();
AliyunIPipController pipController = pipManager.createNewPip ("ストリームファイルの URL");
pipController.setTimelineStartTime(current) // トラックの現在の時点から開始します。
                .setClipStartTime(0) // ビデオでの PiP 効果の開始時刻。
                .apply(); // 設定を適用します。


// PiP 効果を削除します。
mAliyunIEditor.puase(); // ビデオを一時停止します。
AliyunIPipManager pipManager = mAliyunIEditor.getPipManager();
pipManager.removePip(pipController);


// AliyunILayoutController を呼び出してレイアウトを変更します。
mAliyunIEditor.puase(); // ビデオを一時停止します。
AliyunILayoutController layoutController = pipController.getLayoutController(); // レイアウトコントローラーを取得します。
layoutController.setRotation(3.14) // 回転ラジアンを指定します。有効な値: 0 ~ 3.14。
                .setScale(0.3) // スケールを指定します。
                .setPosition(0.5, 0.5) // レイアウトを中央揃えにします。
                .apply();

// キャンバス内の PiP 効果の位置を取得します。
RectF rectf = pipController.getPipRectFInCurrentScreen(); // PiP 効果が配置されている四角形領域を取得します。
int width = mSurfaceView.getWidth() * rectf.width(); // キャンバス内の PiP 効果の実際の幅。
int height = mSurfaceView.getWidth() * rectf.height(); // キャンバス内の PiP 効果の実際の高さ。


// AliyunIAudioController を呼び出してサウンドを変更します。
mAliyunIEditor.puase(); // ビデオを一時停止します。
AliyunIAudioController audioController = pipController.getAudioController(); // オーディオコントローラーを取得します。
audioController.setVolume(100) // 音量を最大値に設定します。
                .setAudioEffect(AudioEffectType.EFFECT_TYPE_LOLITA) // 効果音を活発な女性の声に設定します。
                .apply(); // 適用します。


// AliyunIAnimationController を呼び出して、PiP 効果にアニメーションを追加します。
mAliyunIEditor.puase(); // ビデオを一時停止します。
AliyunIAnimationController animationController = pipController.getAnimationController();
if (mActionTranslate == null) { // 移動アニメーションを追加します。
    mActionTranslate = new ActionTranslate();
    mActionTranslate.setFromPointX(-1);
    mActionTranslate.setFromPointY(-1);
    mActionTranslate.setToPointX(1);
    mActionTranslate.setToPointY(1);
    mActionTranslate.setStartTime(pipController.getTimeLineStartTimeInMillis() * 1000);
    mActionTranslate.setDuration(pipController.getClipDurationInMillis() * 1000);
    animationController.addFrameAnimation(mActionTranslate);
} else { // 移動アニメーションを削除します。
    animationController.removeFrameAnimation(mActionTranslate);
    mActionTranslate = null;
}


// AliyunIAugmentationController を呼び出して、補強設定を構成します。
mAliyunIEditor.puase(); // ビデオを一時停止します。
AliyunIAugmentationController augmentationController=pipController.getAugmentationController(); // 補強コントローラーを取得します。
augmentationController.setVignette(0 to 1) // ビネットを指定します。
                        .setSharpness(0 to 1) // シャープネスを指定します。
                        .setSaturation(0 to 1) // 彩度を指定します。
                        .apply(); // 適用します。

// AliyunIPipTrack を呼び出して、トラックに関する情報を取得します。
// 方法 1: 管理クラスからすべてのトラックを取得します。
AliyunIPipManager pipManager = mAliyunIEditor.getPipManager();
List<AliyunIPipTrack> pipTrackList=pipManager.getPipTracks(); // すべての PIP トラックを取得します。

// 方法 2: 現在の コントローラーが配置されているトラックを取得します。
AliyunIPipTrack pipTrack = pipController.getOwnerTrack();
List<AliyunIPipController> pipControllers=pipTrack.getPipClips(); // 現在のトラック上のすべての PiP 効果のコントローラーを取得します。

字幕とアニメーション ステッカーの構成

AliyunPasterManager を使用して、字幕とアニメーション ステッカーを管理できます。 AliyunPasterManager 内の AliyunIPasterController を使用して、字幕とアニメーション ステッカーに対する操作を実行できます。コードで使用されているパラメーターの詳細については、「関連クラス」をご参照ください。

ショートビデオ SDK は、字幕のワードアートと吹き出し効果を提供します。ワードアート、吹き出し、アニメーション ステッカーの作成方法の詳細については、「ワードアート」および「アニメーション ステッカー」をご参照ください。

字幕

字幕を追加または削除する

Source fontSouce = null;
long startTime = 0L;
long duration = 20000L;

// 1. 字幕を追加します。
AliyunPasterControllerCompoundCaption captionController=pasterManager.addCaptionWithStartTime ('テキスト', null, fontSouce, startTime,duration);

// 2. 字幕を削除します。
controller.remove()

字幕のプロパティを変更する

AliyunPasterControllerCompoundCaption を使用して、字幕に関連するすべての操作を呼び出すことができます。詳細については、API リファレンスをご参照ください。字幕のプロパティを変更するたびに、AliyunPasterControllerCompoundCaption.apply() を呼び出して変更を有効にする必要があります。

// 背景色を指定します。
captionController.setColor(AliyunColor color);
// フォントを指定します。
captionController.setFontPath(ISouce fontPath);
// 上記の変更を適用します。
captionController.apply();

ワードアート

Source fontEffectSource(fontEffectFolder);

// 1. ワードアートを適用します。
captionController.setFontEffectTemplate(fontEffectSource)

// 2. ワードアートを削除します。
captionController.setFontEffectTemplate(null)

吹き出し

Source bubbleEffectSource(bubbleEffectFolder);
// 1. 吹き出しを適用します。
captionController.setBubbleEffectTemplate(bubbleEffectSource)

// 2. 吹き出しを削除します。
captionController.setBubbleEffectTemplate(null)

アニメーション ステッカー

アニメーション ステッカーを追加する

AliyunPasterController pasterController = pasterManager.addPasterWithStartTime(Source path, long startTime, long duration);

アニメーション ステッカーのプロパティを構成する

アニメーション ステッカーは、Android UI に表示されるアニメーション効果です。 AliyunPasterBaseView を呼び出して、サイズ、幅と高さ、回転角度などのプロパティを定義し、Android UI にステッカーを表示する必要があります。 Android UI 用に構成したアニメーション ステッカーは、プラットフォームレイヤーにも表示されます。レンダリングレイヤーでステッカーを表示または非表示にして、ステッカーの重複を防ぐことができます。

// 次のメソッドを呼び出す必要があります。
pasterController.setPasterView(AliyunPasterBaseView pasterView);

// ステッカーを表示します。
pasterController.editCompleted();

// ステッカーを非表示にします。
pasterController.editStart();

ステッカーをプレビューする

// プレビューを構成します。
pasterController.createPasterPlayer(TextureView view);

// 再生を開始するか、プレビューを停止します。
protected void playPasterEffect() {
        TextureView pv = new TextureView(mPasterView.getContext());
        animPlayerView = mController.createPasterPlayer(pv);
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT);
        ViewGroup vg = (ViewGroup) mPasterView.getContentView();
        vg.addView(pv, 0, lp);

    }

    
    protected void stopPasterEffect() {
        ViewGroup vg = (ViewGroup) mPasterView.getContentView();
        vg.removeViewAt(0);
        animPlayerView = null;
    }

アニメーション ステッカーを削除する

pasterController.removePaster();

ドラフトボックス

コードで使用されているパラメーターの詳細については、「関連クラス」をご参照ください。

プロジェクト構成を取得する

// エディターを初期化します。
AliyunIEditor.init(SurfaceView surfaceView, Context context);
// プロジェクト構成を取得します。
AliyunEditorProject project = AliyunIEditor.getEditorProject();

ドラフトマネージャーを初期化する

AliyunDraftManager draftManager = AliyunDraftManager.getInstance(context);

ドラフトリストを取得する

// ドラフトリストを非同期で取得します。
AliyunDraftManager.getInstance(getContext())
                          .getDraftListByAsync(new AliyunDraftListCallback() {
                              @Override
                              public void onFailure(final String msg) {
                                  // ドラフトリストの取得に失敗しました。
                              }

                              @Override
                              public void onSuccess(final List<AliyunDraft> draftList) {
                                  // ドラフトリストの取得に成功しました。
                              }
                          });

ドラフト ID に基づいてドラフトを削除する

// ドラフトを削除します。ドラフトはドラフトリスト内のアイテムです。関連メソッドを呼び出すことで、ドラフトリストを取得できます。
AliyunDraftManager.getInstance(v.getContext()).deleteDraft(draft.getId());

ドラフトの名前を変更する

// ドラフトの名前を変更します。ドラフトはドラフトリスト内のアイテムです。関連メソッドを呼び出すことで、ドラフトリストを取得できます。
AliyunDraftManager.getInstance(v.getContext()).rename(draft.getId(), newName);

ドラフトをコピーする

// ドラフトをコピーした後、新しいドラフトが生成されます。ドラフトはドラフトリスト内のアイテムです。関連メソッドを呼び出すことで、ドラフトリストを取得できます。
AliyunDraft newDraft = AliyunDraftManager.getInstance(v.getContext()).copy(draft.getId());

ドラフトを読み込む

// ドラフトはドラフトリスト内のアイテムです。関連メソッドを呼び出すことで、ドラフトリストを取得できます。
AliyunDraftManager.getInstance(v.getContext()).preLoadDraft(draft, new AliyunDraftResourceLoader() {

                @Override
                public void onHandleResourceTasks(final List<AliyunDraftResTask> tasks) {
                    // 関連リソースがないため、処理するリソースタスクが返されます。タスクを修復、無視、または削除できます。
                    HashMap<String, List<AliyunDraftResTask>> map = new HashMap<>();
                    for (AliyunDraftResTask task : tasks) {
                        if (task.getSource() != null && !StringUtils.isEmpty(task.getSource().getURL())) {
                            if (map.containsKey(task.getSource().getURL())) {
                                map.get(task.getSource().getURL()).add(task);
                            } else {
                                List<AliyunDraftResTask> list = new ArrayList<>();
                                list.add(task);
                                map.put(task.getSource().getURL(), list);
                            }
                        } else {
                            // タスクを修復、無視、または削除できます。
                            if (task.getResModuleType() == AliyunResModuleType.MAIN_VIDEO) {
                                task.getSource().setPath(EditorCommon.SD_DIR + "svideo_res/image/aliyun_svideo_failed.jpg");
                                task.onHandleCallback(task.getSource());
                            } else if(task.getResModuleType() == AliyunResModuleType.TRANSITION) {
                                // タスクを削除します。
                                task.onRemove();
                            } else {
                                // タスクを無視します。
                                task.onIgnore();
                            }
                        }
                        for (final Map.Entry<String, List<AliyunDraftResTask>> entry : map.entrySet()) {
                            // Key の値はリソースの URL です。 Value の値は、リソースの URL を使用して処理するタスクです。
                            final List<AliyunDraftResTask> list = entry.getValue();
                            try {
                                final String url = entry.getKey();
                                // リソースがプラットフォームリソースかどうかを確認します。
                                if (url.startsWith(AlivcResUtil.SCHEME)) {
                                    // プラットフォームリソースを読み込むための コールバック。
                                    AlivcResUtil.LoadCallback callback = new AlivcResUtil.LoadCallback() {
                                        @Override
                                        public void onSuccess(String path) {
                                            for (AliyunDraftResTask task : list) {
                                                Source source = task.getSource();
                                                source.setPath(path);
                                                task.onHandleCallback(source);
                                            }
                                        }

                                        @Override
                                        public void onFailure(String type, String msg) {
                                            Log.d("CloudDraft", "loadRes>Failure>type>" + type + ">msg>" + msg);
                                            for (AliyunDraftResTask task : list) {
                                                task.onIgnore();
                                            }
                                        }
                                    };
                                    // プラットフォームリソースを読み込みます。完全なサンプルコードについては、デモをご参照ください。
                                    AlivcResUtil.loadRes(context, url, callback);
                                } else {
                                    // ユーザーリソースをダウンロードします。完全なサンプルコードについては、デモをご参照ください。
                                    downloadRes(url, new File(item.getEditorProjectUri()).getParent(), list);
                                }
                            } catch (Exception e) {
                                // エラーが発生しました。
                                for (AliyunDraftResTask item : list) {
                                    item.onIgnore();
                                }
                            }
                        }
                    }
                }

                @Override
                public void onFailure(final String msg) {
                    // プリロードに失敗しました。
                    Toast.makeText(v.getContext(), "プリロードに失敗しました", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onSuccess() {
                    // プリロードが完了したら、編集ページに移動できます。ドラフトはドラフトリスト内のアイテムです。関連 API 操作を呼び出すことで、ドラフトリストを取得できます。 draft.getEditorProjectUri() を使用してドラフトを読み込むことができます。
                    EditorActivity.startEdit(v.getContext(), draft);
                }
            });

ドラフトをアップロードする

ドラフトをアップロードするには、ドラフトサーバーを使用します。サンプルコードをクリックして、サーバーのサンプルコードをダウンロードします。

// ドラフトはドラフトリスト内のアイテムです。関連メソッドを呼び出すことで、ドラフトリストを取得できます。
AliyunDraftManager.getInstance(context)
                          .uploadDraft(draft, new AliyunDraftResourceUploader() {
                              @Override
                              public void onHandleResourceTasks(final List<AliyunDraftResTask> tasks) {
                                  // 処理する必要があるリソースアップロードタスク。
                                  HashMap<String, List<AliyunDraftResTask>> map = new HashMap<>();
                                  // 重複するリソースをフィルターします。
                                  for (AliyunDraftResTask task : tasks) {
                                      if (task.getSource() == null) {
                                          task.onIgnore();
                                          continue;
                                      }
                                      // URL が空であるか、URL が alivc_resource で始まっていない場合は、URL を処理する必要があります。
                                      String url = task.getSource().getURL();
                                      if (StringUtils.isEmpty(url) || !url.startsWith("alivc_resource")) {
                                          if (map.containsKey(task.getSource().getPath())) {
                                              map.get(task.getSource().getPath()).add(task);
                                          } else {
                                              List<AliyunDraftResTask> list = new ArrayList<>();
                                              list.add(task);
                                              map.put(task.getSource().getPath(), list);
                                          }
                                      } else {
                                          // エラーを無視します。
                                          task.onIgnore();
                                      }
                                  }
                                  for (Map.Entry<String, List<AliyunDraftResTask>> entry : map.entrySet()) {
                                      try {
                                          for (AliyunDraftResTask task : tasks) {
                                              Source source = task.getSource();
                                              // アップロード完了後の コールバック URL を構成します。
                                              source.setURL();
                                              task.onHandleCallback(source);
                                          }
                                      } catch (Exception e) {
                                          // エラーを無視します。
                                          List<AliyunDraftResTask> list = entry.getValue();
                                          for (AliyunDraftResTask item:list){
                                              item.onIgnore();
                                          }
                                      }
                                  }
                              }

                              @Override
                              public void onSuccess(final String projectPath, String coverUrl) {
                                  // すべてのリソースがアップロードされると、プロジェクト構成の URL とサムネイルの URL が返されます。
                                  // リソースをクラウドにアップロードできます。他のユーザーは、プロジェクト構成の URL を使用してドラフトを編集状態に復元できます。
                              }

                              @Override
                              public void onFailure(final String msg) {
                                  Toast.makeText(context,"バックアップに失敗しました",Toast.LENGTH_SHORT).show();
                              }
                          });

ドラフトをダウンロードする

ドラフトをダウンロードするには、ドラフトサーバーを使用します。サンプルコードをクリックして、サーバーのサンプルコードをダウンロードします。

// ドラフトのプロジェクト構成に基づいて、ドラフト関連リソースをダウンロードします。 file は、ドラフトをバックアップした後にサーバーからダウンロードできるプロジェクト構成ファイルです。
AliyunDraftManager.getInstance(context).downloadDraft(file, new AliyunDraftResourceDownloader() {
            @Override
            public void onHandleResourceTasks(final String projectDir, final List<AliyunDraftResTask> tasks) {
                // 処理する必要があるドラフトリソースタスク。ドラフト内のリソースをダウンロードする必要があります。
                HashMap<String, List<AliyunDraftResTask>> map = new HashMap<>();
                // 重複するリソースをフィルターします。
                for (AliyunDraftResTask task : tasks) {
                    if (task.getSource() == null || StringUtils.isEmpty(task.getSource().getURL())) {
                        task.onIgnore();
                    } else if (map.containsKey(task.getSource().getURL())) {
                        map.get(task.getSource().getURL()).add(task);
                    } else {
                        List<AliyunDraftResTask> list = new ArrayList<>();
                        list.add(task);
                        map.put(task.getSource().getURL(), list);
                    }
                }
                for (final Map.Entry<String, List<AliyunDraftResTask>> entry : map.entrySet()) {
                    final List<AliyunDraftResTask> list = entry.getValue();
                    try {
                        final String url = entry.getKey();
                        // URL を使用してドラフトリソースをダウンロードします。
                        for (AliyunDraftResTask task : list) {
                            Source source = task.getSource();
                            // ダウンロード完了後にリソースのローカル URL を指定します。
                            source.setPath(path);
                            // リソースが MV の場合は、ID を取得し、MV を表示するために ID を Source の値として指定します。
                            if (task.getResModuleType() == AliyunResModuleType.MV) {
                                try {
                                    source.setId(Uri.parse(url).getQueryParameter("gid"));
                                }catch (Exception ignored){
                                }
                            }
                            task.onHandleCallback(source);
                        }
                    } catch (Exception e) {
                        // エラーが発生しました。
                        for (AliyunDraftResTask item : list) {
                            item.onIgnore();
                        }
                    }
                }

            }

            @Override
            public void onSuccess(final AliyunDraft draft) {
                // すべてのリソースをダウンロードした後、サーバーの ProjectID パラメーターを構成します。 ProjectID を使用して、ローカルドラフトをクラウドドラフトに関連付けることができます。
                AliyunDraftManager.getInstance(context).setProjectId(draft.getId(), projectId);
                Toast.makeText(context,"ドラフトはローカル PC に復元されました",Toast.LENGTH_SHORT).show();
                // ドラフトをローカル PC に復元した後、ローカルドラフトリストでドラフトを表示できます。
            }

            @Override
            public void onFailure(final String msg) {
                Toast.makeText(context,"ドラフトをローカル PC に復元できませんでした",Toast.LENGTH_SHORT).show();
            }
        });

その他の設定

コードで使用されているパラメーターの詳細については、「関連クラス」をご参照ください。

タイムエフェクト

// 1. 速度ランプを構成します。
// SDK V3.7.0 以降を使用すると、このメソッドを呼び出して、複数のビデオまたは画像の再生速度を調整できます。
int effectId;
effectId = AliyunIEditor.rate(float rate, long startTime, long duration, boolean needOriginDuration);

// 2. 繰り返し設定を構成します。
effectId = AliyunIEditor.repeat(int times, long startTime, long duration, boolean needOriginDuration);

//3. 逆再生を構成します。
// 注: 逆再生を実行する前に、グループオブピクチャ (GOP) サイズが 5 より大きいビデオをトランスコードします。 NativeParser.getMaxGopSize() メソッドを呼び出して、ビデオの GOP サイズを表示できます。トランスコード中に、CropParam.setGop(1) メソッドを呼び出して GOP サイズを 1 に設定します。
effectId = AliyunIEditor.invert();


// タイムエフェクトを削除します。
AliyunIEditor.deleteTimeEffect(effectId);

ウォーターマーク

ウォーターマークには、一般的なウォーターマークと終了ウォーターマークがあります。一般的なウォーターマークは、ビデオストリームの全期間にわたって表示されます。終了ウォーターマークは、ビデオストリームの最後に表示されます。

// ウォーターマークのサンプル。 sizeX と sizeY は、表示領域の幅に対するウォーターマークの幅の比率と、表示領域の高さに対するウォーターマークの高さの比率を指定します。比率に注意してください。そうしないと、ウォーターマークが不完全に表示される場合があります。
// posX と posY は、表示領域におけるウォーターマークの中心の座標を指定します。たとえば、0,0 は左上隅を示し、1,1 は右下隅を示します。

// 一般的なウォーターマークを構成します。
AliyunIEditor.applyWaterMark(String imgPath, float sizeX, float sizeY, float posX, float posY);

// 終了ウォーターマークを構成します。
AliyunIEditor.addTailWaterMark(String imagePath, float sizeX, float sizeY, float posX, float posY, long durationUs);

落書き

ショートビデオ SDK は、キャンバスとペイントブラシの構成操作を含む、一連の落書き操作を提供します。 AliyunICanvasController を使用して、落書き構成を管理できます。

  • キャンバス: 落書き用に提供される UI インタラクションビュー。 UI インタラクションビューを UI インタラクションビューグループに追加できます。

  • ペイントブラシ: android.graphics.Paint オブジェクト。カスタムペイントブラシを構成するか、デフォルトのペイントブラシを使用できます。

// 落書きコントローラーを取得します。
int width = 600;
int height = 800
AliyunICanvasController controller = AliyunIEditor.obtainCanvasController( context, width, height);


// 落書きキャンバスを取得します。
View canvasView = controller.getCanvas();

// 落書きを適用します。
controller.applyPaintCanvas();

// リソースを解放します。
controller.release();

//*******
// その他の操作を実行します。
//*******

// 前のストロークを元に戻します。
controller.undo();

// キャンバスをクリアします。
controller.clear();

// 落書きを削除します。

controller.removeCanvas();

// キャンバスに落書きが存在するかどうかを確認します。
controller.hasCanvasPath();