短視頻SDK提供視頻編輯與導出功能,支持視頻圖片素材混合導入、提供濾鏡、配音、時間特效等豐富的編輯效果。
版本支持
版本 | 是否支持 |
專業版 | 支持所有功能。 |
標準版 | 部分支持,支持除了字幕、動態貼紙、MV以外的其他功能。 |
基礎版 | 不支持。 |
相關類功能
操作 | 類名 | 功能 |
初始化 | 視頻編輯核心類。 | |
工廠類。 | ||
視頻管理 | 視頻源管理器。 | |
圖片片段。 | ||
視頻片段。 | ||
設置視頻特效 | 濾鏡及MV的Model。 | |
動效濾鏡Model。 | ||
轉場Model。 | ||
設置畫中畫 | 畫中畫管理類,負責畫中畫的增刪改查。 | |
畫中畫控制器,設置畫中畫的開始時間,結束時間。 | ||
軌道信息獲取。 | ||
布局控制器,對畫中畫移動、縮放、旋轉、透明度等設置。 | ||
動畫控制器,可以對畫中畫做幀動畫。 | ||
聲音控制器,控制畫中畫音量,降噪、音效、淡入淡出等。 | ||
畫面調節控制器,可以調節飽和度、亮度、對比度等。 | ||
設置字幕及動態貼紙 | 字幕及動態貼紙管理器。 | |
字幕控制器。 | ||
動態貼紙控制器。 | ||
草稿箱 | 工程配置。 | |
草稿管理。 | ||
草稿。 | ||
資源加載器。 | ||
資源上傳器。 | ||
資源下載器。 | ||
草稿資源處理任務。 |
編輯視頻流程
階段 | 流程 | 說明 | 示例代碼 |
基礎 | 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();