Can anyone tell me how to combine images and generate a mp4 file in android and store the video file in sdCard?
Press ALT+PRINT SCREEN. Play the video and pause it at the point you want to take a still from it. Press PRINT SCREEN or ALT+PRINT SCREEN, depending on whether the video is playing full screen or in an active window.
Please check the below code
Make one file FfmpegController.java
public class FfmpegController {
private static Context mContext;
private static Utility mUtility;
private static String mFfmpegBinaryPath;
public FfmpegController(Context context) {
mContext = context;
mUtility = new Utility(context);
initFfmpeg();
}
private void initFfmpeg()
{
/*
Save the ffmpeg binary to app internal storage, so we can use it by executing java runtime command.
*/
mFfmpegBinaryPath = mContext.getApplicationContext().getFilesDir().getAbsolutePath() + "/ffmpeg";
if (Utility.isFileExsisted(mFfmpegBinaryPath))
return;
InputStream inputStream = mContext.getResources().openRawResource(R.raw.ffmpeg);
mUtility.saveFileToAppInternalStorage(inputStream, "ffmpeg");
Utility.excuteCommand(CommandHelper.commandChangeFilePermissionForExecuting(mFfmpegBinaryPath));
}
public void convertImageToVideo(String inputImgPath)
{
/*
Delete previous video.
*/
Log.e("Image Parth", "inputImgPath - "+inputImgPath);
if (Utility.isFileExsisted(pathOuputVideo()))
Utility.deleteFileAtPath(pathOuputVideo());
/*
Save the command into a shell script.
*/
saveShellCommandImg2VideoToAppDir(inputImgPath);
Utility.excuteCommand("sh" + " " + pathShellScriptImg2Video());
}
public String pathOuputVideo()
{
return mUtility.getPathOfAppInternalStorage() + "/out.mp4";
}
private String pathShellScriptImg2Video()
{
return mUtility.getPathOfAppInternalStorage() + "/img2video.sh";
}
private void saveShellCommandImg2VideoToAppDir(String inputImgPath)
{
String command = CommandHelper.commandConvertImgToVideo(mFfmpegBinaryPath, inputImgPath, pathOuputVideo());
InputStream is = new ByteArrayInputStream(command.getBytes());
mUtility.saveFileToAppInternalStorage(is, "img2video.sh");
}
}
Make another Java file Utility.java
public class Utility {
private final static String TAG = Utility.class.getName();
private static Context mContext;
public Utility(Context context) {
mContext = context;
}
public static String excuteCommand(String command)
{
try {
Log.d(TAG, "execute command : " + command);
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
process.waitFor();
Log.d(TAG, "command result: " + output.toString());
return output.toString();
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
} catch (InterruptedException e) {
Log.e(TAG, e.getMessage(), e);
}
return "";
}
public String getPathOfAppInternalStorage()
{
return mContext.getApplicationContext().getFilesDir().getAbsolutePath();
}
public void saveFileToAppInternalStorage(InputStream inputStream, String fileName)
{
File file = new File(getPathOfAppInternalStorage() + "/" + fileName);
if (file.exists())
{
Log.d(TAG, "SaveRawToAppDir Delete Exsisted File");
file.delete();
}
FileOutputStream outputStream;
try {
outputStream = mContext.openFileOutput(fileName, Context.MODE_PRIVATE);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0)
{
outputStream.write(buffer, 0, length);
}
outputStream.close();
inputStream.close();
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
}
public static boolean isFileExsisted(String filePath)
{
File file = new File(filePath);
return file.exists();
}
public static void deleteFileAtPath(String filePath)
{
File file = new File(filePath);
file.delete();
}
}
Make another file CommandHelper.java
public class CommandHelper {
public static String commandConvertImgToVideo(String ffmpegBinaryPath, String inputImgPath, String outputVideoPath) {
Log.e("ffmpegBinaryPath", "ffmpegBinaryPath - "+ffmpegBinaryPath);
Log.e("inputImgPath", "inputImgPath - "+inputImgPath);
Log.e("outputVideoPath", "outputVideoPath - "+outputVideoPath);
return ffmpegBinaryPath + " -r 1/1 -i " + inputImgPath + " -c:v libx264 -crf 23 -pix_fmt yuv420p -s 640x480 " + outputVideoPath;
}
public static String commandChangeFilePermissionForExecuting(String filePath) {
return "chmod 777 " + filePath;
}
}
When you want to execute code and make images to video please use below code.
AsyncTask asyncTask = new AsyncTask() {
ProgressDialog mProgressDialog;
@Override
protected void onPreExecute() {
/* mProgressDialog = new ProgressDialog(activity.this);
mProgressDialog.setMessage("Converting...");
mProgressDialog.setCancelable(false);
mProgressDialog.show();*/
Log.e("Video Process Start", "======================== Video Process Start ======================================");
}
@Override
protected Object doInBackground(Object... params) {
saveInputImgToAppInternalStorage();
/* for(int i = 1; i<11 ; i++){
mFfmpegController.convertImageToVideo(mUtility.getPathOfAppInternalStorage() + "/" + "Img"+i+".jpg");
}
*/
mFfmpegController.convertImageToVideo(mUtility.getPathOfAppInternalStorage() + "/" + "img%05d.jpg");
return null;
}
@Override
protected void onPostExecute(Object o) {
// mProgressDialog.dismiss();
Log.e("Video Process Complete", "======================== Video Process Complete ======================================");
Log.e("Video Path", "Path - "+mFfmpegController.pathOuputVideo());
Toast.makeText(activity.this, "Video Process Complete", Toast.LENGTH_LONG).show();
stopSelfResult(lateststartid);
Common.ScreenshotCounter = 0;
Common.ScreenshotTimerCounter = 0;
/*try {
copyFile(new FileInputStream(mFfmpegController.pathOuputVideo()), new FileOutputStream(Common.strPathForVideos));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
};
Please note:
Captured images must be in format like:
Img00001, Img00002 .......
Because FFMPEG code expects it this way.
Fo those who didn't find R.raw.ffmpeg : Go To : https://github.com/guardianproject/android-ffmpeg-java/blob/master/res/raw/ffmpeg
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With