您的位置:首页 > 移动开发 > Android开发

android视频的编辑(录制,裁剪,合成)(2)

2017-06-22 12:34 375 查看
废话少说接着上一篇的接着介绍:

布局文件:

<?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=0;
private int mBottomLength=1;
private int mDragPosition=0;//手势拖动的距离
private boolean isPlaying=false;

private Handler mHandler=new Handler(){

@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
switch (msg.what) {
case 0://拖动更新
if(!mVideoView.isPlaying()&&!isPlaying){
//非播放状态
mVideoView.seekTo(mDragPosition);
}else{
//播放状态
int mDragPosition1 = mVideoView.getCurrentPosition();
int currentPosition=0;
if(mDuration!=0){
currentPosition=mBottomLength*mDragPosition1/mDuration;
}else{
if(currentPosition<=100){
currentPosition=mDragPosition1;
}
}
mScrollView.scrollTo(currentPosition==0?1:currentPosition, 0);
mCurrentPosition=currentPosition;
mHandler.sendEmptyMessageDelayed(0, 100);
}
int currentPosition = mVideoView.getCurrentPosition();
mVideoEditProgressBar.setProgress((currentPosition*1.0f/mDuration));
break;
case 1://视频播放或者暂停action

break;
case 3:
mVideoView.pause();
break;
case 100:
mererVideo();
break;
case 101:
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>=0){
this.mCurrentPosition=x;
mImageLists.showSelectArea(true);
mBottomLength = mImageLists.getMeasuredWidth();
if(mBottomLength!=0){
mDragPosition = mDuration*x/mBottomLength;
}
if(!mVideoView.isPlaying()&&!isPlaying){
mHandler.sendEmptyMessage(0);
}
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/2, 0, screenWidth/2, 0);
}

/**
* 初始化参数生成
*/
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 = 0; i <info.getFlags().size(); i++) {
Integer integer = info.getFlags().get(i);
pausePoints.add(integer*1.0f/mDuration);
}
}
if (pausePoints != null && pausePoints.size() > 0) {
mVideoEditProgressBar.setPausePoints(pausePoints);
}
mVideoView.start();
mHandler.sendEmptyMessageDelayed(3, 100);

}
});
//      mVideoView.seekTo(1);
mVideoView.setOnCompletionListener(new OnCompletionListener() {

@Override
public void onCompletion(MediaPlayer mp) {
isPlayCompletion=true;
isPlaying=false;
mPlayerController.getDrawable().setLevel(1);
mScrollView.scrollTo(mDragPosition, 0);
}
});
}
private boolean isPlayCompletion=false;

/**
* 初始化视频文件信息
*/
private void initVideoInfo(){
File playFile=new File(mVedioPath);
if(playFile.exists()){
new ExtractTask(mVedioPath).execute();//执行抽取关键帧的异步任务
}else{
Toast.makeText(this, "请检查视频文件是否存在!", 0).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, "您还未对视频进行编辑!", 0).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()>0){
onSave();
}else{
Toast.makeText(this, "请选择删除视频片段!", 0).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=0;
mScrollView.scrollTo(mDragPosition, 0);
isPlayCompletion=false;
}
if(mVideoView.isPlaying()){
isPlaying=false;
mVideoView.pause();
mPlayerController.getDrawable().setLevel(1);
}else{
isPlaying=true;
//          mVideoView.seekTo(mDragPosition);
mPlayerController.getDrawable().setLevel(2);
mVideoView.start();
}

mHandler.sendEmptyMessage(0);

}
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(0);
}

}

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 / 1000;
keyFrameList = new ArrayList<Integer>();
int interval = 0;

for (int i = 0; i < toatalFrames; i++) {//
int frameTime = Integer.valueOf(interval) / 1000;
keyFrameList.add(frameTime);
interval += duration / toatalFrames;
}
List<Bitmap> bits=new ArrayList<Bitmap>();
for (int i = 0; i < keyFrameList.size(); i++) {
Bitmap bitmap = retriever.getFrameAtTime(keyFrameList.get(i) * 1000 * 1000,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
if(bitmap!=null){
int bmpWidth=bitmap.getWidth();
int bmpHeight=bitmap.getHeight();
float scale=(float) 0.7;
/* 产生reSize后的Bitmap对象 */
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bmpWidth,
bmpHeight,matrix,true);
bits.add(resizeBmp);
}
}
return bits;
}
private int mCurrentPosition=0;

/**
* 删除删除片段操作
*/
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=0;i<cutPostion.size();i++){
long[] temp_fs=new long[2];
float[] fs = cutPostion.get(i);

double start=fs[0]*mDuration/mBottomLength;
double end=fs[1]*mDuration/mBottomLength;

temp_fs[0] = (long) start;
temp_fs[1] = (long) end;
cutPostion_temp.add(temp_fs);
}
cutPostion_use.clear();

//头部开始计算
long[] lg_f=new long[2];
lg_f[0]=0;
lg_f[1]=0;
cutPostion_use.add(lg_f);
//添加选中的区间
for(int i=0;i<cutPostion_temp.size();i++){
cutPostion_use.add(cutPostion_temp.get(i));
}
//最后的默认选中区间
long[] lg_e=new long[2];
lg_e[0]=mDuration;
lg_e[1]=mDuration;
cutPostion_use.add(lg_e);
cutPostion_use1.clear();

//非选中区间集合
for(int i=0;i<cutPostion_use.size();i++){
if((i+1)<cutPostion_use.size()){
//不超边界
if((cutPostion_use.get(i+1)[0]-cutPostion_use.get(i)[1])!=0){
//所取区域的帧数不能为0,即去除时间段为0 的区间片段
long[] lon=new long[2];
lon[0]=cutPostion_use.get(i)[1];
lon[1]=cutPostion_use.get(i+1)[0];
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()>0){
for(int i=0;i<flags.size();i++){
for(int j=0;j<cutPostion_use1.size();j++){
if(flags.get(i)<cutPostion_use1.get(j)[1]&&flags.get(i)>cutPostion_use1.get(j)[0]){
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()>0){
mMergerList=merger;
mHandler.sendEmptyMessage(100);
}
}
});
}

/**
* 合并裁剪过后的视频
*/
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(101);
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+1, 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=0;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)[0]);
String durationTime=TimeFormatUtils.formatLongToTimeStr((int)(mNewSeeks.get(i)[1]-mNewSeeks.get(i)[0]));
//          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%1000;
//求出整数的秒数(可能大于60秒,如果大于60秒则要转换为分钟
int seconds=progressPosition/1000;
int minutes=seconds/60;
//求余数求出剩余的秒数
int remainSecond=seconds%60;
String millSeconds=remain+"";
if(remain<10){
millSeconds="00"+millSeconds;
}else if(remain<100){
millSeconds="0"+millSeconds;
}
String second=remainSecond+"";
if(remainSecond<10){
second="0"+second;
}
String minute=minutes+"";
if(minutes<10){
minute="0"+minute;
}
return "00:"+minute+":"+second+"."+millSeconds;
}

}


ok,一些基本的功能类就这些了。

github地址:

https://github.com/T-chuangxin/VideoMergeDemo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息