parent
b2ef61cc53
commit
da13535830
@ -1,20 +1,228 @@ |
|||||||
package com.frank.ffmpeg.activity; |
package com.frank.ffmpeg.activity; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
import android.os.Bundle; |
import android.os.Bundle; |
||||||
|
import android.os.Environment; |
||||||
|
import android.os.Handler; |
||||||
|
import android.os.Message; |
||||||
import android.support.v7.app.AppCompatActivity; |
import android.support.v7.app.AppCompatActivity; |
||||||
|
import android.util.Log; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.ProgressBar; |
||||||
|
|
||||||
|
import com.frank.ffmpeg.FFmpegCmd; |
||||||
import com.frank.ffmpeg.R; |
import com.frank.ffmpeg.R; |
||||||
|
import com.frank.ffmpeg.util.FFmpegUtil; |
||||||
|
|
||||||
/** |
import java.io.File; |
||||||
* 使用ffmpeg进行视频处理 |
|
||||||
* Created by frank on 2018/1/23. |
public class VideoHandleActivity extends AppCompatActivity implements View.OnClickListener{ |
||||||
*/ |
|
||||||
public class VideoHandleActivity extends AppCompatActivity { |
private static final String TAG = VideoHandleActivity.class.getSimpleName(); |
||||||
|
private static final int MSG_BEGIN = 101; |
||||||
|
private static final int MSG_FINISH = 102; |
||||||
|
|
||||||
|
private static final String PATH = Environment.getExternalStorageDirectory().getPath(); |
||||||
|
private static final String srcFile = PATH + File.separator + "hello.mp4"; |
||||||
|
private static final String appendVideo = PATH + File.separator + "test.mp4"; |
||||||
|
private ProgressBar progress_video; |
||||||
|
|
||||||
|
@SuppressLint("HandlerLeak") |
||||||
|
private Handler mHandler = new Handler(){ |
||||||
|
@Override |
||||||
|
public void handleMessage(Message msg) { |
||||||
|
super.handleMessage(msg); |
||||||
|
switch (msg.what){ |
||||||
|
case MSG_BEGIN: |
||||||
|
progress_video.setVisibility(View.VISIBLE); |
||||||
|
setGone(); |
||||||
|
break; |
||||||
|
case MSG_FINISH: |
||||||
|
progress_video.setVisibility(View.GONE); |
||||||
|
setVisible(); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
@Override |
@Override |
||||||
protected void onCreate(Bundle savedInstanceState) { |
protected void onCreate(Bundle savedInstanceState) { |
||||||
super.onCreate(savedInstanceState); |
super.onCreate(savedInstanceState); |
||||||
setContentView(R.layout.activity_video_handle); |
setContentView(R.layout.activity_video_handle); |
||||||
|
|
||||||
|
intView(); |
||||||
|
} |
||||||
|
|
||||||
|
private void intView() { |
||||||
|
progress_video = (ProgressBar)findViewById(R.id.progress_video); |
||||||
|
findViewById(R.id.btn_video_transform).setOnClickListener(this); |
||||||
|
findViewById(R.id.btn_video_cut).setOnClickListener(this); |
||||||
|
findViewById(R.id.btn_video_concat).setOnClickListener(this); |
||||||
|
findViewById(R.id.btn_screen_shot).setOnClickListener(this); |
||||||
|
findViewById(R.id.btn_water_mark).setOnClickListener(this); |
||||||
|
findViewById(R.id.btn_generate_gif).setOnClickListener(this); |
||||||
|
findViewById(R.id.btn_screen_record).setOnClickListener(this); |
||||||
|
findViewById(R.id.btn_combine_video).setOnClickListener(this); |
||||||
|
} |
||||||
|
|
||||||
|
private void setVisible() { |
||||||
|
findViewById(R.id.btn_video_transform).setVisibility(View.VISIBLE); |
||||||
|
findViewById(R.id.btn_video_cut).setVisibility(View.VISIBLE); |
||||||
|
findViewById(R.id.btn_video_concat).setVisibility(View.GONE); |
||||||
|
findViewById(R.id.btn_screen_shot).setVisibility(View.VISIBLE); |
||||||
|
findViewById(R.id.btn_water_mark).setVisibility(View.VISIBLE); |
||||||
|
findViewById(R.id.btn_generate_gif).setVisibility(View.VISIBLE); |
||||||
|
findViewById(R.id.btn_screen_record).setVisibility(View.GONE); |
||||||
|
findViewById(R.id.btn_combine_video).setVisibility(View.VISIBLE); |
||||||
|
} |
||||||
|
|
||||||
|
private void setGone() { |
||||||
|
findViewById(R.id.btn_video_transform).setVisibility(View.GONE); |
||||||
|
findViewById(R.id.btn_video_cut).setVisibility(View.GONE); |
||||||
|
findViewById(R.id.btn_video_concat).setVisibility(View.GONE); |
||||||
|
findViewById(R.id.btn_screen_shot).setVisibility(View.GONE); |
||||||
|
findViewById(R.id.btn_water_mark).setVisibility(View.GONE); |
||||||
|
findViewById(R.id.btn_generate_gif).setVisibility(View.GONE); |
||||||
|
findViewById(R.id.btn_screen_record).setVisibility(View.GONE); |
||||||
|
findViewById(R.id.btn_combine_video).setVisibility(View.GONE); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
int handleType; |
||||||
|
switch (v.getId()){ |
||||||
|
case R.id.btn_video_transform: |
||||||
|
handleType = 0; |
||||||
|
break; |
||||||
|
case R.id.btn_video_cut: |
||||||
|
handleType = 1; |
||||||
|
break; |
||||||
|
case R.id.btn_video_concat: |
||||||
|
handleType = 2; |
||||||
|
break; |
||||||
|
case R.id.btn_screen_shot: |
||||||
|
handleType = 3; |
||||||
|
break; |
||||||
|
case R.id.btn_water_mark: |
||||||
|
handleType = 4; |
||||||
|
break; |
||||||
|
case R.id.btn_generate_gif: |
||||||
|
handleType = 5; |
||||||
|
break; |
||||||
|
case R.id.btn_screen_record: |
||||||
|
handleType = 6; |
||||||
|
break; |
||||||
|
case R.id.btn_combine_video: |
||||||
|
handleType = 7; |
||||||
|
break; |
||||||
|
default: |
||||||
|
handleType = 0; |
||||||
|
break; |
||||||
|
} |
||||||
|
doHandleVideo(handleType); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 调用ffmpeg处理视频 |
||||||
|
* @param handleType handleType |
||||||
|
*/ |
||||||
|
private void doHandleVideo(int handleType){ |
||||||
|
String[] commandLine = null; |
||||||
|
switch (handleType){ |
||||||
|
case 0://视频转码
|
||||||
|
String transformVideo = PATH + File.separator + "transformVideo.wmv"; |
||||||
|
commandLine = FFmpegUtil.transformVideo(srcFile, transformVideo); |
||||||
|
break; |
||||||
|
case 1://视频剪切
|
||||||
|
String cutVideo = PATH + File.separator + "cutVideo.mp4"; |
||||||
|
int startTime = 0; |
||||||
|
int duration = 20; |
||||||
|
commandLine = FFmpegUtil.cutVideo(srcFile, startTime, duration, cutVideo); |
||||||
|
break; |
||||||
|
case 2://视频合并
|
||||||
|
// commandLine = FFmpegUtil.toTs(srcFile, ts1);
|
||||||
|
// concatStep ++;
|
||||||
|
// String concatVideo = PATH + File.separator + "concatVideo.mp4";
|
||||||
|
// String appendVideo = PATH + File.separator + "test.mp4";
|
||||||
|
// File concatFile = new File(PATH + File.separator + "fileList.txt");
|
||||||
|
// try {
|
||||||
|
// FileOutputStream fileOutputStream = new FileOutputStream(concatFile);
|
||||||
|
// fileOutputStream.write(("file \'" + srcFile + "\'").getBytes());
|
||||||
|
// fileOutputStream.write("\n".getBytes());
|
||||||
|
// fileOutputStream.write(("file \'" + appendVideo + "\'").getBytes());
|
||||||
|
// fileOutputStream.flush();
|
||||||
|
// fileOutputStream.close();
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// commandLine = FFmpegUtil.concatVideo(srcFile, concatFile.getAbsolutePath(), concatVideo);
|
||||||
|
break; |
||||||
|
case 3://视频截图
|
||||||
|
String screenShot = PATH + File.separator + "screenShot.jpg"; |
||||||
|
String size = "1080x720"; |
||||||
|
commandLine = FFmpegUtil.screenShot(srcFile, size, screenShot); |
||||||
|
break; |
||||||
|
case 4://视频添加水印
|
||||||
|
//1、图片
|
||||||
|
String photo = PATH + File.separator + "launcher.png"; |
||||||
|
String photoMark = PATH + File.separator + "photoMark.mp4"; |
||||||
|
commandLine = FFmpegUtil.addWaterMark(appendVideo, photo, photoMark); |
||||||
|
//2、文字
|
||||||
|
//String text = "Hello,FFmpeg";
|
||||||
|
//String textPath = PATH + File.separator + "text.jpg";
|
||||||
|
//boolean result = BitmapUtil.textToPicture(textPath, text, this);
|
||||||
|
//Log.i(TAG, "text to pitcture result=" + result);
|
||||||
|
//String textMark = PATH + File.separator + "textMark.mp4";
|
||||||
|
//commandLine = FFmpegUtil.addWaterMark(appendVideo, photo, textMark);
|
||||||
|
break; |
||||||
|
case 5://视频转成gif
|
||||||
|
String Video2Gif = PATH + File.separator + "Video2Gif.gif"; |
||||||
|
int gifStart = 30; |
||||||
|
int gifDuration = 5; |
||||||
|
commandLine = FFmpegUtil.generateGif(srcFile, gifStart, gifDuration, Video2Gif); |
||||||
|
break; |
||||||
|
case 6://屏幕录制
|
||||||
|
// String screenRecord = PATH + File.separator + "screenRecord.mp4";
|
||||||
|
// String screenSize = "320x240";
|
||||||
|
// int recordTime = 10;
|
||||||
|
// commandLine = FFmpegUtil.screenRecord(screenSize, recordTime, screenRecord);
|
||||||
|
break; |
||||||
|
case 7://图片合成视频
|
||||||
|
//图片所在路径,图片命名格式img+number.jpg
|
||||||
|
String picturePath = PATH + File.separator + "img/"; |
||||||
|
String combineVideo = PATH + File.separator + "combineVideo.mp4"; |
||||||
|
commandLine = FFmpegUtil.pictureToVideo(picturePath, combineVideo); |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
executeFFmpegCmd(commandLine); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 执行ffmpeg命令行 |
||||||
|
* @param commandLine commandLine |
||||||
|
*/ |
||||||
|
private void executeFFmpegCmd(final String[] commandLine){ |
||||||
|
if(commandLine == null){ |
||||||
|
return; |
||||||
|
} |
||||||
|
FFmpegCmd.execute(commandLine, new FFmpegCmd.OnHandleListener() { |
||||||
|
@Override |
||||||
|
public void onBegin() { |
||||||
|
Log.i(TAG, "handle video onBegin..."); |
||||||
|
mHandler.obtainMessage(MSG_BEGIN).sendToTarget(); |
||||||
} |
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onEnd(int result) { |
||||||
|
Log.i(TAG, "handle video onEnd..."); |
||||||
|
|
||||||
|
mHandler.obtainMessage(MSG_FINISH).sendToTarget(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
} |
} |
||||||
|
@ -0,0 +1,92 @@ |
|||||||
|
package com.frank.ffmpeg.util; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.graphics.Bitmap; |
||||||
|
import android.graphics.Color; |
||||||
|
import android.view.Gravity; |
||||||
|
import android.view.View; |
||||||
|
import android.widget.LinearLayout; |
||||||
|
import android.widget.TextView; |
||||||
|
|
||||||
|
import java.io.File; |
||||||
|
import java.io.FileOutputStream; |
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
/** |
||||||
|
* bitmap工具类:文字转成图片 |
||||||
|
* Created by frank on 2018/1/24. |
||||||
|
*/ |
||||||
|
|
||||||
|
public class BitmapUtil { |
||||||
|
|
||||||
|
private final static int TEXT_SIZE = 16; |
||||||
|
private final static int TEXT_COLOR = Color.RED; |
||||||
|
|
||||||
|
/** |
||||||
|
* 文本转成Bitmap |
||||||
|
* @param text 文本内容 |
||||||
|
* @param context 上下文 |
||||||
|
* @return 图片的bitmap |
||||||
|
*/ |
||||||
|
private static Bitmap textToBitmap(String text , Context context) { |
||||||
|
float scale = context.getResources().getDisplayMetrics().scaledDensity; |
||||||
|
TextView tv = new TextView(context); |
||||||
|
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( |
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT, |
||||||
|
LinearLayout.LayoutParams.WRAP_CONTENT); |
||||||
|
tv.setLayoutParams(layoutParams); |
||||||
|
tv.setText(text); |
||||||
|
tv.setTextSize(scale * TEXT_SIZE); |
||||||
|
tv.setGravity(Gravity.CENTER_HORIZONTAL); |
||||||
|
tv.setDrawingCacheEnabled(true); |
||||||
|
tv.setTextColor(TEXT_COLOR); |
||||||
|
tv.setBackgroundColor(Color.WHITE); |
||||||
|
tv.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), |
||||||
|
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); |
||||||
|
tv.layout(0, 0, tv.getMeasuredWidth(), tv.getMeasuredHeight()); |
||||||
|
tv.buildDrawingCache(); |
||||||
|
Bitmap bitmap = tv.getDrawingCache(); |
||||||
|
int rate = bitmap.getHeight() / 20; |
||||||
|
return Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/rate, 20, false); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 文字生成图片 |
||||||
|
* @param filePath filePath |
||||||
|
* @param text text |
||||||
|
* @param context context |
||||||
|
* @return 生成图片是否成功 |
||||||
|
*/ |
||||||
|
public static boolean textToPicture(String filePath, String text , Context context){ |
||||||
|
Bitmap bitmap = textToBitmap(text , context); |
||||||
|
FileOutputStream outputStream = null; |
||||||
|
try { |
||||||
|
outputStream = new FileOutputStream(filePath); |
||||||
|
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, outputStream); |
||||||
|
outputStream.flush(); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
return false; |
||||||
|
}finally { |
||||||
|
try { |
||||||
|
if(outputStream != null){ |
||||||
|
outputStream.close(); |
||||||
|
} |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除源文件 |
||||||
|
* @param filePath filePath |
||||||
|
* @return 删除是否成功 |
||||||
|
*/ |
||||||
|
public static boolean deleteTextFile(String filePath) { |
||||||
|
File file = new File(filePath); |
||||||
|
return file.exists() && file.delete(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue