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

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

  • FFMpeg_b4a.zip
    105.9 KB · Views: 2,157
Last edited:

Mark Zraik

Member
Licensed User
Longtime User

moster67

Expert
Licensed User
Longtime User
Well, ALL of the files I've tested do not work, so it is probably a bug somewere... For instance, take this one:

http://download.wavetlan.com/SVV/Media/HTTP/BlackBerry.mp4

If you look carefully in the unfiltered log, you can see the following message:
B4X:
No codec could be found with id 13

Apparently the previous error message is not entirely the reason for the failure but it probably pops up nonetheless since it is somehow related to the missing codec. By having a look at the unfiltered log, I can see that the missing codec is
B4X:
Video: mpeg4 (mp4v / 0x7634706D), 320x180, 348 kb/s

I built a new FFMpeg build and compiled the same and now the BlackBerry.mp4 file works fine.
 

wimpie3

Well-Known Member
Licensed User
Longtime User
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.

This does not seem to be working. I get an error:
B4X:
java.lang.ClassCastException: android.widget.VideoView cannot be cast to tv.danmaku.ijk.media.widget.VideoView

However, this code seems to work:

B4X:
<?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">

    <tv.danmaku.ijk.media.widget.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">
    </tv.danmaku.ijk.media.widget.VideoView>

</RelativeLayout>
 

moster67

Expert
Licensed User
Longtime User
However, this code seems to work:

B4X:
<?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">

    <tv.danmaku.ijk.media.widget.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">
    </tv.danmaku.ijk.media.widget.VideoView>

</RelativeLayout>


Great!
 

wimpie3

Well-Known Member
Licensed User
Longtime User
No idea on where I can download the most recent version with the latest FFMPEG?
 

moster67

Expert
Licensed User
Longtime User
FFMpeg_B4A (version 1.22)

Final version of FFMpeg_B4A was released (I don't consider it a beta any more). There is now a single library with support for armeabi, armeabi-v7a and x86.
Please read also the added "Important final notes" section in the first post for important information about the library.
 

wimpie3

Well-Known Member
Licensed User
Longtime User
Unfortunately, I get the same error on the backberry.mp4 file:

B4X:
IjkMediaPlayer_native_init
IjkMediaPlayer_native_setup
IjkMediaPlayer_setAvFormatOption
ijkmp_set_format_option(http-detect-range-support, 0)
ijkmp_set_format_option()=void
IjkMediaPlayer_setOverlayFormat
ijkmp_set_overlay_format(RV32(0x32335652))
ijkmp_set_overlay_format()=void
IjkMediaPlayer_setDataSourceAndHeaders
setDataSource: path /storage/emulated/0/blackberry.mp4
ijkmp_set_data_source(url="/storage/emulated/0/blackberry.mp4")
ijkmp_set_data_source(url="/storage/emulated/0/blackberry.mp4")=0
IjkMediaPlayer_setVideoSurface
ijkmp_set_android_surface(surface=0x1b90001d)
ijkmp_set_android_surface(surface=0x1b90001d)=void
IjkMediaPlayer_prepareAsync
ijkmp_prepare_async()
SDL_RunThread: [8602] ff_msg_loop
message_loop
FFP_MSG_FLUSH:
ijkmp_prepare_async()=0
IjkMediaPlayer_setVideoSurface
ijkmp_set_android_surface(surface=0x1ba0001d)
ijkmp_set_android_surface(surface=0x1ba0001d)=void
SDL_RunThread: [8604] ff_read
SDL_RunThread: [8603] ff_vout
Option http-detect-range-support not found.
max_frame_duration: 3600.000
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/storage/emulated/0/blackberry.mp4':
  Metadata:
    major_brand    :
mp42

    minor_version  :
0

    compatible_brands:
mp42isom

    creation_time  :
2007-01-29 23:25:04

  Duration:
00:00:36.92
, start:
0.000000
, bitrate:
432 kb/s

    Stream #0:0
(und)
: Audio: aac (mp4a / 0x6134706D), 32000 Hz, mono, fltp, 80 kb/s
(default)

    Metadata:
      creation_time  :
2007-01-29 23:25:04

      handler_name    :
soun

    Stream #0:1
(und)
: Video: mpeg4 (mp4v / 0x7634706D), 320x180, 348 kb/s
, 24 fps
, 24 tbr
, 600 tbn
, 600 tbc
(default)

    Metadata:
      creation_time  :
2007-01-29 23:25:04

      handler_name    :
vide

    Stream #0:2
(und)
: Data: none (mp4s / 0x7334706D), 0 kb/s
(default)

    Metadata:
      creation_time  :
2007-01-29 23:25:31

      handler_name    :
sdsm

    Stream #0:3
(und)
: Data: none (mp4s / 0x7334706D), 0 kb/s
(default)

    Metadata:
      creation_time  :
2007-01-29 23:25:31

      handler_name    :
odsm

SDL_AndroidAudioTrack: CHANNEL_OUT_MONO
SDL_AndroidAudioTrack: ENCODING_PCM_16BIT
sdl_audiotrack_new: init volume as 1.000000/(0.000000,1.000000)
SDL_RunThread: [8606] ff_aout_android


No codec could be found with id 13
ijkmp_get_msg: FFP_MSG_PREPARED
FFP_MSG_PREPARED:
unknown FFP_MSG_xxx(700)
Fatal signal 11 (SIGSEGV) at 0x0000002c (code=1), thread 8604 (b4a.example)
 

moster67

Expert
Licensed User
Longtime User
Unfortunately, I get the same error on the backberry.mp4 file:.....

The FFmpeg-library is the same as the first beta-libraries I posted earlier. The only difference is that there is now a single library and not 3 different ones. Other changes have not been done to it since I want to stick with the original FFmpeg-configuration implemented by the author of the library.

If you would have read the updated information in the first post, you would have seen how you could track down your error and how to conclude that your error is due to a missing codec. In order to fix it, you will need to compile a new FFmpeg-library and include the missing codec. I cannot provide a library which is working for all available codecs out there. If I would, the library would be huge while I want it rather small and optimized.

I believe that I have provided a wrapper which is helpful and useful for the B4A-community and it will (probably) work with any FFmpeg-library created according to the instructions of IJKPlayer's author. The creation of the FFmpeg-library does not require any programming knowledge and can be done by anyone who has the spirit to learn something new and to spend some time on it. That said, I may help out if I am contacted by PM.
 

wimpie3

Well-Known Member
Licensed User
Longtime User
Ok, fair enough, but can you please provide a list of the included codecs?
 

moster67

Expert
Licensed User
Longtime User
Ok, fair enough, but can you please provide a list of the included codecs?

Sure: take a look here

Support for the mp4-container is already there. You will need to add the mpeg4-codec in order to decode the Blackberry.mp4 file. Should be sufficient by adding the following line in the decoder-section:
B4X:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=mpeg4"

However, mp4 is a container (containing audio/video and meta-data) and sometimes the codecs involved may be different and mpeg4 may not always work if another codec was used in mp4-containers. If you have the luxury to encode the video-file yourself, you can use one of the already supported codecs and you should be good.
 

wimpie3

Well-Known Member
Licensed User
Longtime User
@moster67 I have the "luxury" to encode the file I need to show in any format I want... so I'd prefer to go that way. The page you pointed me to has "h264" in the list, so I'll try with that one... thanks for all the trouble!
 

wimpie3

Well-Known Member
Licensed User
Longtime User
@moster67 I'm about to give up.... I've been re-encoding my movie in over 10 formats (mpeg4, mp4, flv, f4v, avi, in fact every export format supported by my video editor). Some of them crash (due to a codec missing, I can understand that), but those that don't crash show a black video... In fact, the ONLY movie I ever got playing is the demo movie included... So I need some help here... can someone send me a file that is actually WORKING with this library so I can see what format is accepted?
 

moster67

Expert
Licensed User
Longtime User
@moster67 I'm about to give up.... I've been re-encoding my movie in over 10 formats (mpeg4, mp4, flv, f4v, avi, in fact every export format supported by my video editor). Some of them crash (due to a codec missing, I can understand that), but those that don't crash show a black video... In fact, the ONLY movie I ever got playing is the demo movie included... So I need some help here... can someone send me a file that is actually WORKING with this library so I can see what format is accepted?

Could be that if you encode a video, you gotta make sure that the audio-codec is supported too as well as the container. Maybe some containers accepts only certain video/audio codecs? The tests I have done are all in streaming except for the Blackberry.mp4 file you linked (which I tried in local) and they all work fine as long as the codec(s) is/are supported. If you upload your actual video-file somewhere so I can download it, then I can test it at my end. If you prefer, you can send the link by PM.
 

GabrielM

Member
Licensed User
Longtime User
Sure: take a look here

Support for the mp4-container is already there. You will need to add the mpeg4-codec in order to decode the Blackberry.mp4 file. Should be sufficient by adding the following line in the decoder-section:
B4X:
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-decoder=mpeg4"

However, mp4 is a container (containing audio/video and meta-data) and sometimes the codecs involved may be different and mpeg4 may not always work if another codec was used in mp4-containers. If you have the luxury to encode the video-file yourself, you can use one of the already supported codecs and you should be good.

Hi moster67

I have a video stream that currently I am accessing it in win32 with a videolan/vlc plugin.
The stream address I am using is:
B4X:
 rtsp://192.168.1.104:556/multicast/
Would it be possible to access this video stream with your library, please?

Btw, here is a working sample of a simple html code I am using now too get the above stream:
B4X:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<HTML>
  <BODY marginwidth="0" marginheight="0" topmargin="0" leftmargin="0">
  <OBJECT classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921"
  codebase="http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab"
  width="480" height="360" id="vlc" events="True">
  <param name="Src" value="rtsp://192.168.1.104:556/multicast/" />
  <param name="ShowDisplay" value="True" />
  <param name="AutoLoop" value="False" />
  <param name="AutoPlay" value="True" />
  <embed id="vlcEmb"  type="application/x-google-vlc-plugin" version="VideoLAN.VLCPlugin.2" autoplay="yes" loop="no" width="480" height="360"
  target="rtsp://192.168.1.104:556/multicast/" ></embed>
  </OBJECT>
  </BODY>
</HTML>


Regards,
Gabi.
 

moster67

Expert
Licensed User
Longtime User
@GabrielM

FFmpeg seems to support rtsp (see here). If this library does, I cannot say since I have never tried it with rtsp so you will need to test it yourself unless someone else can confirm if it works or not.

Generally speaking, if it works with Vitamio, then it should work fine with this wrapper too. If it does not, then you probably need to "play around" with the config-file and compile new so-files.
 

GabrielM

Member
Licensed User
Longtime User
Hi moster67

have tried few with this lib but no luck so far. I will try to compile new so-files.
thank you.

Regards,
Gabi.
 

wimpie3

Well-Known Member
Licensed User
Longtime User
After several days of testing, I'm still unable to stretch my video to fill the whole screen... no matter what I do, no matter what XML file I use as layout, the video is ALWAYS shown to fit horizontally (with black borders on the top and on the bottom). I'm afraid I need some help here...
 
Top