B4A Library FFmpeg_b4a - a FFmpeg library for b4a (decoding/streaming)

moster67

Expert
Licensed User
FFmpeg_b4a

EDIT: As of August 2019, this library is not compliant with Google Play store's latest requirements which require native 64bits libs. It is still useable for apps not being distributed on Google Play Store though.

Personally I would probably use the ExoPlayer (search the forum) these days unless you have codec-issues. Alternatively, you can use my Vitamio5 library/wrapper which is compliant with Google Play store's latest requirements.


FFmpeg_b4a
wraps the IJKPlayer library. Before FFmpeg_b4a, the only FFmpeg library available for B4A was Vitamio (for which I wrote a wrapper library back in 2012 - see here). My library for Vitamio was later enhanced by @warwound to support more recent versions of Vitamio - see here.

What is so special with FFmpeg and these libraries?
-Well, these libraries work like Android's default MediaPlayer and VideoView (see b4a's Audio-library) except that they include much more powerful features. They include a collection of media demuxers, decoders, filters - with FFmpeg you can decode many formats which are not supported natively by Android.

Why this new FFmpeg_b4a wrapper when there is already Vitamio?
- Good question! I wrote this library mainly due to licensing costs. As long as you develop personal and free apps (and with no ads) with Vitamio integrated, you can use Vitamio for free if I have understood things correctly. However, if you publish a pay app, an app with ads or develop an app for a third party where Vitamio is integrated, then you need a license which of course is fair enough. However, when I contacted Vitamio asking for license costs, I was informed the license costs were in thousands USD per app and per year! Well, this may be OK for larger companies but for a hobby programmer like myself (and probably others here on the forum), it is far too expensive. With the FFmpeg_b4a wrapper I believe the license costs are not any longer necessary. Please refer to the "read-me" in the link I cited above for IJKPlayer where the author of IJKPlayer explains licensing issues. I think the important thing here is that the author wrote the C++ code and the JAVA wrapper code himself and that his work may be used also in commercial projects. Please note that I am not a lawyer so I cannot be certain about this so don't blame me if you run into any licensing problems. However, personally I feel more confident to include this library in commercial projects compared to Vitamio.

Any disadvantages with FFMpeg_b4a compared to Vitamio?
-well, Vitamio is very mature and exposes more methods and attributes than FFmpeg_b4a. However, the only things that I personally miss in FFmpeg_b4a are support for subtitles and multiple audio tracks. Some other things missing in FFMmeg_b4a are: possibility to select video-quality (for now I believe all streams are "highest quality" only), no support for MIPS, you cannot set buffer-size and some other minor things. However, most methods and attributes available in Vitamio are available also in FFmpeg_b4a. The implementation of the methods are similar and use mostly the same syntax so replacing Vitamio should be rather easy and straight-forward. Hopefully the author of IJKPlayer will continue improving the library and add missing features.

How to use FFmpeg_b4a?

-Requirements:
a) You need B4A v3.20 or later to compile your app.
b) Min SDK version is API level 9 (Android 2.3–2.3.2 Gingerbread)

-Instructions:
1)In your B4A-project (refer to the included demo in the attached zip-file), under Project attributes, add 2 lines as follows:
B4X:
#AdditionalRes: C:\testingb4a\testffmpeg\ijkmediaplayer\res, tv.danmaku.ijk.media.player
#AdditionalRes: C:\testingb4a\testffmpeg\ijkmediawidget\res, tv.danmaku.ijk.media.widget
IMPORTANT - Replace "C:\testingb4a\testffmpeg\ijkmediaplayer\res" and "C:\testingb4a\testffmpeg\ijkmediawidget\res" with the path to your folder where you saved the supplied res-folders on your PC.
The res-folders are included in the attached zip-file. Please note that the res-folder for ijkmediaplayer is empty. I am unsure if B4A still needs the path when compiling so I included it anyway.

2) Copy the libraries (ijkmediaplayer.jar and ijkmediawidget.jar) included in the attached zip-file to your B4A extra-library folder.

3) The wrapper with the necessary FFmpeg-library (support for armeabi, armeabi-v7a and x86) is available here:
- FFmpeg_B4A - first version
- FFmpeg_B4A_v2 - added support for rtsp and some extra codecs
- FFmpeg_B4A_v3 - added support for some speech codecs suitable for IP-cams (https://www.dropbox.com/s/j5fqvgkl4be4dtk/FFMpeg_B4A_v3.zip?dl=0)

Extract and copy the library (jar-file and xml-file) into your B4A extra-library folder.

4) In B4A (in the the libs-tab), remember to tick the FFmpeg_b4a library.

Notes:
-armeabi, armeabi-v7a and x86 architecture are supported while ARMv5, ARMv6, MIPS are not.
-If the author of the IJKPlayer adds new features and I think it would be a worthwhile upgrade, I will try to include them and release an updated version of the wrapper.

Important final notes:
-Compared to the original FFmpeg build by bbcallen, I built and recompiled the basic FFmpeg-configuration by adding some codecs which I needed. I built the FFmpeg-library according to my needs but I think the FFmpeg_b4a wrapper should now work with most containers and video/audio decoders. This means that the FFmpeg-library is also rather light-weight compared to others.
-If you have problems with some streams or with playback of some video/audio-files, you can check the unfiltered logs in B4A and look for a line similar to the following: "No codec could be found with id XXX".
If you see this, then it is likely you need a codec which is not included the FFmpeg-library. Further down in the unfiltered log, you should see an indication which codec is missing. You can then add the missing containers, demuxers, muxers and codec by building and recompiling the FFmpeg-libraries yourself and then replace the existing FFmpeg-libraries (so-files) in the FFmpeg_B4A wrapper with the ones you generated (you can use 7Zip for that). In this way, you are independent as long as there are no major changes in the wrapper itself which could break the code.
-The wrapping of the library itself was not tricky. The difficult and time-consuming part was actually learning how to set up everything on a Linux-box, configure everything (dependencies, system environments etc.), get some basic understanding of FFmpeg in order to create and/or modify the FFmpeg-libraries, trouble-shooting errors and make sure that everything worked. I spent quite some time on this to get a better understanding. Most projects which can be found on the Internet are not supplying the FFmpeg-libraries while I actually decided to furnish a basic working set.
-If you need help with adding missing codecs, then I might be able to help you but you need to contact me by PM for further discussion.

Credits/Thanks:
-to the author of IJKPlayer: Zhang Rui (bbcallen)
-to @warwound (Martin) for permission to use (and modify) wrapper code for MediaController and OutlineTextView. The wrapper code for VideoView is based on code by myself and Martin.

PS: FFmpeg is actually a solution to record, convert and stream audio and video. It is used also for video and audio creation and manipulation. You can for instance download a YouTube-video and extract the audio-file. The version posted cannot do this since it only handles decoding/streaming. However, if I find some time later on, I will try to wrap a FFmpeg-library which will permit you to do other things and not only streaming(decoding).

Good luck!
 

Attachments

Last edited:

wimpie3

Well-Known Member
Licensed User
I get this error with the demo project:
B4X:
Parsing code.                          0.00
Compiling code.                        0.03
Compiling layouts code.                0.01
Generating R file.                      0.06
Compiling debugger engine code.        0.49
Compiling generated Java code.          Error
B4A line: 44
Activity.AddView(FFMpegVideoView1, 0, 0, 100%x, 100%y)
javac 1.7.0_60
src\b4a\example\main.java:329: error: cannot access VideoView
mostCurrent._activity.AddView((android.view.View)(mostCurrent._ffmpegvideoview1.getObject()),(int) (0),(int) (0),anywheresoftware.b4a.keywords.Common.PerXToCurrent((float) (100),mostCurrent.activityBA),anywheresoftware.b4a.keywords.Common.PerYToCurrent((float) (100),mostCurrent.activityBA));
                                                                                        ^
  class file for tv.danmaku.ijk.media.widget.VideoView not found
1 error
I have noticed the RES folder in the ijkmediaplayer directory is empty, is that normal? I've tried with the v7 library.
 

moster67

Expert
Licensed User
Oops - I forgot to include two libraries (jar-files) in the zip-file attached to the first post :eek:
Download the attachment from the first post again and you will see them. Just copy the libraries (jar-files) into your B4A Extra Library folder.

Please note that the res-folder for ijkmediaplayer is empty. I am unsure if B4A still needs the path when compiling so I included it anyway.
 

wimpie3

Well-Known Member
Licensed User
OK, thanks, it's working now! However, I have one more request. VideoView can be zoomed in to fit horizontally OR vertically by using the VideoViewRelativeLayout library. How can I zoom in on the video with your library?
 

Mark Zraik

Member
Licensed User
FFMpeg_b4a

---BETA---
Hi monster67,
I run on x86 (Windows XP SP3) and will be happy to update anything that goes goofy! Of-course, I might be the one going goofy...
I do have a project that downloads mp4's from the net and currently uses VideoView, which works, but is limited in event broadcasting and control.
A couple of videos are quite lengthy, so I'm hoping to allow more control to the user.

I haven't dived in on the in's and out's of this library, yet, but I will. Normally, I will read through before posting anything, but in this case, time is too short and I wanted you to know that I will get to this.

Thanks for the hard work from all who have participated and created this so far.
Coroner
 

wimpie3

Well-Known Member
Licensed User
SetVideoLayout ?
Changing this value does not seem to have an effect on the video. The video always zooms to fit horizontally, not vertically (what I want). Using negative values for SetLayout seems to move the video off-screen, but the width does not change...

Can you please take a look at the VideoViewRelativeLayout library and mimic what is done there? I presume it's just a fill_parent thing, nothing fancy.
 
Last edited:

Mark Zraik

Member
Licensed User
Hi monster67,
I run on x86 (Windows XP SP3) and will be happy to update anything that goes goofy! Of-course, I might be the one going goofy...
I do have a project that downloads mp4's from the net and currently uses VideoView, which works, but is limited in event broadcasting and control.
A couple of videos are quite lengthy, so I'm hoping to allow more control to the user.

I haven't dived in on the in's and out's of this library, yet, but I will. Normally, I will read through before posting anything, but in this case, time is too short and I wanted you to know that I will get to this.

Thanks for the hard work from all who have participated and created this so far.
Coroner
I must apologize,
It's moster67 not monster67...really and totally my fault ;)
 

moster67

Expert
Licensed User
Changing this value does not seem to have an effect on the video. The video always zooms to fit horizontally, not vertically (what I want). Using negative values for SetLayout seems to move the video off-screen, but the width does not change...

Can you please take a look at the VideoViewRelativeLayout library and mimic what is done there? I presume it's just a fill_parent thing, nothing fancy.
I guess I could implement an "Initialize2 method" or something similar to run the RelativeLayout code but to be honest, I prefer to keep the wrapper as simple as possible and to not include "non standard" features (at least for the time being). The very idea, in my opinion, is that Android should scale the video to fit the VideoView but keeping the video aspect ratio.

That said, I had a play with the VideoViewRelativeLayout library by @warwound and it seems to work fine with FFMpeg_b4a. If you have a word with Martin and you can get his approval that I may modify and publish it, I will post a version of his library adapted for FFMpeg_b4a here.

An alternative solution could, perhaps, be that you use the XmlLayoutBuilder library (http://www.basic4ppc.com/android/forum/threads/xmllayoutbuilder-load-xml-layouts.33762/) and use the following layout:

HTML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <VideoView android:id="@+id/videoViewRelative"
        android:layout_alignParentTop="true"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    </VideoView>

</RelativeLayout>
This layout does what Martin is doing with his VideoViewRelativeLayout library. I have not tried but it might work.
 
Last edited:

moster67

Expert
Licensed User
Hi monster67,
Can this be used for Live streaming ? something like Skype ?
Doubt it since this library won't permit you to encode (or even better to transcode) the output of the video-camera.
However, I guess generally speaking FFMPeg could be a solution for this although transcoding would be a critical phase on the phone.
 

moster67

Expert
Licensed User
The unfiltered log files show unknown FFP_MSG_xxx(700)
Having a look at the c++ sources, I found an explanation to the kind of error you got as follows:
B4X:
// 7xx
// The video is too complex for the decoder: it can't decode frames fast
// enough. Possibly only the audio plays fine at this stage.
    MEDIA_INFO_VIDEO_TRACK_LAGGING = 700,
Sorry but I can't help you with that. My knowledge how the FFMpeg engine works is nearly "null" and there is no way I would be able to modify the c++ sources (even if I wanted to). FFMpeg-b4a is just a wrapper over existing code/libraries. On the other hand, if the error was due to an unsupported codec, then I might be able to help if you contact me by PM. If the codec you used was unsupported, you would find an indication in the unfiltered logs and probably also the name of the codec concerned.
 

wimpie3

Well-Known Member
Licensed User
The problem is it happens with all MP4 files I've thrown at it. Could you upload a working MP4 file to your dropbox? This might help me finding a solution (might be an encoding setting, but I need a working example to find that out).
 

moster67

Expert
Licensed User
The problem is it happens with all MP4 files I've thrown at it. Could you upload a working MP4 file to your dropbox? This might help me finding a solution (might be an encoding setting, but I need a working example to find that out).
I am sorry but I don't have test-files to check. I am mainly working in streaming with dvb (mpegts/mpeg2video). However, if you want, you can send me one of the files that are not working (your dropbox or similar) and I will see if I can obtain more information why it does not work.
 

Mark Zraik

Member
Licensed User
I've tried to play a local MP4 file today using SetVideoPath, and this resulted in an error...
B4X:
Fatal signal 11 (SIGSEGV) at 0x0000002c (code=1), thread 16474 (b4a.example)
When I point SetVideoPath to "http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8" again, everything works fine.

The unfiltered log files show unknown FFP_MSG_xxx(700)

I found this online - it might shed some light--
This was a common error when stopping an OpenGL-ES app on Intel x86 AVD (every launch crashes at onStop()).

Here's a quick solution (worked fine for JPCT-AE Engine):- Open AndroidManifest.xml, add
android:allowClearUserData="true" tag to the application node.
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:allowClearUserData="true" >
Here's a link or 2
http://www.jpct.net/forum2/index.php?topic=3987.0
http://stackoverflow.com/questions/12575357/fatal-signal-11
https://www.buzztouch.com/forum/thr...ortColumn=FT.id&sortUpDown=DESC&currentPage=1

They all seem refer to, too large of a memory allocation and running out of memory, which crashes the app.
The others also talk about memory problems, but for different reasons.
I don't know C, C##, Cplus well enough to help. I'm just guessing here...
The B4A - AddPermission(android.permission.CLEAR_APP_USER_DATA) might get the manifest entry done for you.
The last link also chats about making the images smaller, and that fixed the problem.

Lots of things to try, I know, but I tried to at least run down some research.
Coroner
 
Top