Video editor library for android, implemented with android media framework and opengl es 2.0.
The aim of this library is:
- tiny size(no ffmpeg, 103KB for now)
- simple api
- powerful feature
This library is still under development, apis will be changed.
Any suggestion is welcome, you can raise issues or pull requests, thx.
// init with context, you can do this in application or activity. VideoEditorManager.getManager().init(context);
// EditStageListener use to listener every stage progresss. private EditStageListener mStageListener = new EditStageListener() { @Override public void onStart(String action) { super.onStart(action); Log.d(TAG, "EditStageListener, onStart: " + action); mActionView.setText(action + ": started"); } @Override public void onProgress(String action, float progress) { super.onProgress(action, progress); Log.d(TAG, "EditStageListener, onProgress: " + action + ", progress: " + progress); mActionView.setText(action + ": progress"); mProgressView.setText(String.format("%.2f%%", progress * 100)); } @Override public void onSucceeded(String action) { super.onSucceeded(action); Log.d(TAG, "EditStageListener, onSucceeded: " + action); mActionView.setText(action + ": succeed"); if (Constants.ACTION_MERGE_VIDEOS.equals(action)) { mToken = -1; } } @Override public void onFailed(String action) { super.onFailed(action); Log.d(TAG, "EditStageListener, onFailed: " + action); mActionView.setText(action + ": failed"); } }; // EditListener use to listen overall progress. private EditListener mEditListener = new EditListener() { @Override public void onStart(long token) { super.onStart(token); Log.d(TAG, "EditListener, onStart token: " + token); } @Override public void onProgress(long token, float progress) { super.onProgress(token, progress); Log.d(TAG, "EditListener, onProgress: " + progress + ", token: " + token); } @Override public void onSucceeded(long token, File outputFile) { super.onSucceeded(token, outputFile); Log.d(TAG, "EditListener, onSucceeded token: " + token + ", output: " + outputFile); mToken = -1; } @Override public void onFailed(long token) { super.onFailed(token); Log.d(TAG, "EditListener, onFailed token: " + token); mToken = -1; } };
// video water mark config WaterMarkFilter waterMarkFilter = new WaterMarkFilter.Builder() .watermark(BitmapFactory.decodeResource(getResources(), R.drawable.watermark)) .position(100, 200) .scaleFactor(1f) .startFrom(5 * 1000) .duration(5 * 1000) .build(); // video filter config. VideoFrameLookupFilter lookupFilter = new VideoFrameLookupFilter.Builder() .curve(BitmapFactory.decodeResource(getResources(), R.drawable.filter9)) .strength(1f) .startFrom(5 * 1000) .duration(5 * 1000) .build(); // filter action with water mark and filter config. VideoFilterAddAction filterAddAction = new VideoFilterAddAction.Builder() .watermarkFilter(waterMarkFilter) .frameFilter(lookupFilter) .build(); // bgm add action VideoBgmAddAction bgmAddAction = new VideoBgmAddAction.Builder() .bgmFile(new File(Environment.getExternalStorageDirectory(), "videoeditor/music.mp3")) .videoFrom(5 * 1000) .videoDuration(7 * 1000) .override(true) .bgmFrom(5 * 1000) .build(); // bgm remove action VideoBgmRemoveAction bgmRemoveAction = new VideoBgmRemoveAction.Builder() .from(3 * 1000) .duration(8 * 1000) .build(); // cut action VideoCutAction cutAction = new VideoCutAction.Builder() .from(5 * 1000) .duration(10 * 1000) .build(); // merge action VideoMergeAction mergeAction = new VideoMergeAction.Builder() .merge(new File(Environment.getExternalStorageDirectory(), "videoeditor/input.mp4")) // put input file here. .inputHere() .merge(new File(Environment.getExternalStorageDirectory(), "videoeditor/input2.mp4")) .merge(new File(Environment.getExternalStorageDirectory(), "videoeditor/input3.mp4")) .merge(new File(Environment.getExternalStorageDirectory(), "videoeditor/input4.mp4")) .build(); // start it! token is the unique id of this task. mToken = VideoEditorManager.getManager() // give the input file. .edit(new File(Environment.getExternalStorageDirectory(), "videoeditor/input.mp4")) // all actions here will be executed in define order. .withAction(cutAction) .withAction(bgmAddAction) .withAction(filterAddAction) .withAction(bgmRemoveAction) .withAction(mergeAction) // give the output file. .saveAs(new File(Environment.getExternalStorageDirectory(), "videoeditor/output.mp4")) // commit action list, and actions will be executed right now. .commit(mEditListener, mStageListener);
// cancel task with token. VideoEditorManager.cancel(mToken);