i am trying add image over a video using ffmpeg lib. it show
[NULL # 0xb6dab000] Unable to find a suitable output format for
'ffmpeg '
ffmpeg : Invalid argument
String addimg[]={"ffmpeg", "-i", inputpath,"-i", imagepath ,"\"" +"-filter_complex", "[0:v][1:v] overlay=25:25:enable='between(t,0,10)'" ,"\"" +"-pix_fmt yuv420p", "-c:a copy","\"" +output};
LoadFFmpegLibrary
public void LoadFFmpegLibrary()
{
if(ffmpeg==null)
{
ffmpeg = FFmpeg.getInstance(MainActivity.this);
try {
ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
#Override
public void onStart() {
Log.e("ffmpef","Start to load");
}
#Override
public void onFailure() {
Log.e("ffmpef","failed to load");
}
#Override
public void onSuccess() {
Log.e("ffmpef","load Successfully");
ExcuteFfmpefLibrabry(addimg);
}
#Override
public void onFinish() {}
});
} catch (FFmpegNotSupportedException e) {
// Handle if FFmpeg is not supported by device
Log.e("ffmpef",e.toString());
}
}
}
public void ExcuteFfmpefLibrabry(String command[])
{
ffmpeg = FFmpeg.getInstance(MainActivity.this);
try {
// to execute "ffmpeg -version" command you just need to pass "-version"
ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
#Override
public void onStart() {
Log.e("ffmpef","Exaction Start");
}
#Override
public void onProgress(String message) {}
#Override
public void onFailure(String message) {
Log.e("ffmpef","failed to Excute Command");
Log.e("ok",message);
}
#Override
public void onSuccess(String message) {
Log.e("ffmpef","Video Edited Successfully");
Log.e("ok",message);
}
#Override
public void onFinish() {
}
});
} catch (FFmpegCommandAlreadyRunningException e) {
Log.e("ffmpef",e.toString());
}
}
I Have seen your Code and get to know that you are using Writing minds For FFMPEG in Android Right?
and i your erro also indicate that ffmpeg is invalid argumnet means ffmpeg is not found in FFMPEG
when you pass commands to writing mind build
for example :
you pass command like : String command[]={"ffmpeg","-i",inputpath,outputpath};
then ffmpeg execute below code::-- ffmpeg ffmpeg -i inputpath outputpath
so ffmpef cant find argument named ffmpeg in thier build
so change you command
from
String addimg[]={"ffmpeg", "-i", inputpath,"-i", imagepath ,"\"" +"-filter_complex", "[0:v][1:v] overlay=25:25:enable='between(t,0,10)'" ,"\"" +"-pix_fmt yuv420p", "-c:a copy","\"" +output};
to
String addimg[]={"-i", inputpath,"-i", imagepath ,"-filter_complex", "[0:v][1:v] overlay=25:25:enable='between(t,0,10)'" ,"-pix_fmt yuv420p", "-c:a copy",output};
Related
i am using ffmpeg to create video from images and i have 2 image store in my sd card but when i am runing code it takes too long to execute or sometimes its shows only executing..my question is how to increase speed and check if there is anything wrong in my command
String cmd[]={ "-r" ,"1/5", "-i", inputputimg, "-strict",
"experimental", "-vcodec" ,"libx264" ,"-preset" ,"ultrafast" ,"-crf"
,"30",output};
String
inputputimg="/storage/emulated/0/FestiveApp/temp/img%02d.jpeg";
public void ImageCommand(String command[])
{
ffmpeg = FFmpeg.getInstance(MainActivity2.this);
try {
// to execute "ffmpeg -version" command you just need to pass "-version"
ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
#Override
public void onStart() {
Log.e("ffmpeg","Exaction Start");
}
#Override
public void onProgress(String message) {
}
#Override
public void onFailure(String message) {
imageprogressDialog.dismiss();
Log.e("ok",message);
}
#Override
public void onSuccess(String message) {
imageprogressDialog.dismiss();
Toast.makeText(MainActivity2.this,"success",Toast.LENGTH_SHORT).show();
}
#Override
public void onFinish() {
imageprogressDialog.dismiss();
Log.e("ffmpeg","Exaction Start");
}
});
} catch (FFmpegCommandAlreadyRunningException e) {
imageprogressDialog.dismiss();
Log.e("ffmpeg",e.toString());
}
}
i want video should takes some sec to edit and also i trying to merge to video but it also takes same things
As I have understood, the only way to change FFmpeg volume is to do it throught a command line.
This is what should change the volume of the audio :
ffmpeg -i input.wav -filter:a "volume=1.5" output.wav
Now I have used FFmpeg with command line before and it looked like this and gave me no errors:
String[] cmd = { "-i" , pcmtowavTempFile.toString(), "-i", mp3towavTempFile.toString(), "-filter_complex", "amix=inputs=2:duration=first:dropout_transition=3", combinedwavTempFile.toString()};
ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
#Override
public void onSuccess(String message) {
super.onSuccess(message);
encodeWavToAAC();
}
#Override
public void onFailure(String message) {
super.onFailure(message);
onError(message);
}
});
But If I try to do it with audio volume in the same method, it just ignores it :
String[] cmd = { "-i" , pcmtowavTempFile.toString(), "-filter:a", "volume=1.3", pcmtowavTempFile.toString()};
ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
#Override
public void onSuccess(String message) {
super.onSuccess(message);
}
#Override
public void onFailure(String message) {
super.onFailure(message);
}
});
I get neither, no success or error message with the last volume change method.
Since the volume is there between " ", I tried adding this :
String[] cmd = { "-i" , pcmtowavTempFile.toString(), "-filter:a", "\"volume=1.3\"", pcmtowavTempFile.toString()};
But the app started crashing after adding this line.
Please try using this library instead with the same command. It uses the latest FFmpeg.
https://github.com/bravobit/FFmpeg-Android
FFmpeg ffmpeg = FFmpeg.getInstance(context);
if (ffmpeg.isSupported()) {
// to execute "ffmpeg -version" command you just need to pass "-version"
String[] cmd= {"-i", pcmtowavTempFile.toString(), "-af", "volume=1.3", pcmtowavTempFile.toString()};
ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
#Override
public void onStart() {}
#Override
public void onProgress(String message) {}
#Override
public void onFailure(String message) {}
#Override
public void onSuccess(String message) {}
#Override
public void onFinish() {}
});
} else {
// ffmpeg is not supported
}
The error here was that FFmpeg does NOT perform in-place editing which means that I can not overwrite the same File. I tried overwriting by adding command "-y" but that did not also work because of that same rule.
So the solution was to create a new File as output File.
While chaging playback speed of video (making video slow) following exception occurs using FFMPEG android java library.
[aac # 0x416c26f0] The encoder 'aac' is experimental but experimental codecs are not enabled, add '-strict -2' if you want to use it.
Here is a command to change playback of the speed
VideoIn = getInternalDirectoryPath() + "/Download/input.mp4";
VideoOut = getInternalDirectoryPath() + "/Download/output.mp4";
cmd = "-i "+VideoIn+" -vf setpts=2*PTS -strict -2 "+VideoOut;
adding -strict in command avoid encoder 'aac' not enable exception. You can follow this link to implement ffmpeg video commands.
Here is the complete sample code
public class TestFFMpegActivity {
private static String cmd,
private static FFmpeg ffmpeg;
private static Context mContext;
public static String getInternalDirectoryPath() {
return Environment.getExternalStorageDirectory().getAbsolutePath();
}
public static void initiateFFmpeg(Context context, String path) {
mContext = context;
ffmpeg = FFmpeg.getInstance(context);
VideoIn = getInternalDirectoryPath() + "/Download/input.mp4";
VideoOut = getInternalDirectoryPath() + "/Download/output.mp4";
cmd = "-i "+VideoIn+" -vf setpts=2*PTS -strict -2 "+VideoOut;
try {
ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
#Override
public void onStart() {
}
#Override
public void onFailure() {
}
#Override
public void onSuccess() {
}
#Override
public void onFinish() {
processVideo();
}
});
} catch (FFmpegNotSupportedException e) {
// Handle if FFmpeg is not supported by device
}
}
private static void processVideo(){
try {
ffmpeg.execute(cmd ,
new ExecuteBinaryResponseHandler() {
#Override
public void onStart() {
//for logcat
Log.w(null,"processing started");
}
#Override
public void onProgress(String message) {
//for logcat
Log.w(null, "onProgress");
}
#Override
public void onFailure(String message) {
Log.w(null, message.toString());
}
#Override
public void onSuccess(String message) {
Log.w(null, message.toString());
}
#Override
public void onFinish() {
}
});
} catch (FFmpegCommandAlreadyRunningException e) {
Toast.makeText(mContext, "Video processing failed due to exception", Toast.LENGTH_LONG).show();
// Handle if FFmpeg is already running
e.printStackTrace();
Log.w(null, e.toString());
}
}
}
I am processing video in android using FFMPEG android java library to change play back of speed. for 6 sec video to make it play back slow by 0.5 setpts , its taking more than 1 min.
Here is my code
public class TestFFMpegActivity {
private static String cmd,
private static FFmpeg ffmpeg;
private static Context mContext;
public static String getInternalDirectoryPath() {
return Environment.getExternalStorageDirectory().getAbsolutePath();
}
public static void initiateFFmpeg(Context context, String path) {
mContext = context;
ffmpeg = FFmpeg.getInstance(context);
VideoIn = getInternalDirectoryPath() + "/Download/input.mp4";
VideoOut = getInternalDirectoryPath() + "/Download/output.mp4";
cmd = "-i "+VideoIn+" -vf setpts=2*PTS -strict -2 "+VideoOut;
try {
ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
#Override
public void onStart() {
}
#Override
public void onFailure() {
}
#Override
public void onSuccess() {
}
#Override
public void onFinish() {
processVideo();
}
});
} catch (FFmpegNotSupportedException e) {
// Handle if FFmpeg is not supported by device
}
}
private static void processVideo(){
try {
ffmpeg.execute(cmd ,
new ExecuteBinaryResponseHandler() {
#Override
public void onStart() {
//for logcat
Log.w(null,"processing started");
}
#Override
public void onProgress(String message) {
//for logcat
Log.w(null, "onProgress");
}
#Override
public void onFailure(String message) {
Log.w(null, message.toString());
}
#Override
public void onSuccess(String message) {
Log.w(null, message.toString());
}
#Override
public void onFinish() {
}
});
} catch (FFmpegCommandAlreadyRunningException e) {
Toast.makeText(mContext, "Video processing failed due to exception", Toast.LENGTH_LONG).show();
// Handle if FFmpeg is already running
e.printStackTrace();
Log.w(null, e.toString());
}
}
}
This is the gradle build path for using above library
compile 'com.github.hiteshsondhi88.libffmpeg:FFmpegAndroid:0.2.5'
For changing playback command add in it parameter "-ultrafast".
Now cmd will be like
cmd= "-i " + VideoIn+ " -vf setpts=2*PTS -c:v libx264 -c:a aac -strict experimental -vcodec libx264 -preset ultrafast -b:a 128k " + VideoOut;
this parameter has magical effect on processing. The video processing time decreases from 1 min 6 sec to 13 secs with same environment.
On windows I could cut a video with below code with ffmpeg.exe
Can't use ffmpeg in android.
I used gradle to grab ffmpeg in my app.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.github.hiteshsondhi88.libffmpeg:FFmpegAndroid:0.2.5'
}
I have these lines in my method
VideoIn = getInternalDirectoryPath() + "/Download/Ab.mp4";
VideoOut = getInternalDirectoryPath() + "/Download/Ab1.mp4";
try {
ffmpeg.execute("ffmpeg -i " + VideoIn + " -ss 00:00:03 -c:v libx264 -crf 17 -t 00:00:5 " + VideoOut + " -y",null);
}
catch (FFmpegCommandAlreadyRunningException e) {
e.printStackTrace();
}
Shows this error: Error running exec(). Command: [/data/data/com.videoeditor.myname.myapp/files/ffmpeg, ffmpeg, -i, /storage/emulated/0/Download/Ab.mp4, -ss, 00:00:03, -c:v, libx264, -crf, 17, -t, 00:00:5, /storage/emulated/0/Download/Ab1.mp4, -y] Working Directory: null Environment: null
What's wrong with this method? Thanks for your help
Ok I found the answer:
There is no need for "ffmpeg" in cmd with this method of using ffmpeg
Simple video cut example:
/**
* Returns the path to internal storage ex:- /storage/emulated/0
*
* #return
*/
private String getInternalDirectoryPath() {
return Environment.getExternalStorageDirectory().getAbsolutePath();
}
VideoIn = getInternalDirectoryPath() + "/Download/Ab.mp4";
VideoOut = getInternalDirectoryPath() + "/Download/Ab1.mp4";
private void CutVideo(){
try {
ffmpeg.execute("-i "+VideoIn+" -ss 00:01:00 -to 00:02:00 -c copy "+VideoOut ,
new ExecuteBinaryResponseHandler() {
#Override
public void onStart() {
//for logcat
Log.w(null,"Cut started");
}
#Override
public void onProgress(String message) {
//for logcat
Log.w(null,message.toString());
}
#Override
public void onFailure(String message) {
Log.w(null,message.toString());
}
#Override
public void onSuccess(String message) {
Log.w(null,message.toString());
}
#Override
public void onFinish() {
Log.w(null,"Cutting video finished");
}
});
} catch (FFmpegCommandAlreadyRunningException e) {
// Handle if FFmpeg is already running
e.printStackTrace();
Log.w(null,e.toString());
}
}
Ok. Your problem is that you aren't loading the ffmpeg binary. You have to load it before executing the command. Try something like this:
private FFmpeg ffmpeg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FFmpeg ffmpeg = FFmpeg.getInstance(this);
try {
//Load the binary
ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
#Override
public void onStart() {}
#Override
public void onFailure() {}
#Override
public void onSuccess() {}
#Override
public void onFinish() {}
});
} catch (FFmpegNotSupportedException e) {
// Handle if FFmpeg is not supported by device
}
try {
// to execute "ffmpeg -version" command you just need to pass "-version"
// Now, you can execute your command here
ffmpeg.execute("ffmpeg -version", new ExecuteBinaryResponseHandler() {
#Override
public void onStart() {}
#Override
public void onProgress(String message) {}
#Override
public void onFailure(String message) {}
#Override
public void onSuccess(String message) {
Log.i("SUCCESS", message);
}
#Override
public void onFinish() {}
});
} catch (FFmpegCommandAlreadyRunningException e) {
// Handle if FFmpeg is already running
}
}
More info on http://hiteshsondhi88.github.io/ffmpeg-android-java/
Friends, just to mention that if your sdk version is equal or higher than 23 (Marshmelow), don't forget to check runtime permission for
android.permission.WRITE_EXTERNAL_STORAGE
that was my problem. everything was fine but logs didn't show onSuccess result.
android doc for runtime permission
You need to read process's error stream to figure out what is wrong:
InputStreamReader errReader = new InputStreamReader(process.getErrorStream());
BufferedReader bufReader = new BufferedReader(errReader);
while ((String line = bufReader.readLine()) != null) {
Log.d("MyApp", line);
}
But I suppose problem is in wrong argument for exec method, if you need to run both chmod and ffmpeg, you should probably use exec(String[] progArray, String[] envp)