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

編輯視頻

短視頻SDK提供視頻編輯與導出功能,支持視頻圖片素材混合導入、提供濾鏡、配音、時間特效等豐富的編輯效果。

版本支持

版本

是否支持

專業版

支持所有功能。

標準版

部分支持,支持除了字幕、動態貼紙、MV以外的其他功能。

基礎版

不支持。

相關類功能

操作

類名

功能

初始化

AliyunIEditor

視頻編輯核心類。

AliyunEditorFactory

工廠類。

視頻管理

AliyunIClipConstructor

視頻源管理器。

AliyunImageClip

圖片片段。

AliyunVideoClip

視頻片段。

設置視頻特效

EffectBean

濾鏡及MV的Model。

EffectFilter

動效濾鏡Model。

TransitionBase

轉場Model。

設置畫中畫

AliyunIPipManager

畫中畫管理類,負責畫中畫的增刪改查。

AliyunIPipController

畫中畫控制器,設置畫中畫的開始時間,結束時間。

AliyunIPipTrack

軌道信息獲取。

AliyunILayoutController

布局控制器,對畫中畫移動、縮放、旋轉、透明度等設置。

AliyunIAnimationController

動畫控制器,可以對畫中畫做幀動畫。

AliyunIAudioController

聲音控制器,控制畫中畫音量,降噪、音效、淡入淡出等。

AliyunIAugmentationController

畫面調節控制器,可以調節飽和度、亮度、對比度等。

設置字幕及動態貼紙

AliyunPasterManager

字幕及動態貼紙管理器。

AliyunPasterControllerCompoundCaption

字幕控制器。

AliyunPasterController

動態貼紙控制器。

草稿箱

AliyunEditorProject

工程配置。

AliyunDraftManager

草稿管理。

AliyunDraft

草稿。

AliyunDraftResourceLoader

資源加載器。

AliyunDraftResourceUploader

資源上傳器。

AliyunDraftResourceDownloader

資源下載器。

AliyunDraftResTask

草稿資源處理任務。

編輯視頻流程

階段

流程

說明

示例代碼

基礎

1

創建并初始化編輯器。

初始化

2

在編輯過程中動態裁剪視頻、動態更換視頻源、動態調整視頻轉場時間及轉場效果。編輯核心類是AliyunIEditor類。

視頻管理

3

設置編輯器的預覽播放。

預覽控制

進階

4

設置濾鏡、轉場及MV特效。

設置視頻特效

5

設置背景音樂、配音及音效。

設置音樂及音效

6

設置畫中畫。

設置畫中畫

7

設置字幕、花字、文字氣泡及動態貼紙。

設置字幕及動態貼紙

8

支持編輯草稿箱中的視頻、或將編輯完成的視頻保存至草稿箱。

草稿箱

9

設置時間特效、水印及涂鴉。

其他設置

初始化

創建并初始化編輯器。代碼中需要使用的參數詳情,請參考接口文檔。接口鏈接請參見相關類功能。

//1. 實例化
//configPath為導入視頻的地址,為草稿箱地址或者AliyunIImport.generateProjectConfigure()重新生成后的地址
Uri uri = Uri.parse(configPath); 

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

//2. 初始化
//初始化并設置預覽窗口
editor.init(surfaceView, context);


//3. 銷毀,當不再使用時需要調用銷毀接口
editor.onDestroy()

視頻管理

視頻編輯器里的視頻或圖片最終由視頻源管理器AliyunIClipConstructor統一管理,通過AliyunIClipConstructor修改編輯器里的視頻或圖片后,需要手動調用AliyunIEditor.applySourceChange()應用更新的視頻或圖片。

代碼中需要使用的參數詳情,請參考接口文檔。接口鏈接請參見相關類功能。

視頻源管理操作

//1.獲取視頻源管理器
AliyunIClipConstructor contructor = AliyunIEditor.getSourcePartManager();


//[可選] 2.添加視頻或圖片

//在時間軸最后添加視頻或圖片,其中視頻用AliyunVideoClip,圖片用AliyunImageClipAliyunImageClip
contructor.addMediaClip(AliyunClip clip);

//在指定位置的添加視頻或圖片,其中視頻用AliyunVideoClip,圖片用AliyunImageClipAliyunImageClip
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濾鏡:使用Lookup Table方式進行像素替換。

    • 靜態濾鏡:通過編寫著色語言方式進行像素計算,不支持帶動畫效果。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為轉場位置,從0開始記,取消轉場的話,transition傳null即可
AliyunEditor.setTransition(int index, TransitionBase transition); 

//設置批量轉場,取消轉場的話,transition傳null即可
AliyunEditor.setTransition(Map<Integer, TransitionBase> transitions); //設置多個轉場


//2.更新轉場
//從某個轉場更新成另一個轉場,transition不允許為null
AliyunEditor.updateTransition(int index, TransitionBase transition); 

MV

支持自定義MV,MV的制作規范請參見MV

//添加MV
AliyunIEditor.applyMV(EffectBean effect);

//刪除MV
AliyunIEditor.applyMV(null);

設置音樂及音效

音樂

音樂分為背景音樂和配音。背景音樂不受時間特效影響(變速、重復、倒放等),而配音會受到時間特效的影響。代碼中需要使用的參數詳情,請參考接口文檔。接口鏈接請參見相關類功能

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

                    
//切換音樂seek到0清音樂緩存,避免響一聲
musicBean.setStartTime(startTime);
musicBean.setDuration(Integer.MAX_VALUE);//設置為最大時長
musicBean.setStreamStartTime(streamStartTime);
musicBean.setStreamDuration(streamDuration);

int audioSteamId;
//1.添加背景音樂/配音
audioSteamId = AliyunIEditor.applyMusic(musicBean);//音樂
AliyunIEditor.applyDub(EffectBean effect);//配音

//2.刪除背景音樂/配音
AliyunIEditor.removeMusic(EffectBean effect);//音樂
AliyunIEditor.removeDub(EffectBean effect);//配音

//3.調整背景音樂/配音與原音的比重
AliyunIEditor.applyMusicMixWeight(int audioSteamId, int weight);

//4.調整指定音頻流音量
//背景音樂、配音、原音,詳細請查看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);

設置畫中畫

畫中畫功能允許在現有主軌道的基礎上,添加一個或者多個畫中畫。

  • 主軌道:編輯頁面默認軌道,有且僅有一個主軌道,一個主軌道可以有多個視頻流。

  • 畫中畫:允許添加多個畫中畫,畫中畫允許設置位置,縮放,旋轉等。創建畫中畫默認創建一個畫中畫軌道。畫中畫可以在不同畫中畫軌道中移動。

說明

短視頻SDK對畫中畫的個數未做限制,但建議同一時刻畫面中最好不要超過3個畫中畫,具體限制個數由業務方自己做決定。

代碼中需要使用的參數詳情,請參考接口文檔。接口鏈接請參見相關類功能。

//從編輯主接口獲取畫中畫管理類
AliyunIPipManager pipManager = mAliyunIEditor.getPipManager();

//增加畫中畫
mAliyunIEditor.puase(); //先暫停
long current = mAliyunIEditor.getCurrentPlayPosition(); //獲取當前的播放時間點
AliyunIPipManager pipManager = mAliyunIEditor.getPipManager();
AliyunIPipController pipController = pipManager.createNewPip("流文件地址");
pipController.setTimelineStartTime(current) //從軌道當前時間點開始
                .setClipStartTime(0) //畫中畫視頻本身開始時間
                .apply();  //應用生效


//刪除畫中畫
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();

//獲取畫中畫畫布中的位置
RectF rectf = pipController.getPipRectFInCurrentScreen(); //獲得畫中畫所在的矩形區域
int width = mSurfaceView.getWidth() * rectf.width();  //畫中畫在畫布中的實際寬度
int height = mSurfaceView.getWidth() * rectf.height();  //畫中畫在畫布中的實際高度


//修改聲音相關:AliyunIAudioController
mAliyunIEditor.puase(); //先暫停
AliyunIAudioController audioController = pipController.getAudioController(); //獲取聲音控制器
audioController.setVolume(100) //設置音量最大
                .setAudioEffect(AudioEffectType.EFFECT_TYPE_LOLITA)  //設置聲音特效為蘿莉音
                .apply();  //應用


//設置畫中畫幀動畫:AliyunIAnimationController
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~1) //設置暗角
                        .setSharpness(0~1)  //設置銳化程度
                        .setSaturation(0~1)  //設置保護度
                        .apply();  //應用

//獲取軌道信息:AliyunIPipTrack
//方式一: 從管理類獲取所有軌道
AliyunIPipManager pipManager = mAliyunIEditor.getPipManager();
List<AliyunIPipTrack> pipTrackList = pipManager.getPipTracks(); //獲取所有畫中畫軌道

//方式二: 獲取當前控制器所在軌道
AliyunIPipTrack pipTrack = pipController.getOwnerTrack();
List<AliyunIPipController> pipControllers = pipTrack.getPipClips(); //獲取當前軌道下所有畫中畫片段控制器

設置字幕及動態貼紙

字幕及動態貼紙統一通過AliyunPasterManager進行管理,通過AliyunPasterManager獲取到對應的AliyunIPasterController進行相應的操作。代碼中需要使用的參數詳情,請參考接口文檔。接口鏈接請參見相關類功能。

基于字幕,短視頻SDK還提供了花字及氣泡文字的特效?;ㄗ帧馀菸淖旨皠討B貼紙的制作請參見花字動圖

字幕

添加/刪除字幕

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

//1. 添加字幕
AliyunPasterControllerCompoundCaption captionController = pasterManager.addCaptionWithStartTime('輸入文字', null, fontSouce, startTime,duration);

//2. 刪除字幕
controller.remove()

更新字幕屬性

AliyunPasterControllerCompoundCaption包含了字幕的所有操作,詳細請查看接口說明。每次更新完字幕屬性后,必須調用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去展示的動畫效果,因此設置貼紙的屬性需要在Android實現UI(AliyunPasterBaseView),定義動態貼紙的大小、寬高、旋轉角度等屬性。由于是在平臺層也同時實現了AliyunPasterBaseView,因此,提供了從渲染層展示、隱藏動態貼紙的操作,避免兩者重疊。

//必須調用
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刪除草稿

//刪除草稿,draft為草稿列表單個item(草稿列表通過草稿列表接口獲取)
AliyunDraftManager.getInstance(v.getContext()).deleteDraft(draft.getId());

草稿重命名

//重命名,draft為草稿列表單個item(草稿列表通過草稿列表接口獲取)
AliyunDraftManager.getInstance(v.getContext()).rename(draft.getId(), newName);

草稿復制

//復制后會返回新草稿,draft為草稿列表單個item(草稿列表通過草稿列表接口獲取)
AliyunDraft newDraft = AliyunDraftManager.getInstance(v.getContext()).copy(draft.getId());

草稿加載

//draft為草稿列表單個item(草稿列表通過草稿列表接口獲取)
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為資源地址,Value為對應資源地址需要處理的任務
                            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();
                                            }
                                        }
                                    };
                                    //加載平臺資源,具體代碼看demo
                                    AlivcResUtil.loadRes(context, url, callback);
                                } else {
                                    //下載用戶資源,具體代碼看demo
                                    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() {
                    //預加載處理成功即可進入編輯界面,draft為草稿列表單個item(草稿列表通過草稿列表接口獲取),通過draft.getEditorProjectUri()來加載草稿
                    EditorActivity.startEdit(v.getContext(), draft);
                }
            });

上傳草稿

上傳草稿需配合草稿服務端,服務端簡單代碼示例下載。

//draft為草稿列表單個item(草稿列表通過草稿列表接口獲取)
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為空或者不以alivc_resource開頭需要做上傳處理
                                      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();
                                              //上傳成功后回調遠程地址
                                              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) {
                                  //資源全部上傳成功后,返回工程配置地址和封面地址
                                  //可自行處理上傳到云端,其他用戶就可以通過工程配置地址恢復草稿到編輯狀態
                              }

                              @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();
                            //下載完成后回調資源本地地址
                            source.setPath(path);
                            //如果是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到本地草稿用來關聯云端草稿
                AliyunDraftManager.getInstance(context).setProjectId(draft.getId(), projectId);
                Toast.makeText(context,"成功恢復到本地",Toast.LENGTH_SHORT).show();
                //恢復成功后就可以在本地草稿列表查看
            }

            @Override
            public void onFailure(final String msg) {
                Toast.makeText(context,"恢復到本地失敗",Toast.LENGTH_SHORT).show();
            }
        });

其他設置

代碼中需要使用的參數詳情,請參考接口文檔。接口鏈接請參見相關類功能

時間特效

// 1.變速
//3.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的視頻需要先轉碼,否則將無法倒播。對于視頻GOP的檢查可以用NativeParser.getMaxGopSize()來獲取。轉碼時將GOP SIZE設置為1,即CropParam.setGop(1);
effectId = AliyunIEditor.invert();


// 刪除時間特效
AliyunIEditor.deleteTimeEffect(effectId);

水印

水印分為普通水印及片尾水印。普通水印會貫穿整個視頻流時長,而片尾水印會在視頻流結尾處添加水印。

//水印例子 水印的大小為 :水印圖片的寬高和顯示區域的寬高比,注意保持圖片的比例,不然顯示不完全
//水印的位置為 :以水印圖片中心點為基準,顯示區域寬高的比例為偏移量,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交互View,可以添加到UI交互的ViewGroup。

  • 畫筆:一個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();