I have got FFmpeg compiled (libffmpeg.so) on Android. Now I have to build either an application like RockPlayer or use existing Android multimedia framework to invoke FFmpeg along with video playing.
Do you have steps / procedures / code / example on integrating FFmpeg on Android / StageFright?
Can you please guide me on how can I use this library for multimedia
playback?
I already did rendering, mixing.
compile 'com.writingminds:FFmpegAndroid:0.3.2' add this to gradle
Add this inside onCreate :
ffmpeg = FFmpeg.getInstance(this.getApplicationContext());
(Declare FFmpeg ffmpeg; first)
Load library : loadFFMpegBinary();
Code to add audio to video using ffmpeg:
call function using execFFmpegBinaryShortest(null);
**
private void execFFmpegBinaryShortest(final String[] command) {
final File outputFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/videoaudiomerger/"+"Vid"+"output"+i1+".mp4");
String[] cmd = new String[]{"-i", selectedVideoPath,"-i",audiopath,"-map","1:a","-map","0:v","-codec","copy","-shortest",outputFile.getPath()};
try {
ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
#Override
public void onFailure(String s) {
System.out.println("on failure----"+s);
}
#Override
public void onSuccess(String s) {
System.out.println("on success-----"+s);
}
#Override
public void onProgress(String s) {
//Log.d(TAG, "Started command : ffmpeg "+command);
System.out.println("Started---"+s);
}
#Override
public void onStart() {
//Log.d(TAG, "Started command : ffmpeg " + command);
System.out.println("Start----");
}
#Override
public void onFinish() {
System.out.println("Finish-----");
}
});
} catch (FFmpegCommandAlreadyRunningException e) {
// do nothing for now
System.out.println("exceptio :::"+e.getMessage());
}
}
**
Download ffmpeg from here: http://bambuser.com/opensource. It contains scripts to build ffmpeg for android.
Modify build.sh. Replace "com.bambuser.broadcaster" with your package name. You also need to set the ffmpeg flags to enable to codecs you're interested in.
Run build.sh, and copy the build/ffmpeg directory into your apps jni/lib directory.
Use fasaxc's makefile from the SO post.
Create a native.c file in your jni directory and a java wrapper. To start with you can model it after hello-jni in NDK samples (/samples/hello-jni).
Include headers in your native.c file like this: #include "libavcodec/avcodec.h". And call the functions you need: avcodec_register_all(), etc...
Include the native libraries in your root activity by adding: static { System.loadLibraries(""); }
Related
I have MainClass
public class MainClass extends Application {
#Override
public void start(Stage primaryStage) {
try{
Image img = new Image(getClass().getResourceAsStream(".\\build\\resources\\main\\img\\h1.jpg"));
System.out.println("ok");
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
}
public static void main(String[] args) {
launch(args);
}
}
and my image is in \build\resources\main\img\h1.jpg directory
my project files:
When I run project it gives Input stream must not be null exception.
Resource paths are not separated by \ Furthermore they start at the resource root. In this case the path "/img/h1.jpg" should do the trick assuming your IDE properly includes the resources in the classpath at runtime.
getResource(AsStream) does not access the data via file path; The data may not be available as file at all, but as entry in a JAR file. If you need to refer to a file that is not included in the classpath, use File's functionality to convert to a URI or use a FileInputStream:
new Image(new File(".\\build\\resources\\main\\img\\h1.jpg").toURI().toString())
So I'm trying to come up with sed to find all code that matches below between the { and the } for each variable below, however I want to exclude the search that includes any of the lines that have # (present in any part of the line). Then I want the sed script to copy the matched lines to under the "libraries {" of the expected output and then add a # At the end of the name of the first line copies for each match when copying.
Original code to find a match/copy:
bundle {
path /system/lib/soundfx/libbundlewrapper.so
}
#positive {
#path /system/lib/soundfx/libpositive.so
#}
reverb {
path /system/lib/soundfx/libreverbwrapper.so
}
Expected output:
libraries {
bundle {#
path /system/lib/soundfx/libbundlewrapper.so
}
reverb {#
path /system/lib/soundfx/libreverbwrapper.so
}
proxy {
path /system/lib/soundfx/libeffectproxy.so
}
jdsp {
path /system/lib/soundfx/libjamesdsp.so
}
Then I want to do the same thing with below, but it's more complicated because I also need it to match and copy both of the two below (they all have "library" and "uuid", but only some have hw and sw").
Original code for match/copy:
jamesdsp {
library jdsp
uuid f27317f4-c984-4de6-9a90-545759495bf2
}
sa3d {
library proxy
uuid 1c91fca0-664a-11e4-b8c2-0002a5d5c51b
libsw {
library myspace
uuid 3462a6e0-655a-11e4-8b67-0002a5d5c51b
}
libhw {
library offload
uuid c7a84e61-eebe-4fcc-bc53-efcb841b4625
}
}
#downmix {
#library downmix
#uuid 93f04452-e4fe-41cc-91f9-e475b6d1d69f
#}
visualizer {
library visualizer
uuid d069d9e0-8329-11df-9168-0002a5d5c51b
}
Expected output:
effects {
jamesdsp {#
library jdsp
uuid f27317f4-c984-4de6-9a90-545759495bf2
}
sa3d {#
library proxy
uuid 1c91fca0-664a-11e4-b8c2-0002a5d5c51b
libsw {
library myspace
uuid 3462a6e0-655a-11e4-8b67-0002a5d5c51b
}
libhw {
library offload
uuid c7a84e61-eebe-4fcc-bc53-efcb841b4625
}
}
visualizer {#
library visualizer
uuid d069d9e0-8329-11df-9168-0002a5d5c51b
}
dax {
library dax
uuid 9d4921da-8225-4f29-aefa-6e6f69726861
}
Keep in mind the above code needs to be placed under "effects {".
Your source files have Tcl syntax, so if we execute them as Tcl code (with an appriopriate "unknown procedure" handler), we're good. I have your first sample as "file1.dat" and the second as "file2.dat"
$ cat process.tcl
rename unknown __tcl_unknown
proc unknown {cmd body} {
puts "$cmd {#$body}"
}
lassign $argv filename prefix suffix
puts $prefix
source $filename
puts $suffix
Then
$ tclsh process.tcl file1.dat "libraries {" " proxy {
path /system/lib/soundfx/libeffectproxy.so
}
jdsp {
path /system/lib/soundfx/libjamesdsp.so
}"
libraries {
bundle {#
path /system/lib/soundfx/libbundlewrapper.so
}
reverb {#
path /system/lib/soundfx/libreverbwrapper.so
}
proxy {
path /system/lib/soundfx/libeffectproxy.so
}
jdsp {
path /system/lib/soundfx/libjamesdsp.so
}
and
$ tclsh process.tcl file2.dat "effects {" " dax {
library dax
uuid 9d4921da-8225-4f29-aefa-6e6f69726861
}"
effects {
jamesdsp {#
library jdsp
uuid f27317f4-c984-4de6-9a90-545759495bf2
}
sa3d {#
library proxy
uuid 1c91fca0-664a-11e4-b8c2-0002a5d5c51b
libsw {
library myspace
uuid 3462a6e0-655a-11e4-8b67-0002a5d5c51b
}
libhw {
library offload
uuid c7a84e61-eebe-4fcc-bc53-efcb841b4625
}
}
visualizer {#
library visualizer
uuid d069d9e0-8329-11df-9168-0002a5d5c51b
}
dax {
library dax
uuid 9d4921da-8225-4f29-aefa-6e6f69726861
}
It doesn't give the indentation you want. Is that a deal breaker?
I want to develop an android application which will convert file of all video formats to file of all audio formats . And the question - what is the best way to decode file of video formats to accomplish my task?
If you mean extract the audio track/stream from a video and save it separately, then ffmpeg will allow you do this.
There are a number of ways to use ffmpeg in Android - using a wrapper is the way I find most convenient as it will allow you use the standard command line syntax.
The following wrapper is a popular one for ffmpeg on Android:
https://github.com/WritingMinds/ffmpeg-android-java
and this ffmpeg syntax will allow you extract audio from a video file (mp4 in this case):
ffmpeg -i input.mp4 -c:a copy -vn -sn output.m4a
Using this with the above wrapper, leveraging the examples refereed to on their site, you would use the following code:
FFmpeg ffmpeg = FFmpeg.getInstance(context);
try {
//Set the ffmpeg syntax you want to execute
cmd = "-i input.mp4 -c:a copy -vn -sn output.m4a";
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() {}
});
} catch (FFmpegCommandAlreadyRunningException e) {
// Handle if FFmpeg is already running
}
I got the Gaurdian Project FFMPEG android java from the following link
https://github.com/guardianproject/android-ffmpeg-java
Is there any good documents available to use the library for code. Its difficult to use without documentation. Plz help me.
I managed to get it work.
First, download the guardian project ffmpeg library project:
Then import it in eclipse. (no need to follow their Build Procedure, with the NDK just import their project in eclipse directly)
Then right click on your Main project (not the library project) -> Properties -> Android -> Library -> Add
Then, use it this way :
File fileTmp = context.getActivity().getCacheDir();
File fileAppRoot = new File(context.getActivity().getApplicationInfo().dataDir);
FfmpegController fc = new FfmpegController(fileTmp, fileAppRoot);
final Clip out = new Clip("compiled.mp4");
fc.concatAndTrimFilesMP4Stream(videos, out, true, false, new ShellUtils.ShellCallback() {
#Override
public void shellOut(String shellLine) {
System.out.println("MIX> " + shellLine);
}
#Override
public void processComplete(int exitValue) {
if (exitValue != 0) {
System.err.println("concat non-zero exit: " + exitValue);
Log.d("ffmpeg","Compilation error. FFmpeg failed");
} else {
if(new File(out.path).exists()) {
Log.d("ffmpeg","Success file:"+out.path);
}
}
}
});
With an ArrayList<Clip> of videos you want to concatenate.
I just have an annoying problem with jni when i compile the native method in java class with javah to generate JNI header files.
If the class has used 3rd-party package, For example: org.opencv.core.Mat, then the javah will show the error that can't find the org.opencv.core.Mat class.
The OpenCV sample code as below:
package org.opencv.samples.fd;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
public class DetectionBasedTracker
{
public DetectionBasedTracker(String cascadeName, int minFaceSize) {
mNativeObj = nativeCreateObject(cascadeName, minFaceSize);
}
public void start() {
nativeStart(mNativeObj);
}
public void stop() {
nativeStop(mNativeObj);
}
public void setMinFaceSize(int size) {
nativeSetFaceSize(mNativeObj, size);
}
public void detect(Mat imageGray, MatOfRect faces) {
nativeDetect(mNativeObj, imageGray.getNativeObjAddr(), faces.getNativeObjAddr());
}
public void release() {
nativeDestroyObject(mNativeObj);
mNativeObj = 0;
}
private long mNativeObj = 0;
private static native long nativeCreateObject(String cascadeName, int minFaceSize);
private static native void nativeDestroyObject(long thiz);
private static native void nativeStart(long thiz);
private static native void nativeStop(long thiz);
private static native void nativeSetFaceSize(long thiz, int size);
private static native void nativeDetect(long thiz, long inputImage, long faces);
}
First, I used the command
javah -classpath bin/classes -bootclasspath (the directory of android.jar) -d jni (packageName + ClassName) , shows the error "can't find the org.opencv.core.Mat
Then I modified the command to
javah - classpath bin/classes - bootclasspath (the dir of android.jar) ; (the dir of the opencv lib jar) -d jni ..." ", this time it shows error
Exception
Exception in thread "main" java.lang.IllegalArgumentException: Not a valid class
name: E:\Computer_Language\Java\soft_android\OpenCV-2.4.3-rc-android-sdk\OpenCV
-2.4.3-rc-android-sdk\sdk\java\bin\opencv library - 2.4.3.jar
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:177)
at com.sun.tools.javac.api.JavacTool.getTask(JavacTool.java:68)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:509)
at com.sun.tools.javah.JavahTask.run(JavahTask.java:335)
at com.sun.tools.javah.Main.main(Main.java:46)
I think, adding the directory of opencv lib in -bootclasspath is useful and neccessary. The error is because i just added two path in -bootclasspath or the format is something wrong?
Really confused.
Please give some help , thank u!
This is what I did:
1.Open Command line, type to the (project)/bin/classes:
2.type: javah -classpath (opencv4android sdk path)/java/bin/classes:(your project location)/bin/classes -jni (your java class file that contains the native library interfaces)
In my project. I did:
javah -classpath /home/zijun/Dev/adt/OpencvAndroid/sdk/java/bin/classes:/home/zijun/workspace/LocTM/bin/classes -jni com.brainport.loctm.TMatching
That works on Linux Ubuntu 12.04.02 64bit OS
I encountered the same problem too,it cost me half day.I just copy DetectionBasedTracker.java to my poject.I use Android Studio.When I use ExternalTools>javah to generate .h files,the console print cant find org.opencv.core.Mat.copying mat.java & matofRect.java to the directory DetectionBasedTracker.java exists just cause more java class cant be find.finally,I find this problem was caused by the import * clause in java file.and we seldom use java class in native method we defined.so I cut these java method and got this:
package cn.ntu.tonguefur.nativemethod;
public class DetectionBasedTracker{
private static native long nativeCreateObject(String cascadeName,int minFaceSize);
//Other native methods
private static native void nativeDetect(long thiz,long inputImage,long faces);
}
Now you can freely use javah command to generate .h
file.After that,add java methods and import packages you need.