B4A Library Ffmpeg Library for B4X with Inline JAVA Only

With ffmpeg library, you can work with ffmpeg by using command-line
It base this: https://github.com/bravobit/FFmpeg-Android

You can convert any media to other format, edit video and audio,.....

Because it use command to control ffmpeg so you should test on windows or mac firsts, if it works you can test it on android

Note that: Size of aar is large, but you can remove x86 library to reduce size (1/2 only)


very easily to use:
download ffmeg library for android http://maven.endeavourhealth.net:8081/artifactory/libs-release/nl/bravobit/android-ffmpeg/

i current use 1.1.6 : http://maven.endeavourhealth.net:80...android-ffmpeg/1.1.6/android-ffmpeg-1.1.6.aar

copy file aar to your Additional Library

Add this line to your project version 1.1.6 you can change to 1.1.5 or 1.1.7,...)

B4X:
#AdditionalJar: android-ffmpeg-1.1.6.aar

Add Inline-JAVA code to your project (You can modify my demo project for faster)


1. Check device if it support ffmpeg by sub checkdevicesupport
2. Command is a list:

B4X:
Dim command_to_run As List
command_to_run.Initialize
command_to_run.AddAll( Array As String("-y","-i",inputfile,outputfile))

It same command on Windows or other platform : ffmpeg -y -i inputfile outputfile
So you will be easily to test and command to work

Has some events to check progress and complete.

because my bad English and my code is very badly now, i dont have time to pretty it, hope member b4A will find it to usefull for you!
Thank you!
I hope that somebody can remake it to perfect library for every member B4X can has a library for apps
And hope that has a wrapper for this libray for IOS too!
Thank you all!
 

Attachments

  • ffmpegdemo.zip
    9.9 KB · Views: 465

noeleon

Active Member
Licensed User
Thank you for sharing this.
Can you help fix this error

B4A Version: 9.01.2
Java Version: 8
Parsing code. (0.00s)
Building folders structure. (0.03s)
Compiling code. (0.01s)
Compiling layouts code. (0.00s)
Organizing libraries. (0.00s)
Generating R file. (0.00s)
Compiling generated Java code. Error
javac 1.8.0_102
src\b4a\ffmpeg\share4rum\main.java:506: error: cannot find symbol
public void runcommandb4a(ArrayList<String> danhsachthamsotruyen,Context thamsocontext){
^
symbol: class Context
location: class main
1 error
 

noeleon

Active Member
Licensed User
i got it to work by adding
import android.content.Context;

modified the sub
B4X:
Sub run_command_b4a(lenh As List)
   Dim nt As JavaObject
   nt.RunMethod("runcommandb4a", Array As Object(lenh, nt.InitializeContext))
End Sub

and i removed the if-else in runcommandb4a
 

zhangke

Member
Licensed User
@noeleon
I also met this problem, please tell me the specific solution, thank you
1.png
 

noeleon

Active Member
Licensed User
i don't have my computer right now but try this code i edited according to my previous response to this thread. hope it works.

B4X:
#Region  Project Attributes 
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName: 
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes 
    #FullScreen: False
    #IncludeTitle: True
#End Region
#AdditionalJar: android-ffmpeg-1.1.6.aar
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub
'FFmpegAndroid-0.3.2.aar
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Private cmdrun As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("frm_main_ffmpeg")
    Log(checkdevicesupport)
    'khoitaolib
End Sub
Sub cmdrun_Click
    'run_command_b4a("-version")
    '-i filename.mp4 filename.mp3
    'run_command_b4a("-i /storage/emulated/0/1.mp4 /storage/emulated/0/199.mp3")
    '//String[] cmd = new String[]{"-i","/storage/emulated/0/step.mov","/storage/emulated/0/he.mp4"};
    
    Dim command_to_run As List
    command_to_run.Initialize
    Dim inputfile="/storage/emulated/0/step.mov" As String
    Dim outputfile="/storage/emulated/0/he.mp4"  As String
    'YOU NEED CHANGE HERE , DEMO IS MOV TO MP4
    
    command_to_run.AddAll( Array As String("-y","-i",inputfile,outputfile))
    
    run_command_b4a(command_to_run)
    'run_command_b4a("""-i"",""/storage/emulated/0/1.mp4"",""-vcodec"",""libx264"",""-preset"",""veryfast"",""-maxrate"",""500k"",""-bufsize"",""2500k"",""-vf"",""format=yuv420p"",""-g"",""60"",""-acodec"",""libmp3lame"",""-b:a"",""198k"",""-ar"",""44100"",""-f"",""flv"",""rtmp://a.rtmp.youtube.com/live2/7s5s-2rh2-0xwu-2079""")
    'run_command_b4a("-re -i ""/storage/emulated/0/1.mp4"" -vcodec libx264 -preset veryfast -maxrate 500k -bufsize 2500k -vf ""format=yuv420p"" -g 60 -acodec libmp3lame -b:a 198k -ar 44100 -f flv ""rtmp://a.rtmp.youtube.com/live2/7s5s-2rh2-0xwu-2079""")
    '-re -i "/storage/emulated/0/1.mp4" -vcodec libx264 -preset veryfast -maxrate 500k -bufsize 2500k -vf "format=yuv420p" -g 60 -acodec libmp3lame -b:a 198k -ar 44100 -f flv "rtmp://a.rtmp.youtube.com/live2/7s5s-2rh2-0xwu-2079"
End Sub
Sub Activity_Resume
    
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub checkdevicesupport As Boolean
    Dim nt As JavaObject
    nt.InitializeContext
    nt.RunMethod("checkdevicesupport", Null)
    Return nt.RunMethod("checkdevicesupport",Null)
End Sub

Sub run_command_b4a(lenh As List) 
Dim nt As JavaObject 
nt.RunMethod("runcommandb4a", Array As Object(lenh, nt.InitializeContext)) 
End Sub

Sub startffmpegb4a
    Log("startffmpegb4a")
End Sub
Sub returnduration(giatri As Double)
    Log(giatri)
End Sub

Sub currenttimevalue(giatri As Double)
    Log(giatri)
End Sub

Sub errornotice(giatri As String)
    Log(giatri)
End Sub



Sub successfunc(giatri As String)
    Log("Successfull convert!!!")
End Sub
Sub GetContext As JavaObject
    Return GetBA.GetField("context")
End Sub

Sub GetBA As JavaObject
    Dim jo As JavaObject
    Dim cls As String = Me
    cls = cls.SubString("class ".Length)
    jo.InitializeStatic(cls)
    Return jo.GetFieldJO("processBA")
End Sub

#If Java
import android.content.Context;
import android.util.Log;
import nl.bravobit.ffmpeg.ExecuteBinaryResponseHandler;
import nl.bravobit.ffmpeg.FFmpeg;
import anywheresoftware.b4a.keywords.Common;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
 double totalSecs=0;
 public Boolean checkdevicesupport(){
     if (FFmpeg.getInstance(this).isSupported()) {
         // ffmpeg is supported
        // processBA.raiseEventFromUI(null, "duochotro_log");
         return true;
     } else {
     // processBA.raiseEventFromUI(null, "khonghotro_log");
         return false;
         // ffmpeg is not supported
     }
 }
 
public void runcommandb4a(ArrayList<String> danhsachthamsotruyen,Context thamsocontext){
double hientaisec=0;
double phantram=0;


     
     
        FFmpeg ffmpeg = FFmpeg.getInstance(thamsocontext);
        // to execute "ffmpeg -version" command you just need to pass "-version"
        //String[] cmd = new String[]{"-i","/storage/emulated/0/step.mov","/storage/emulated/0/he.mp4"};
        //    String [] countries = list.toArray(new String[list.size()]);
//    String[] cmd = new String[]{"-re","-stream_loop","-1","-i","/storage/emulated/0/1.mp4","-vcodec","libx264","-preset","veryfast","-maxrate","500k","-bufsize","2500k","-vf","format=yuv420p","-g","60","-acodec","libmp3lame","-b:a","198k","-ar","44100","-f","flv","rtmp://a.rtmp.youtube.com/live2/7s5s-2rh2-0xwu-2079"};
        String[] cmd = danhsachthamsotruyen.toArray(new String[danhsachthamsotruyen.size()]);
        //-stream_loop -1
        ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {

            @Override
            public void onStart() {
//BA.Log("Bat dau");
processBA.raiseEventFromUI(null, "startffmpegb4a");
            }

            @Override
            public void onProgress(String message) {
            
             try{
            if (message.contains("Duration:")) {
         String dur;
         dur=message.substring(message.indexOf("Duration: ")+10,message.indexOf(", start:"));

         String[] hms = dur.split(":");
          totalSecs = Integer.parseInt(hms[0]) * 3600
                 + Integer.parseInt(hms[1]) *   60
                 + Double.parseDouble(hms[2]);
//BA.Log("Tong thoi gian" + String.valueOf(totalSecs));
processBA.raiseEventFromUI(null, "returnduration",totalSecs);
     }
     
              if (message.contains(" time=") && message.contains("frame=") && message.contains("speed=") && message.contains("fps=") ) {
//dang xu ly 
 String hientai;
         hientai=message.substring(message.indexOf(" time=")+6,message.indexOf(" bitrate"));

         String[] hms = hientai.split(":");
         double hientaisec = Integer.parseInt(hms[0]) * 3600
                 + Integer.parseInt(hms[1]) *   60
                 + Double.parseDouble(hms[2]);
    //BA.Log("Tong thoi gian la" + String.valueOf(totalSecs) );
    processBA.raiseEventFromUI(null, "currenttimevalue",hientaisec);             
//BA.Log("Thoi gian hien tai" + String.valueOf(hientaisec) );
//BA.Log("Phan tram la " + String.valueOf(hientaisec*100/totalSecs) );
//processBA.raiseEventFromUI(null, "currenttimevalue",hientaisec);    

     }
     }
     catch (Exception e)
{}
            
            //BA.Log(message.substring(message.indexOf("Duration: ")+1, message.lastIndexOf(", start:")));
        //    BA.Log("Dang xu ly" + message);
            
            }

            @Override
            public void onFailure(String message) {
            BA.Log(message);
            processBA.raiseEventFromUI(null, "errornotice",message);             
            }

            @Override
            public void onSuccess(String message) {
            processBA.raiseEventFromUI(null, "successfunc",message);             
            BA.Log(message);
            }

            @Override
            public void onFinish() {
            BA.Log("Hoan thanh!");
            //processBA.raiseEventFromUI(null, "finish",message);             
        //    BA.Log(message);
            }

        });

    }


#End If
 

noeleon

Active Member
Licensed User
I did not use a modified jar. Just the aar from the link above. Worked with version 1.1.7 too.
 

marcos_sa

Member
With ffmpeg library, you can work with ffmpeg by using command-line
It base this: https://github.com/bravobit/FFmpeg-Android

You can convert any media to other format, edit video and audio,.....

Because it use command to control ffmpeg so you should test on windows or mac firsts, if it works you can test it on android

Note that: Size of aar is large, but you can remove x86 library to reduce size (1/2 only)


very easily to use:
download ffmeg library for android http://maven.endeavourhealth.net:8081/artifactory/libs-release/nl/bravobit/android-ffmpeg/

i current use 1.1.6 : http://maven.endeavourhealth.net:80...android-ffmpeg/1.1.6/android-ffmpeg-1.1.6.aar

copy file aar to your Additional Library

Add this line to your project version 1.1.6 you can change to 1.1.5 or 1.1.7,...)

B4X:
#AdditionalJar: android-ffmpeg-1.1.6.aar

Add Inline-JAVA code to your project (You can modify my demo project for faster)


1. Check device if it support ffmpeg by sub checkdevicesupport
2. Command is a list:

B4X:
Dim command_to_run As List
command_to_run.Initialize
command_to_run.AddAll( Array As String("-y","-i",inputfile,outputfile))

It same command on Windows or other platform : ffmpeg -y -i inputfile outputfile
So you will be easily to test and command to work

Has some events to check progress and complete.

because my bad English and my code is very badly now, i dont have time to pretty it, hope member b4A will find it to usefull for you!
Thank you!
I hope that somebody can remake it to perfect library for every member B4X can has a library for apps
And hope that has a wrapper for this libray for IOS too!
Thank you all!
How can I can contact you for a quote? I have 2 software companies and currently I am in search for skilled programmers to develop a module capable of control (START/STOP) cameras and read data from a multiserial port in a RPi using B4J. My deadline is short, so no time for experiences.
 

mohmmad mustaf

New Member
i don't have my computer right now but try this code i edited according to my previous response to this thread. hope it works.

B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region
#AdditionalJar: android-ffmpeg-1.1.6.aar
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub
'FFmpegAndroid-0.3.2.aar
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Private cmdrun As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("frm_main_ffmpeg")
    Log(checkdevicesupport)
    'khoitaolib
End Sub
Sub cmdrun_Click
    'run_command_b4a("-version")
    '-i filename.mp4 filename.mp3
    'run_command_b4a("-i /storage/emulated/0/1.mp4 /storage/emulated/0/199.mp3")
    '//String[] cmd = new String[]{"-i","/storage/emulated/0/step.mov","/storage/emulated/0/he.mp4"};
   
    Dim command_to_run As List
    command_to_run.Initialize
    Dim inputfile="/storage/emulated/0/step.mov" As String
    Dim outputfile="/storage/emulated/0/he.mp4"  As String
    'YOU NEED CHANGE HERE , DEMO IS MOV TO MP4
   
    command_to_run.AddAll( Array As String("-y","-i",inputfile,outputfile))
   
    run_command_b4a(command_to_run)
    'run_command_b4a("""-i"",""/storage/emulated/0/1.mp4"",""-vcodec"",""libx264"",""-preset"",""veryfast"",""-maxrate"",""500k"",""-bufsize"",""2500k"",""-vf"",""format=yuv420p"",""-g"",""60"",""-acodec"",""libmp3lame"",""-b:a"",""198k"",""-ar"",""44100"",""-f"",""flv"",""rtmp://a.rtmp.youtube.com/live2/7s5s-2rh2-0xwu-2079""")
    'run_command_b4a("-re -i ""/storage/emulated/0/1.mp4"" -vcodec libx264 -preset veryfast -maxrate 500k -bufsize 2500k -vf ""format=yuv420p"" -g 60 -acodec libmp3lame -b:a 198k -ar 44100 -f flv ""rtmp://a.rtmp.youtube.com/live2/7s5s-2rh2-0xwu-2079""")
    '-re -i "/storage/emulated/0/1.mp4" -vcodec libx264 -preset veryfast -maxrate 500k -bufsize 2500k -vf "format=yuv420p" -g 60 -acodec libmp3lame -b:a 198k -ar 44100 -f flv "rtmp://a.rtmp.youtube.com/live2/7s5s-2rh2-0xwu-2079"
End Sub
Sub Activity_Resume
   
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub checkdevicesupport As Boolean
    Dim nt As JavaObject
    nt.InitializeContext
    nt.RunMethod("checkdevicesupport", Null)
    Return nt.RunMethod("checkdevicesupport",Null)
End Sub

Sub run_command_b4a(lenh As List)
Dim nt As JavaObject
nt.RunMethod("runcommandb4a", Array As Object(lenh, nt.InitializeContext))
End Sub

Sub startffmpegb4a
    Log("startffmpegb4a")
End Sub
Sub returnduration(giatri As Double)
    Log(giatri)
End Sub

Sub currenttimevalue(giatri As Double)
    Log(giatri)
End Sub

Sub errornotice(giatri As String)
    Log(giatri)
End Sub



Sub successfunc(giatri As String)
    Log("Successfull convert!!!")
End Sub
Sub GetContext As JavaObject
    Return GetBA.GetField("context")
End Sub

Sub GetBA As JavaObject
    Dim jo As JavaObject
    Dim cls As String = Me
    cls = cls.SubString("class ".Length)
    jo.InitializeStatic(cls)
    Return jo.GetFieldJO("processBA")
End Sub

#If Java
import android.content.Context;
import android.util.Log;
import nl.bravobit.ffmpeg.ExecuteBinaryResponseHandler;
import nl.bravobit.ffmpeg.FFmpeg;
import anywheresoftware.b4a.keywords.Common;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
double totalSecs=0;
public Boolean checkdevicesupport(){
     if (FFmpeg.getInstance(this).isSupported()) {
         // ffmpeg is supported
        // processBA.raiseEventFromUI(null, "duochotro_log");
         return true;
     } else {
     // processBA.raiseEventFromUI(null, "khonghotro_log");
         return false;
         // ffmpeg is not supported
     }
}

public void runcommandb4a(ArrayList<String> danhsachthamsotruyen,Context thamsocontext){
double hientaisec=0;
double phantram=0;


    
    
        FFmpeg ffmpeg = FFmpeg.getInstance(thamsocontext);
        // to execute "ffmpeg -version" command you just need to pass "-version"
        //String[] cmd = new String[]{"-i","/storage/emulated/0/step.mov","/storage/emulated/0/he.mp4"};
        //    String [] countries = list.toArray(new String[list.size()]);
//    String[] cmd = new String[]{"-re","-stream_loop","-1","-i","/storage/emulated/0/1.mp4","-vcodec","libx264","-preset","veryfast","-maxrate","500k","-bufsize","2500k","-vf","format=yuv420p","-g","60","-acodec","libmp3lame","-b:a","198k","-ar","44100","-f","flv","rtmp://a.rtmp.youtube.com/live2/7s5s-2rh2-0xwu-2079"};
        String[] cmd = danhsachthamsotruyen.toArray(new String[danhsachthamsotruyen.size()]);
        //-stream_loop -1
        ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {

            @Override
            public void onStart() {
//BA.Log("Bat dau");
processBA.raiseEventFromUI(null, "startffmpegb4a");
            }

            @Override
            public void onProgress(String message) {
           
             try{
            if (message.contains("Duration:")) {
         String dur;
         dur=message.substring(message.indexOf("Duration: ")+10,message.indexOf(", start:"));

         String[] hms = dur.split(":");
          totalSecs = Integer.parseInt(hms[0]) * 3600
                 + Integer.parseInt(hms[1]) *   60
                 + Double.parseDouble(hms[2]);
//BA.Log("Tong thoi gian" + String.valueOf(totalSecs));
processBA.raiseEventFromUI(null, "returnduration",totalSecs);
     }
    
              if (message.contains(" time=") && message.contains("frame=") && message.contains("speed=") && message.contains("fps=") ) {
//dang xu ly
String hientai;
         hientai=message.substring(message.indexOf(" time=")+6,message.indexOf(" bitrate"));

         String[] hms = hientai.split(":");
         double hientaisec = Integer.parseInt(hms[0]) * 3600
                 + Integer.parseInt(hms[1]) *   60
                 + Double.parseDouble(hms[2]);
    //BA.Log("Tong thoi gian la" + String.valueOf(totalSecs) );
    processBA.raiseEventFromUI(null, "currenttimevalue",hientaisec);            
//BA.Log("Thoi gian hien tai" + String.valueOf(hientaisec) );
//BA.Log("Phan tram la " + String.valueOf(hientaisec*100/totalSecs) );
//processBA.raiseEventFromUI(null, "currenttimevalue",hientaisec);   

     }
     }
     catch (Exception e)
{}
           
            //BA.Log(message.substring(message.indexOf("Duration: ")+1, message.lastIndexOf(", start:")));
        //    BA.Log("Dang xu ly" + message);
           
            }

            @Override
            public void onFailure(String message) {
            BA.Log(message);
            processBA.raiseEventFromUI(null, "errornotice",message);            
            }

            @Override
            public void onSuccess(String message) {
            processBA.raiseEventFromUI(null, "successfunc",message);            
            BA.Log(message);
            }

            @Override
            public void onFinish() {
            BA.Log("Hoan thanh!");
            //processBA.raiseEventFromUI(null, "finish",message);            
        //    BA.Log(message);
            }

        });

    }


#End If
tnx it work with 1.1.6
 
Top