廢話少說接着上一篇的接着介紹:
布局檔案:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#ffffff"
>
<RelativeLayout
android:id="@+id/rl_top"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_above="@+id/tv_progress_time"
android:background="#2a3552" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>
<VideoView
android:id="@+id/vv_vedio_show"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
<ImageView
android:id="@+id/iv_edit_back"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="17dp"
android:layout_marginTop="20dp"
android:src="@drawable/ic_vedio_back" />
<ImageView
android:id="@+id/iv_play_pause"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:layout_marginBottom="27dp"
android:layout_marginTop="87dp"
android:src="@drawable/play_btn_state" />
<com.tian.videomergedemo.view.VideoEditProgressBar
android:id="@+id/vedio_progress"
android:layout_width="match_parent"
android:layout_height="27dp"
android:layout_alignParentBottom="true"
android:background="@color/transparent" />
<TextView
android:id="@+id/tv_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/vedio_progress"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:text="00:00:00"
android:textColor="#b6c5dc"
android:textSize="10sp" />
</RelativeLayout>
<TextView
android:id="@+id/tv_progress_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/sl"
android:layout_centerHorizontal="true"
android:layout_marginBottom="2dp"
android:text="00:00:00"
android:gravity="center"
android:textColor="#2a3552"
android:textSize="10sp" />
<com.tian.videomergedemo.view.ObservableScrollView
android:id="@+id/sl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/rl_bottom"
android:scrollbars="none"
>
<LinearLayout
android:id="@+id/ll_scroll"
android:layout_width="match_parent"
android:layout_height="110dp"
android:orientation="horizontal"
android:gravity="center_vertical|center_horizontal"
>
<com.tian.videomergedemo.view.EditVideoImageBar
android:id="@+id/iv_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
</com.tian.videomergedemo.view.ObservableScrollView>
<RelativeLayout
android:id="@+id/rl_bottom"
android:layout_width="match_parent"
android:background="#ffffff"
android:layout_alignParentBottom="true"
android:layout_height="100dp" >
<ImageView
android:id="@+id/iv_btn_cut"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="25dp"
android:src="@drawable/video_cut" />
<ImageView
android:id="@+id/iv_delete"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="35dp"
android:layout_marginRight="50dp"
android:layout_toLeftOf="@id/iv_btn_cut"
android:src="@drawable/video_delete" />
<ImageView
android:id="@+id/iv_merge"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:layout_marginBottom="35dp"
android:layout_marginLeft="50dp"
android:layout_toRightOf="@id/iv_btn_cut"
android:src="@drawable/video_merge" />
</RelativeLayout>
<View
android:layout_width="1dp"
android:layout_below="@+id/tv_progress_time"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_marginBottom="85dp"
android:background="#f1404b" />
</RelativeLayout>
效果圖如下:
編輯代碼:
package com.tian.videomergedemo;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
import com.tian.videomergedemo.bean.AttachsBeen;
import com.tian.videomergedemo.bean.ComposeInfo;
import com.tian.videomergedemo.bean.RecordDetail;
import com.tian.videomergedemo.dao.DatabaseContext;
import com.tian.videomergedemo.dao.RecordDao;
import com.tian.videomergedemo.inter.CompletionListener;
import com.tian.videomergedemo.inter.ScrollViewListener;
import com.tian.videomergedemo.manager.FfmpegManager;
import com.tian.videomergedemo.manager.VideoStitchingRequest;
import com.tian.videomergedemo.utils.BitmapUtils;
import com.tian.videomergedemo.utils.TimeFormatUtils;
import com.tian.videomergedemo.view.EditVideoImageBar;
import com.tian.videomergedemo.view.ObservableScrollView;
import com.tian.videomergedemo.view.VideoEditProgressBar;
/**
*
* 視訊的編輯界面
*
* @author TCX
*
*/
@SuppressLint("NewApi") public class EditVedioActivity extends Activity implements OnClickListener, ScrollViewListener {
private int screenWidth;
private int screenHeight;
private String mVedioPath;
private ComposeInfo info;
private RecordDao dao;
private AttachsBeen bean;
private VideoView mVideoView;
private VideoEditProgressBar mVedioBar;
private ImageView mPlayerController;
private TextView mVideoDuration;
private ImageView mCutter;
private ImageView mDelete;
private ImageView mmerge;
private ArrayList<Integer> keyFrameList;
private EditVideoImageBar mImageLists;
protected int mDuration=;
private int mBottomLength=;
private int mDragPosition=;//手勢拖動的距離
private boolean isPlaying=false;
private Handler mHandler=new Handler(){
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
switch (msg.what) {
case ://拖動更新
if(!mVideoView.isPlaying()&&!isPlaying){
//非播放狀态
mVideoView.seekTo(mDragPosition);
}else{
//播放狀态
int mDragPosition1 = mVideoView.getCurrentPosition();
int currentPosition=;
if(mDuration!=){
currentPosition=mBottomLength*mDragPosition1/mDuration;
}else{
if(currentPosition<=){
currentPosition=mDragPosition1;
}
}
mScrollView.scrollTo(currentPosition==?:currentPosition, );
mCurrentPosition=currentPosition;
mHandler.sendEmptyMessageDelayed(, );
}
int currentPosition = mVideoView.getCurrentPosition();
mVideoEditProgressBar.setProgress((currentPosition*f/mDuration));
break;
case ://視訊播放或者暫停action
break;
case :
mVideoView.pause();
break;
case :
mererVideo();
break;
case :
reRreshUI();
break;
default:
break;
}
}
};
/**
* Scroller的滑動監聽
* @param scrollView
* @param x
* @param y
* @param oldx
* @param oldy
*/
@Override
public void onScrollChanged(ObservableScrollView scrollView, int x, int y,
int oldx, int oldy,boolean isByUser) {
if(x>=){
this.mCurrentPosition=x;
mImageLists.showSelectArea(true);
mBottomLength = mImageLists.getMeasuredWidth();
if(mBottomLength!=){
mDragPosition = mDuration*x/mBottomLength;
}
if(!mVideoView.isPlaying()&&!isPlaying){
mHandler.sendEmptyMessage();
}
currentTime.setText(TimeFormatUtils.formatLongToTimeStr(mDragPosition)+"");
}
}
private TextView currentTime;
private ObservableScrollView mScrollView;
private AlertDialog alertDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_edit_vedio);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
WindowManager windowManager = (WindowManager) getApplication().
getSystemService(getApplication().WINDOW_SERVICE);
screenWidth = windowManager.getDefaultDisplay().getWidth();
screenHeight = windowManager.getDefaultDisplay().getHeight();
mVedioPath = getIntent().getStringExtra("vedio_path");
info=new ComposeInfo();
info.setPath(mVedioPath);
if(dao==null){
dao=new RecordDao(this);
}
bean = new AttachsBeen();
bean.setAchsPath(mVedioPath);
bean = dao.isExist(bean);
info.setTips(bean.getTips());
info.setFlags(bean.getFlags());
initView();
init();
}
/**
* 初始化頁面控件
*/
private void initView() {
mVideoView = (VideoView)this.findViewById(R.id.vv_vedio_show);
View backView=this.findViewById(R.id.iv_edit_back);
backView.setOnClickListener(this);
mPlayerController = (ImageView)this.findViewById(R.id.iv_play_pause);
mPlayerController.setOnClickListener(this);
mVideoDuration = (TextView)this.findViewById(R.id.tv_duration);
mCutter = (ImageView)this.findViewById(R.id.iv_btn_cut);
mCutter.setOnClickListener(this);
mDelete = (ImageView)this.findViewById(R.id.iv_delete);
mDelete.setOnClickListener(this);
mmerge = (ImageView)this.findViewById(R.id.iv_merge);
mmerge.setOnClickListener(this);
mImageLists = (EditVideoImageBar)this.findViewById(R.id.iv_show);
mVideoEditProgressBar = (VideoEditProgressBar)this.findViewById(R.id.vedio_progress);
currentTime = (TextView)this.findViewById(R.id.tv_progress_time);
mScrollView = (ObservableScrollView)this.findViewById(R.id.sl);
mScrollView.setScrollViewListener(this);
mImageLists.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mImageLists.showSelectArea(false);
}
});
LinearLayout ll_wave_content = (LinearLayout)this.findViewById(R.id.ll_scroll);
ll_wave_content.setPadding(screenWidth/, , screenWidth/, );
}
/**
* 初始化參數生成
*/
private void init() {
mImageLists.clearPosition();
initVideoInfo();
mVideoEditProgressBar.clearPoint();
mVideoEditProgressBar.setPausePoints(info.getPausePoints());
final ArrayList<Float> pausePoints = new ArrayList<Float>();
mVideoView.setVideoPath(mVedioPath);
mVideoView.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mDuration = mp.getDuration();
// mVideoView.seekTo(1);//避免顯示黑屏
mVideoDuration.setText(TimeFormatUtils.formatLongToTimeStr(mDuration)+"");
if(info.getFlags()!=null&&!info.getFlags().isEmpty()){
for (int i = ; i <info.getFlags().size(); i++) {
Integer integer = info.getFlags().get(i);
pausePoints.add(integer*f/mDuration);
}
}
if (pausePoints != null && pausePoints.size() > ) {
mVideoEditProgressBar.setPausePoints(pausePoints);
}
mVideoView.start();
mHandler.sendEmptyMessageDelayed(, );
}
});
// mVideoView.seekTo(1);
mVideoView.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
isPlayCompletion=true;
isPlaying=false;
mPlayerController.getDrawable().setLevel();
mScrollView.scrollTo(mDragPosition, );
}
});
}
private boolean isPlayCompletion=false;
/**
* 初始化視訊檔案資訊
*/
private void initVideoInfo(){
File playFile=new File(mVedioPath);
if(playFile.exists()){
new ExtractTask(mVedioPath).execute();//執行抽取關鍵幀的異步任務
}else{
Toast.makeText(this, "請檢查視訊檔案是否存在!", ).show();
}
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.iv_edit_back://傳回按鈕
if(isEdit){
showTip();
}else{
finish();
}
break;
case R.id.iv_play_pause://視訊暫停/開始
playVideo();
break;
case R.id.iv_btn_cut://裁剪按鈕
setCurrentPostion();
break;
case R.id.iv_delete://删除按鈕
cutVideo();
break;
case R.id.iv_merge://合并按鈕
if(isEdit){//如果被編輯了
showTip();
}else{
Toast.makeText(EditVedioActivity.this, "您還未對視訊進行編輯!", ).show();
}
break;
case R.id.tv_yes:
//TODO
saveFlag();//儲存重置的标記點
// EventBus.getDefault().post(new StringMessage(mVedioPath));
alertDialog.dismiss();
finish();
break;
case R.id.tv_no://不儲存
alertDialog.dismiss();
finish();
break;
default:
break;
}
}
/**
* 音頻的裁剪删除操作
*/
protected void cutVideo() {
cutPostion = mImageLists.getCutPostion();
if(cutPostion!=null&&cutPostion.size()>){
onSave();
}else{
Toast.makeText(this, "請選擇删除視訊片段!", ).show();
}
}
/**
* 進行斷點處理
*/
private void setCurrentPostion(){
mImageLists.setCutPostion(mCurrentPosition);
}
/**
* 顯示是否儲存編輯的提示
*/
private void showTip(){
if (alertDialog == null) {
alertDialog = new AlertDialog.Builder(this)
.create();
}
alertDialog.show();
View tipView = View.inflate(this, R.layout.edit_alert_layout, null);
View tv_yes = (TextView) tipView.findViewById(R.id.tv_yes);
//不再提醒
tv_yes.setOnClickListener(this);
tipView.findViewById(R.id.tv_no).setOnClickListener(this);
alertDialog.setContentView(tipView);
}
@Override
public void onBackPressed() {
if(isEdit){
showTip();
}else{
super.onBackPressed();
}
}
/**
* 播放控制
*/
private void playVideo() {
if(isPlayCompletion){
mDragPosition=;
mScrollView.scrollTo(mDragPosition, );
isPlayCompletion=false;
}
if(mVideoView.isPlaying()){
isPlaying=false;
mVideoView.pause();
mPlayerController.getDrawable().setLevel();
}else{
isPlaying=true;
// mVideoView.seekTo(mDragPosition);
mPlayerController.getDrawable().setLevel();
mVideoView.start();
}
mHandler.sendEmptyMessage();
}
private int width1;
private VideoEditProgressBar mVideoEditProgressBar;
/**
* 抽取關鍵幀的異步任務
* @author howie
*
*/
class ExtractTask extends AsyncTask<Void, Void, Bitmap>{
private String path;
private ProgressDialog progressDialog1;
public ExtractTask(String path) {
super();
this.path = path;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
if(progressDialog1==null){
progressDialog1 = ProgressDialog.show(EditVedioActivity.this,
"加載中...", "請稍等...", true);
}else{
progressDialog1.show();
}
}
@Override
protected Bitmap doInBackground(Void... arg0) {
return BitmapUtils.addHBitmap(addFrames(path));
}
@SuppressLint("NewApi")
@Override
protected void onPostExecute(Bitmap bitmaps) {
super.onPostExecute(bitmaps);
progressDialog1.dismiss();
progressDialog1.cancel();
progressDialog1=null;
mImageLists.setBackground(new BitmapDrawable(bitmaps));
mHandler.sendEmptyMessage();
}
}
private List<Bitmap> addFrames(String path) {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(path);
// 取得視訊的長度(機關為毫秒)
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
int duration = Integer.parseInt(time);
int toatalFrames = duration / ;
keyFrameList = new ArrayList<Integer>();
int interval = ;
for (int i = ; i < toatalFrames; i++) {//
int frameTime = Integer.valueOf(interval) / ;
keyFrameList.add(frameTime);
interval += duration / toatalFrames;
}
List<Bitmap> bits=new ArrayList<Bitmap>();
for (int i = ; i < keyFrameList.size(); i++) {
Bitmap bitmap = retriever.getFrameAtTime(keyFrameList.get(i) * * ,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
if(bitmap!=null){
int bmpWidth=bitmap.getWidth();
int bmpHeight=bitmap.getHeight();
float scale=(float) ;
/* 産生reSize後的Bitmap對象 */
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
Bitmap resizeBmp = Bitmap.createBitmap(bitmap,,,bmpWidth,
bmpHeight,matrix,true);
bits.add(resizeBmp);
}
}
return bits;
}
private int mCurrentPosition=;
/**
* 删除删除片段操作
*/
private void onSave() {
saveRingtone();
}
private int mNewFileKind;
private File outFile;
private List<float[]> cutPostion;
private boolean isEdit=false;
private List<long[]> cutPostion_temp=new ArrayList<long[]>();
private List<long[]> cutPostion_use=new ArrayList<long[]>();
private List<long[]> cutPostion_use1=new ArrayList<long[]>();
protected String mMessage=null;
protected List<String> mMergerList;
private void saveRingtone() {
isEdit = true;
cutPostion_temp.clear();
for(int i=;i<cutPostion.size();i++){
long[] temp_fs=new long[];
float[] fs = cutPostion.get(i);
double start=fs[]*mDuration/mBottomLength;
double end=fs[]*mDuration/mBottomLength;
temp_fs[] = (long) start;
temp_fs[] = (long) end;
cutPostion_temp.add(temp_fs);
}
cutPostion_use.clear();
//頭部開始計算
long[] lg_f=new long[];
lg_f[]=;
lg_f[]=;
cutPostion_use.add(lg_f);
//添加選中的區間
for(int i=;i<cutPostion_temp.size();i++){
cutPostion_use.add(cutPostion_temp.get(i));
}
//最後的預設選中區間
long[] lg_e=new long[];
lg_e[]=mDuration;
lg_e[]=mDuration;
cutPostion_use.add(lg_e);
cutPostion_use1.clear();
//非選中區間集合
for(int i=;i<cutPostion_use.size();i++){
if((i+)<cutPostion_use.size()){
//不超邊界
if((cutPostion_use.get(i+)[]-cutPostion_use.get(i)[])!=){
//所取區域的幀數不能為0,即去除時間段為0 的區間片段
long[] lon=new long[];
lon[]=cutPostion_use.get(i)[];
lon[]=cutPostion_use.get(i+)[];
cutPostion_use1.add(lon);
}
}
}
//合并前重置标記點集合
resetFlag(cutPostion_use1);
String workingPath=getRecordFileFolder()+"/trim";
//裁剪操縱開始執行
trimVideo(workingPath,cutPostion_use1);
}
/**
* 重置标記集合
*/
private void resetFlag(List<long[]> cutPostion_use1) {
ArrayList<Integer> flags = info.getFlags();
ArrayList<Integer> flags_temp=new ArrayList<Integer>();
boolean isContent=false;
if(flags!=null&&flags.size()>){
for(int i=;i<flags.size();i++){
for(int j=;j<cutPostion_use1.size();j++){
if(flags.get(i)<cutPostion_use1.get(j)[]&&flags.get(i)>cutPostion_use1.get(j)[]){
isContent=true;
}
}
if(isContent){
flags_temp.add(flags.get(i));
}
}
bean.setFlags(flags_temp);
}
}
/**
* 裁剪視訊
*/
private void trimVideo(String workingPath, List<long[]> newSeeks){
progressDialog = ProgressDialog.show(EditVedioActivity.this,
"裁剪中...", "請稍等...", true);
File storagePath = new File(workingPath);
storagePath.mkdirs();
FfmpegManager manager = FfmpegManager.getInstance();
File file = new File(mVedioPath);
boolean exists = file.exists();
manager.trimVideo(EditVedioActivity.this, file, storagePath, newSeeks, new CompletionListener() {
@Override
public void onProcessCompleted(String message,List<String> merger) {
if(merger!=null&&merger.size()>){
mMergerList=merger;
mHandler.sendEmptyMessage();
}
}
});
}
/**
* 合并裁剪過後的視訊
*/
private void mererVideo(){
String workingPath1=getRecordFileFolder()+"/merge";
File storagePath1 = new File(workingPath1);
storagePath1.mkdirs();
File myMovie = new File(storagePath1, String.format("cut-output-%s.mp4", System.currentTimeMillis()+""));
finalPath = myMovie.getAbsolutePath();
VideoStitchingRequest videoStitchingRequest = new VideoStitchingRequest.Builder()
.inputVideoFilePath((ArrayList<String>) mMergerList)
.outputPath(finalPath).build();
FfmpegManager manager = FfmpegManager.getInstance();
manager.stitchVideos(this, videoStitchingRequest,
new CompletionListener() {
@Override
public void onProcessCompleted(String message,List<String> merger) {
mHandler.sendEmptyMessage();
mMessage=message;
}
});
}
private void reRreshUI(){
progressDialog.dismiss();
progressDialog.cancel();
progressDialog=null;
if(mMessage!=null){
Toast.makeText(this, "編輯成功!", Toast.LENGTH_SHORT).show();
isEdit=true;//已經編輯過了
mVedioPath=finalPath;
init();
}else{
}
}
private static final String fileFolder = Environment.getExternalStorageDirectory().getAbsolutePath()+"/jwzt_recorder";
private ProgressDialog progressDialog;
private String finalPath;
private String getRecordFileFolder() {
File file = new File(fileFolder);
if (!file.exists()) {
file.mkdir();
}
return fileFolder;
}
/**
* 标記儲存操作
*/
private void saveFlag() {
RecordDao recordDao=new RecordDao(new DatabaseContext(this));
RecordDetail bean=new RecordDetail();
bean.setName(getVideoName(mVedioPath));
bean.setFormat("mp4");
bean.setPath(mVedioPath);
bean.setMarks(info.getTips());//斷點拍攝的點的進度的值
bean.setFlags(info.getFlags());
recordDao.add(bean);
}
private String getVideoName(String path){
int slash = path.lastIndexOf("/");
int dot = path.lastIndexOf(".");
String substring = path.substring(slash+, dot);
return substring;
}
}
FFmpeg裁剪線程:
package com.tian.videomergedemo.task;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.util.Log;
import com.tian.videomergedemo.inter.CompletionListener;
import com.tian.videomergedemo.utils.TimeFormatUtils;
/**
* @author TCX
*/
public class TrimTask implements Runnable {
private Context context;
// private VideoStitchingRequest videoStitchingRequest;
private CompletionListener completionListener;
private String mFfmpegInstallPath;
private File srcFile;
private File destFile;
private List<long[]> mNewSeeks;
private List<String> mMergeList=new ArrayList<String>();
public TrimTask(Context context, String mFfmpegInstallPath, File srcFile,File destFile,List<long[]> mNewSeeks, CompletionListener completionListener) {
this.context = context;
this.mFfmpegInstallPath = mFfmpegInstallPath;
// this.videoStitchingRequest = stitchingRequest;
this.completionListener = completionListener;
this.srcFile=srcFile;
this.destFile=destFile;
this.mNewSeeks=mNewSeeks;
}
@Override
public void run() {
trimVideo(context, mFfmpegInstallPath, completionListener, mNewSeeks, srcFile, destFile);
}
/**
* @param context
* @param mFfmpegInstallPath
* @param videoStitchingRequest
* @param completionListener
*/
private void trimVideo(Context context, String mFfmpegInstallPath, final CompletionListener completionListener,List<long[]> mNewSeeks,File srcFile,File destFile) {
mMergeList.clear();
for(int i=;i<mNewSeeks.size();i++){
File myMovie = new File(destFile, String.format("0cut_output-%s.mp4", System.currentTimeMillis()+""));
mMergeList.add(myMovie.getAbsolutePath());
String startTime=TimeFormatUtils.formatLongToTimeStr((int)mNewSeeks.get(i)[]);
String durationTime=TimeFormatUtils.formatLongToTimeStr((int)(mNewSeeks.get(i)[]-mNewSeeks.get(i)[]));
// ffmpeg -ss 00:00:20 -t 00:00:10 -i D:/MyVideo.mpg -vcodec copy -acopy copy D:/Split.mpg
// String [] ffmpegTrimCommand={mFfmpegInstallPath,"-ss" ,startTime, "-t",durationTime, "-i" ,srcFile.getAbsolutePath(), "-vcodec","copy" , "-acopy","copy",myMovie.getAbsolutePath(),"-y"};
//切割的指令行
String [] ffmpegTrimCommand={mFfmpegInstallPath,"-i" ,srcFile.getAbsolutePath(),"-vcodec", "copy", "-acodec", "copy","-ss",startTime ,"-t" , durationTime,myMovie.getAbsolutePath(),"-y"};
try {
Process ffmpegProcess = new ProcessBuilder(ffmpegTrimCommand)
.redirectErrorStream(true).start();
String line;
BufferedReader reader = new BufferedReader(
new InputStreamReader(ffmpegProcess.getInputStream()));
Log.e("***", "*******Starting FFMPEG");
while ((line = reader.readLine()) != null) {
Log.e("***", "***" + line + "***");
}
Log.e(null, "****ending FFMPEG****");
ffmpegProcess.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
//裁剪完成回調接口(MergeList為裁剪後短視訊的路徑集合)
completionListener.onProcessCompleted("Video trim Comleted",mMergeList);
}
/**
* 将播放的進度轉換成類似00:00:01.000”這種形
* @param progressPosition
* @return
*/
public static String convertToStr(int progressPosition){
//先求出剩餘的餘數的毫
int remain=progressPosition%;
//求出整數的秒數(可能大于60秒,如果大于60秒則要轉換為分鐘
int seconds=progressPosition/;
int minutes=seconds/;
//求餘數求出剩餘的秒數
int remainSecond=seconds%;
String millSeconds=remain+"";
if(remain<){
millSeconds="00"+millSeconds;
}else if(remain<){
millSeconds="0"+millSeconds;
}
String second=remainSecond+"";
if(remainSecond<){
second="0"+second;
}
String minute=minutes+"";
if(minutes<){
minute="0"+minute;
}
return "00:"+minute+":"+second+"."+millSeconds;
}
}
ok,一些基本的功能類就這些了。
github位址:
https://github.com/T-chuangxin/VideoMergeDemo