private String defaultPath = Environment.getExternalStorageDirectory().getAbsolutePath();
private Handler mHandler = new MyHandler(this);
private class MyHandler extends Handler {
private final WeakReference<MainActivity> mActivity;
public MyHandler(MainActivity activity) {
mActivity = new WeakReference<>(activity);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (mActivity.get() == null) {
return;
}
switch (msg.what) {
case ImageSaveVideo.START_RECORD:
Log.d(TAG, "正在录制...." + msg.obj);
break;
case ImageSaveVideo.FINISH_RECORD:
Log.d(TAG, "录制完成...." + msg.obj);
break;
}
}
}
/**
* 图片合成视频
*/
private void startImageToVideo() {
String newFileName = "test_" + System.currentTimeMillis() + ".mp4";//视频名称
createDir(defaultPath + "/temporaryImg");
String tempFilePath = defaultPath + "/temporaryImg" + File.separator;//临时文件
createDir(defaultPath + "/saveVideo");
String savePath = defaultPath + "saveVideo/" + newFileName;//保存路径
ImageSaveVideo.imageToMp4(mHandler, tempFilePath, savePath, 15, 60);// 临时文件路径(需要合成视频的多张图片)
}
/**
* 创建目录
*
* @param defaultPath
*/
private void createDir(String defaultPath) {
File mFile = new File(defaultPath);
if (!mFile.exists()) {
mFile.mkdir();
}
}
public class ImageSaveVideo {
private static final String TAG = "wufeng_ImageSaveVideo";
private static final String IMAGE_TYPE = ".jpg";//图片类型
private static boolean isRunning = false;//图片转视频状态
public static final int START_RECORD = 600;//开始录制
public static final int FINISH_RECORD = 601;//录制完成
/**
* @param sourcePath :临时文件
* @param savePath :视频保存路径
* @param frameRate :帧率
* @param totalNum :文件下有多少张图片
*/
public static void imageToMp4(Handler mHandler, String sourcePath, final String savePath, final int frameRate, int totalNum) {
new Thread() {
@Override
public void run() {
isRunning = true;
Log.d(TAG, "开始将图片转成视频 frameRate=" + frameRate + " 临时文件路径:" + sourcePath);
try {
Bitmap testBitmap = BitmapFactory.decodeFile(sourcePath + "0" + IMAGE_TYPE);
//创建一个记录者
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(savePath, testBitmap.getWidth(), testBitmap.getHeight());
// 设置视频格式
recorder.setFormat("mp4");
//设置编码格式
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setInterleaved(true);
//零延迟
// recorder.setVideoOption("tune","zerolatency");
// ultrafast(终极快)提供最少的压缩(低编码器CPU)和最大的视频流大小 ("true", "zerolatency")降低编码延迟
recorder.setVideoOption("preset", "ultrafast");
// 录像帧率
recorder.setFrameRate(frameRate);
// 记录开始
recorder.start();
int index = 0;
while (isRunning && index < totalNum) {
// 获取图片--->图片格式为0.jpg,1.jpg....
opencv_core.IplImage image = opencv_highgui.cvLoadImage(sourcePath + index + IMAGE_TYPE);
recorder.record(image);
opencv_core.cvReleaseImage(image);//释放内存:注意,经过验证,这一条要加上,否则多次合成会内存溢出
index++;
Log.d(TAG, "正在录制...." + index);
sendMessageByHandler(mHandler, START_RECORD, index);
}
Log.d(TAG, "录制完成...." + savePath);
sendMessageByHandler(mHandler, FINISH_RECORD, totalNum);
// 录制结束
recorder.stop();
recorder.release();
isRunning = false;
} catch (FrameRecorder.Exception e) {
e.printStackTrace();
}
}
}.start();
}
/**
* 发送数据
*
* @param mHandler
* @param typeWhat
* @param num
*/
private static void sendMessageByHandler(Handler mHandler, int typeWhat, int num) {
Message message = Message.obtain();
message.what = typeWhat;
message.obj = num;
mHandler.sendMessage(message);
}
}
代码下载链接:https://download.csdn.net/download/qq_22985533/85110683
图片合并成视频
于 2022-04-11 15:56:11 首次发布