diff --git a/app/src/main/java/com/frank/ffmpeg/activity/AudioHandleActivity.java b/app/src/main/java/com/frank/ffmpeg/activity/AudioHandleActivity.java
index 32b41ae..8a0d5c7 100644
--- a/app/src/main/java/com/frank/ffmpeg/activity/AudioHandleActivity.java
+++ b/app/src/main/java/com/frank/ffmpeg/activity/AudioHandleActivity.java
@@ -1,12 +1,14 @@
package com.frank.ffmpeg.activity;
+import android.annotation.SuppressLint;
import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
-import android.widget.Toast;
-
+import android.widget.ProgressBar;
import java.io.File;
import com.frank.ffmpeg.FFmpegCmd;
import com.frank.ffmpeg.R;
@@ -20,9 +22,32 @@ import com.frank.ffmpeg.util.FFmpegUtil;
public class AudioHandleActivity extends AppCompatActivity implements View.OnClickListener{
private final static String TAG = AudioHandleActivity.class.getSimpleName();
- private static final String PATH = Environment.getExternalStorageDirectory().getPath();
- String srcFile = PATH + File.separator + "tiger.mp3";
- String appendFile = PATH + File.separator + "test.mp3";
+ private final static String PATH = Environment.getExternalStorageDirectory().getPath();
+ private String srcFile = PATH + File.separator + "tiger.mp3";
+ private String appendFile = PATH + File.separator + "test.mp3";
+ private final static int MSG_BEGIN = 11;
+ private final static int MSG_FINISH = 12;
+ private ProgressBar progress_audio;
+
+ @SuppressLint("HandlerLeak")
+ private Handler mHandler = new Handler(){
+ @Override
+ public void handleMessage(Message msg) {
+ super.handleMessage(msg);
+ switch (msg.what){
+ case MSG_BEGIN:
+ progress_audio.setVisibility(View.VISIBLE);
+ setGone();
+ break;
+ case MSG_FINISH:
+ progress_audio.setVisibility(View.GONE);
+ setVisible();
+ break;
+ default:
+ break;
+ }
+ }
+ };
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -33,12 +58,27 @@ public class AudioHandleActivity extends AppCompatActivity implements View.OnCli
}
private void initView() {
+ progress_audio = (ProgressBar) findViewById(R.id.progress_audio);
findViewById(R.id.btn_transform).setOnClickListener(this);
findViewById(R.id.btn_cut).setOnClickListener(this);
findViewById(R.id.btn_concat).setOnClickListener(this);
findViewById(R.id.btn_mix).setOnClickListener(this);
}
+ private void setVisible() {
+ findViewById(R.id.btn_transform).setVisibility(View.VISIBLE);
+ findViewById(R.id.btn_cut).setVisibility(View.VISIBLE);
+ findViewById(R.id.btn_concat).setVisibility(View.VISIBLE);
+ findViewById(R.id.btn_mix).setVisibility(View.VISIBLE);
+ }
+
+ private void setGone() {
+ findViewById(R.id.btn_transform).setVisibility(View.GONE);
+ findViewById(R.id.btn_cut).setVisibility(View.GONE);
+ findViewById(R.id.btn_concat).setVisibility(View.GONE);
+ findViewById(R.id.btn_mix).setVisibility(View.GONE);
+ }
+
@Override
public void onClick(View v) {
int handleType;
@@ -103,17 +143,13 @@ public class AudioHandleActivity extends AppCompatActivity implements View.OnCli
@Override
public void onBegin() {
Log.i(TAG, "handle audio onBegin...");
+ mHandler.obtainMessage(MSG_BEGIN).sendToTarget();
}
@Override
public void onEnd(int result) {
Log.i(TAG, "handle audio onEnd...");
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(AudioHandleActivity.this, "handle audio finish...", Toast.LENGTH_SHORT).show();
- }
- });
+ mHandler.obtainMessage(MSG_FINISH).sendToTarget();
}
});
}
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/MainActivity.java b/app/src/main/java/com/frank/ffmpeg/activity/MainActivity.java
index 01bd390..27173ec 100644
--- a/app/src/main/java/com/frank/ffmpeg/activity/MainActivity.java
+++ b/app/src/main/java/com/frank/ffmpeg/activity/MainActivity.java
@@ -4,8 +4,6 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
-import android.widget.Toast;
-
import com.frank.ffmpeg.R;
/**
@@ -38,8 +36,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
startActivity(new Intent(MainActivity.this, MediaHandleActivity.class));
break;
case R.id.btn_video://视频处理
- Toast.makeText(this, "暂时还没完善该功能...", Toast.LENGTH_LONG).show();
-// startActivity(new Intent(MainActivity.this, VideoHandleActivity.class));
+ startActivity(new Intent(MainActivity.this, VideoHandleActivity.class));
break;
default:
break;
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/MediaHandleActivity.java b/app/src/main/java/com/frank/ffmpeg/activity/MediaHandleActivity.java
index c223f09..7bfa747 100644
--- a/app/src/main/java/com/frank/ffmpeg/activity/MediaHandleActivity.java
+++ b/app/src/main/java/com/frank/ffmpeg/activity/MediaHandleActivity.java
@@ -10,12 +10,10 @@ import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
-import android.widget.Toast;
-
+import android.widget.ProgressBar;
import com.frank.ffmpeg.FFmpegCmd;
import com.frank.ffmpeg.R;
import com.frank.ffmpeg.util.FFmpegUtil;
-
import java.io.File;
/**
@@ -30,42 +28,58 @@ public class MediaHandleActivity extends AppCompatActivity implements View.OnCli
private String videoFile = PATH + File.separator + "flash-tree.mp4";//flash-tree.mp4
String temp = PATH + File.separator + "temp.mp4";
private boolean isMux;
+ private final static int MSG_MUX = 100;
+ private final static int MSG_BEGIN = 101;
+ private final static int MSG_FINISH = 102;
+ private ProgressBar progress_media;
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
- if(msg.what == 100){
- String audioFile = PATH + File.separator + "tiger.mp3";//tiger.mp3
- String muxFile = PATH + File.separator + "media-mux.mp4";
+ switch (msg.what){
+ case MSG_MUX:
+ String audioFile = PATH + File.separator + "tiger.mp3";//tiger.mp3
+ String muxFile = PATH + File.separator + "media-mux.mp4";
- try {
- //使用MediaPlayer获取视频时长
- MediaPlayer mediaPlayer = new MediaPlayer();
- mediaPlayer.setDataSource(videoFile);
- mediaPlayer.prepare();
- //单位为ms
- int videoDuration = mediaPlayer.getDuration()/1000;
- Log.i(TAG, "videoDuration=" + videoDuration);
- mediaPlayer.release();
- //使用MediaMetadataRetriever获取音频时长
- MediaMetadataRetriever mediaRetriever = new MediaMetadataRetriever();
- mediaRetriever.setDataSource(audioFile);
- //单位为ms
- String duration = mediaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
- int audioDuration = (int)(Long.parseLong(duration)/1000);
- Log.i(TAG, "audioDuration=" + audioDuration);
- mediaRetriever.release();
- //如果视频时长比音频长,采用音频时长,否则用视频时长
- int mDuration = Math.min(audioDuration, videoDuration);
- //使用纯视频与音频进行合成
- String[] commandLine = FFmpegUtil.mediaMux(temp, audioFile, mDuration, muxFile);
- executeFFmpegCmd(commandLine);
- isMux = false;
- } catch (Exception e) {
- e.printStackTrace();
- }
+ try {
+ //使用MediaPlayer获取视频时长
+ MediaPlayer mediaPlayer = new MediaPlayer();
+ mediaPlayer.setDataSource(videoFile);
+ mediaPlayer.prepare();
+ //单位为ms
+ int videoDuration = mediaPlayer.getDuration()/1000;
+ Log.i(TAG, "videoDuration=" + videoDuration);
+ mediaPlayer.release();
+ //使用MediaMetadataRetriever获取音频时长
+ MediaMetadataRetriever mediaRetriever = new MediaMetadataRetriever();
+ mediaRetriever.setDataSource(audioFile);
+ //单位为ms
+ String duration = mediaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
+ int audioDuration = (int)(Long.parseLong(duration)/1000);
+ Log.i(TAG, "audioDuration=" + audioDuration);
+ mediaRetriever.release();
+ //如果视频时长比音频长,采用音频时长,否则用视频时长
+ int mDuration = Math.min(audioDuration, videoDuration);
+ //使用纯视频与音频进行合成
+ String[] commandLine = FFmpegUtil.mediaMux(temp, audioFile, mDuration, muxFile);
+ executeFFmpegCmd(commandLine);
+ isMux = false;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ break;
+ case MSG_BEGIN:
+ progress_media.setVisibility(View.VISIBLE);
+ setGone();
+ break;
+ case MSG_FINISH:
+ progress_media.setVisibility(View.GONE);
+ setVisible();
+ break;
+ default:
+ break;
}
}
};
@@ -79,11 +93,24 @@ public class MediaHandleActivity extends AppCompatActivity implements View.OnCli
}
private void initView() {
+ progress_media = (ProgressBar) findViewById(R.id.progress_media) ;
findViewById(R.id.btn_mux).setOnClickListener(this);
findViewById(R.id.btn_extract_audio).setOnClickListener(this);
findViewById(R.id.btn_extract_video).setOnClickListener(this);
}
+ private void setVisible() {
+ findViewById(R.id.btn_mux).setVisibility(View.VISIBLE);
+ findViewById(R.id.btn_extract_audio).setVisibility(View.VISIBLE);
+ findViewById(R.id.btn_extract_video).setVisibility(View.VISIBLE);
+ }
+
+ private void setGone() {
+ findViewById(R.id.btn_mux).setVisibility(View.GONE);
+ findViewById(R.id.btn_extract_audio).setVisibility(View.GONE);
+ findViewById(R.id.btn_extract_video).setVisibility(View.GONE);
+ }
+
@Override
public void onClick(View v) {
int handleType;
@@ -146,20 +173,16 @@ public class MediaHandleActivity extends AppCompatActivity implements View.OnCli
@Override
public void onBegin() {
Log.i(TAG, "handle media onBegin...");
+ mHandler.obtainMessage(MSG_BEGIN).sendToTarget();
}
@Override
public void onEnd(int result) {
Log.i(TAG, "handle media onEnd...");
if(isMux){
- mHandler.obtainMessage(100).sendToTarget();
+ mHandler.obtainMessage(MSG_MUX).sendToTarget();
}else {
- runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(MediaHandleActivity.this, "handle media finish...", Toast.LENGTH_SHORT).show();
- }
- });
+ mHandler.obtainMessage(MSG_FINISH).sendToTarget();
}
}
});
diff --git a/app/src/main/java/com/frank/ffmpeg/activity/VideoHandleActivity.java b/app/src/main/java/com/frank/ffmpeg/activity/VideoHandleActivity.java
index 0e570f8..f034c51 100644
--- a/app/src/main/java/com/frank/ffmpeg/activity/VideoHandleActivity.java
+++ b/app/src/main/java/com/frank/ffmpeg/activity/VideoHandleActivity.java
@@ -1,20 +1,228 @@
package com.frank.ffmpeg.activity;
+import android.annotation.SuppressLint;
import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
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.util.FFmpegUtil;
-/**
- * 使用ffmpeg进行视频处理
- * Created by frank on 2018/1/23.
- */
-public class VideoHandleActivity extends AppCompatActivity {
+import java.io.File;
+
+public class VideoHandleActivity extends AppCompatActivity implements View.OnClickListener{
+
+ 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
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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();
+ }
+ });
+ }
}
diff --git a/app/src/main/java/com/frank/ffmpeg/util/BitmapUtil.java b/app/src/main/java/com/frank/ffmpeg/util/BitmapUtil.java
new file mode 100644
index 0000000..7776cf0
--- /dev/null
+++ b/app/src/main/java/com/frank/ffmpeg/util/BitmapUtil.java
@@ -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();
+ }
+
+}
diff --git a/app/src/main/java/com/frank/ffmpeg/util/FFmpegUtil.java b/app/src/main/java/com/frank/ffmpeg/util/FFmpegUtil.java
index 9e69292..b904748 100644
--- a/app/src/main/java/com/frank/ffmpeg/util/FFmpegUtil.java
+++ b/app/src/main/java/com/frank/ffmpeg/util/FFmpegUtil.java
@@ -1,9 +1,10 @@
package com.frank.ffmpeg.util;
import android.annotation.SuppressLint;
+import android.util.Log;
/**
- * ffmpeg工具:拼接命令行处理音频
+ * ffmpeg工具:拼接命令行处理音视频
* Created by frank on 2018/1/23.
*/
@@ -75,7 +76,7 @@ public class FFmpegUtil {
@SuppressLint("DefaultLocale")
public static String[] mediaMux(String videoFile, String audioFile, int duration, String muxFile){
//-t:时长 如果忽略音视频时长,则把"-t %d"去掉
- String mixAudioCmd = "ffmpeg -i %s -i %s -t %d -acodec copy %s";
+ String mixAudioCmd = "ffmpeg -i %s -i %s -t %d %s";
mixAudioCmd = String.format(mixAudioCmd, videoFile, audioFile, duration, muxFile);
return mixAudioCmd.split(" ");//以空格分割为字符串数组
}
@@ -106,4 +107,108 @@ public class FFmpegUtil {
return mixAudioCmd.split(" ");//以空格分割为字符串数组
}
+
+ /**
+ * 使用ffmpeg命令行进行视频转码
+ * @param srcFile 源文件
+ * @param targetFile 目标文件(后缀指定转码格式)
+ * @return 转码后的文件
+ */
+ public static String[] transformVideo(String srcFile, String targetFile){
+// String transformVideoCmd = "ffmpeg -i %s -r 25 -b 200 -s 1080x720 %s";
+ String transformVideoCmd = "ffmpeg -i %s %s";
+ transformVideoCmd = String.format(transformVideoCmd, srcFile, targetFile);
+ return transformVideoCmd.split(" ");//以空格分割为字符串数组
+ }
+
+ /**
+ * 使用ffmpeg命令行进行视频剪切
+ * @param srcFile 源文件
+ * @param startTime 剪切的开始时间(单位为秒)
+ * @param duration 剪切时长(单位为秒)
+ * @param targetFile 目标文件
+ * @return 剪切后的文件
+ */
+ @SuppressLint("DefaultLocale")
+ public static String[] cutVideo(String srcFile, int startTime, int duration, String targetFile){
+ String cutVideoCmd = "ffmpeg -i %s -ss %d -t %d %s";
+ cutVideoCmd = String.format(cutVideoCmd, srcFile, startTime, duration, targetFile);
+ return cutVideoCmd.split(" ");//以空格分割为字符串数组
+ }
+
+ /**
+ * 使用ffmpeg命令行进行视频截图
+ * @param srcFile 源文件
+ * @param size 图片尺寸大小
+ * @param targetFile 目标文件
+ * @return 截图后的文件
+ */
+ public static String[] screenShot(String srcFile, String size, String targetFile){
+ String screenShotCmd = "ffmpeg -i %s -f image2 -t 0.001 -s %s %s";
+ screenShotCmd = String.format(screenShotCmd, srcFile, size, targetFile);
+ return screenShotCmd.split(" ");//以空格分割为字符串数组
+ }
+
+ /**
+ * 使用ffmpeg命令行给视频添加水印
+ * @param srcFile 源文件
+ * @param waterMark 水印文件路径
+ * @param targetFile 目标文件
+ * @return 添加水印后的文件
+ */
+ public static String[] addWaterMark(String srcFile, String waterMark, String targetFile){
+ String waterMarkCmd = "ffmpeg -i %s -i %s -filter_complex overlay=0:0 %s";
+ waterMarkCmd = String.format(waterMarkCmd, srcFile, waterMark, targetFile);
+ return waterMarkCmd.split(" ");//以空格分割为字符串数组
+ }
+
+ /**
+ * 使用ffmpeg命令行进行视频转成Gif动图
+ * @param srcFile 源文件
+ * @param startTime 开始时间
+ * @param duration 截取时长
+ * @param targetFile 目标文件
+ * @return Gif文件
+ */
+ @SuppressLint("DefaultLocale")
+ public static String[] generateGif(String srcFile, int startTime, int duration, String targetFile){
+ //String screenShotCmd = "ffmpeg -i %s -vframes %d -f gif %s";
+ String screenShotCmd = "ffmpeg -i %s -ss %d -t %d -s 320x240 -f gif %s";
+ screenShotCmd = String.format(screenShotCmd, srcFile, startTime, duration, targetFile);
+ return screenShotCmd.split(" ");//以空格分割为字符串数组
+ }
+
+ /**
+ * 使用ffmpeg命令行进行屏幕录制
+ * @param size 视频尺寸大小
+ * @param recordTime 录屏时间
+ * @param targetFile 目标文件
+ * @return 屏幕录制文件
+ */
+ @SuppressLint("DefaultLocale")
+ public static String[] screenRecord(String size, int recordTime, String targetFile){
+ //-vd x11:0,0 指录制所使用的偏移为 x=0 和 y=0
+ //String screenRecordCmd = "ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -vd x11:0,0 -s %s %s";
+ String screenRecordCmd = "ffmpeg -vcodec mpeg4 -b 1000 -r 10 -g 300 -vd x11:0,0 -s %s -t %d %s";
+ screenRecordCmd = String.format(screenRecordCmd, size, recordTime, targetFile);
+ Log.i("VideoHandleActivity", "screenRecordCmd=" + screenRecordCmd);
+ return screenRecordCmd.split(" ");//以空格分割为字符串数组
+ }
+
+ /**
+ * 使用ffmpeg命令行进行图片合成视频
+ * @param srcFile 源文件
+ * @param targetFile 目标文件(mpg格式)
+ * @return 合成的视频文件
+ */
+ @SuppressLint("DefaultLocale")
+ public static String[] pictureToVideo(String srcFile, String targetFile){
+ //-f image2:代表使用image2格式,需要放在输入文件前面
+ String combineVideo = "ffmpeg -f image2 -r 1 -i %simg#d.jpg -vcodec mpeg4 %s";
+ combineVideo = String.format(combineVideo, srcFile, targetFile);
+ combineVideo = combineVideo.replace("#", "%");
+ Log.i("VideoHandleActivity", "combineVideo=" + combineVideo);
+ return combineVideo.split(" ");//以空格分割为字符串数组
+ }
+
}
diff --git a/app/src/main/res/layout/activity_audio_handle.xml b/app/src/main/res/layout/activity_audio_handle.xml
index 9783ad2..5565d6d 100644
--- a/app/src/main/res/layout/activity_audio_handle.xml
+++ b/app/src/main/res/layout/activity_audio_handle.xml
@@ -41,4 +41,11 @@
android:layout_marginTop="10dp"
android:layout_centerHorizontal="true"/>
+
+
diff --git a/app/src/main/res/layout/activity_media_handle.xml b/app/src/main/res/layout/activity_media_handle.xml
index 57d7a07..a886fa7 100644
--- a/app/src/main/res/layout/activity_media_handle.xml
+++ b/app/src/main/res/layout/activity_media_handle.xml
@@ -31,4 +31,11 @@
android:layout_centerHorizontal="true"
android:layout_below="@+id/btn_extract_audio"/>
+
+
diff --git a/app/src/main/res/layout/activity_video_handle.xml b/app/src/main/res/layout/activity_video_handle.xml
index d526645..c32a039 100644
--- a/app/src/main/res/layout/activity_video_handle.xml
+++ b/app/src/main/res/layout/activity_video_handle.xml
@@ -5,4 +5,84 @@
android:layout_height="match_parent"
tools:context="com.frank.ffmpeg.activity.VideoHandleActivity">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 2d8cd2f..65caa62 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -15,11 +15,12 @@
视频剪切
视频拼接
- 视频文字水印
- 视频图片水印
+ 视频水印
视频转Gif
视频转码
视频截图
+ 屏幕录制
+ 图片合成视频
视频抽帧
视频局部放大