B4A Library PndAudioExoPlayer - For online radio stations apps

Original library: https://github.com/google/ExoPlayer
Wrapper is based on ExoPlayer version v2.17.1 (10 Mar 2022)

This wrapper is no substitute for Erel's ExoPlayer, it was created with one goal in mind, to make it easier to create applications that use the online radio streams.

A few things have been added or made easier in relation to Erel's:
  • Handle audio focus - temporary mute player on call, SMS, etc.
  • Player's user agent
  • Radio station metadata
  • Stream metadata
  • Show song name, artist and album art (image) on remote Bluetooth device
  • Control player from remote device (smart watch, car's steering wheel, headphones, etc.)
  • Audio session ID for future improvements.

Some of the data you can extract from metadata: radio station name, song name, bitrate, radio station genre, radio station's url, etc.
Library can be used in Activity/B4XPage/Service.
Requires: B4A v11.5+, minSdkVersion: 21+

Screenshot.png

This is how example app looks on my Samsung (Tizen) watch, similar look and same functionality on Android and Huawei watches:
img.jpg

If you use not secure HTTP protocol for streams, you need to add this code in manifest:
B4X:
CreateResourceFromFile(Macro, Core.NetworkClearText)

PndAudioExoPlayer

Author:
Author: Google - B4a Wrapper: Pendrush
Version: 1.21
  • PndAudioExoPlayer
    • Events:
      • MediaSessionOnButton (KeyCode As Int)
      • MediaSessionOnPause
      • MediaSessionOnPlay
      • MediaSessionOnStop
      • OnAudioSessionIdChanged (AudioSessionId As Int)
      • OnIsPlayingChanged (IsPlaying As Boolean)
      • OnMetadata (Metadata As String)
      • OnPlaybackStateChanged (PlaybackState As Int)
      • OnPlayerError (Error As String)
      • OnTracksInfoChanged (Metadata As String)
    • Functions:
      • AudioSessionId As Int
        Returns the audio session identifier.
      • HlsMediaSource (Url As String)
        For: HLS streams (stream Url ends with .m3u8)
        Url - Radio station stream Url
      • Initialize (EventName As String, UserAgent As String, HandleAudioFocus As Boolean, AllowCrossProtocolRedirects As Boolean)
        Initialize player.
        EventName - Event name.
        UserAgent - User agent of player.
        HandleAudioFocus - Whether the player should handle audio focus, for example temporary mute player on call, SMS, etc.
        AllowCrossProtocolRedirects - Allow redirect from HTTPS to HTTP and vice versa.
        PndAudioExoPlayer1.Initialize("PndAudioExoPlayer1", "MyAppUserAgent/1.0", True, True)
      • IsInitialized As Boolean
      • IsPlaying As Boolean
        Returns whether the player is playing.
      • Play
        Resumes playback.
      • ProgressiveMediaSource (Url As String)
        For: MPEG (MP3), AAC, OGG streams
        Url - Radio station stream Url
      • Release
        Releases the player.
        This method must be called when the player is no longer required.
        The player must not be used after calling this method.
      • Stop
        Stops playback.
      • UpdateMediaSession (KeyTitle As String, KeyArtist As String, KeyAlbumArt As android.graphics.Bitmap)
        This items will display on remote (bluetooth) device like: smart watch, car display, etc.
        KeyTitle - Title name or song name
        KeyArtist - Artist name or for example radio station name
        KeyAlbumArt- Image of album or for example radio station logo.
    • Properties:
      • Volume As Float
        Get or Sets the audio volume.
        Range(from = 0.0, to = 1.0)

What's new:

v1.21
  • Resolved conflict with RuntimePermissions library.
  • Example app updated, removed AppCompat library.
v1.20
  • Previous, Next and all other media buttons will rise new event MediaSessionOnButton (KeyCode As Int)
  • Example app updated
v1.10
  • UpdateMediaSession - Title, song name and album art for remote devices like: smart watch, car display, etc.
  • 3 new events for remote devices (Bluetooth): play, pause, stop, this also should work from headphone devices. You can use it FROM remote device to control player on your phone, volume also work from remote device.

Download library from: https://www.dropbox.com/s/8954fff9pewc0rt/PndAudioExoPlayerLibrary.zip?dl=0
 

Attachments

  • PndAudioExoPlayerExample.zip
    91.8 KB · Views: 51
Last edited:

Pendrush

Well-Known Member
Licensed User
Longtime User
I don't have a habit of adding new messages to the existing thread concerning my libraries, but this is a very important upgrade of the library.
The first thread has been updated with new info.
 

wizard699

Active Member
Licensed User
Longtime User
I've this error in your project when execute

Uncaught translation error: com.android.dx.cf.code.SimException: invalid opcode
 

gunnarjonsson

Member
Licensed User
Longtime User
Hi!
When I run the app it works fine for maybe a couple of minutes then the sound stops and the app only reacts to the "is playing"- button which reports null. What can be the reason?
Gunnar
 

Pendrush

Well-Known Member
Licensed User
Longtime User
If you want to work with screen tuned off, you need to create partial lock, also is good to create service for player in foreground mode.
Example app is just example app to show possibilities of library and not to use it as is in production.
 

gunnarjonsson

Member
Licensed User
Longtime User
I have replaced Exoplayer with this player in my personal radiostreamer. When I try to compile I get the following error:
Dex merge Error
Error in c:\android\tools\..\extras\b4a_local\unpacked-pnd-media-1.5.0-63785105566389\jars\classes.zip:classes.dex:
Type android.support.v4.media.MediaBrowserCompat$CallbackHandler is defined multiple times: c:\android\tools\..\extras\b4a_local\unpacked-pnd-media-1.5.0-63785105566389\jars\classes.zip:classes.dex, c:\android\tools\..\extras\b4a_remote\androidx\media\media\1.1.0\unpacked-media-1.1.0\jars\classes.zip:classes.dex
Compilation failed
I dont know how to fix this. I suppose that unpacked-pnd-media-1.5.0 should be used in this case but I have no idea how to stop referencing unpacked-media-1.1.0.
Any ideas
 

PdeG

Member
Licensed User
I have replaced Exoplayer with this player in my personal radiostreamer. When I try to compile I get the following error:
Dex merge Error
When addding the RuntimePermissions library to the example app the error in post #8 appears.
 

Pendrush

Well-Known Member
Licensed User
Longtime User
When addding the RuntimePermissions library to the example app the error in post #8 appears.

Error in c:\android\tools\..\extras\b4a_local\unpacked-pnd-media-1.5.0-63785105566389\jars\classes.zip:classes.dex:
Type android.support.v4.media.MediaBrowserCompat$CallbackHandler is defined multiple times: c:\android\tools\..\extras\b4a_local\unpacked-pnd-media-1.5.0-63785105566389\jars\classes.zip:classes.dex, c:\android\tools\..\extras\b4a_remote\androidx\media\media\1.1.0\unpacked-media-1.1.0\jars\classes.zip:classes.dex
Compilation failed

You can try to add: #ExcludedLib: media-1.1.0

@Erel or anyone who knows what to try, can you help here?
 
Last edited:

Pendrush

Well-Known Member
Licensed User
Longtime User
What is pnd-media? Can't you remove the duplicate classes from the jar?
pnd-media is androidx.media:media:1.5.0
Duplicate class is provided from RuntimePermissions library.
If you create empty project and only add these two libs, you cannot compile app.
 

Pendrush

Well-Known Member
Licensed User
Longtime User
Can you download example project and additional libraries from post #1, add RuntimePermissions library and then try to compile project?
 

Pendrush

Well-Known Member
Licensed User
Longtime User
Make some tests and if it works fine, I recommend that you remove pnd-media-1.5.0 and add a dependency on com.android.support:support-v4
Ok. Thank you.
Done.
 
Last edited:
Dear MR Pendrush,
I would like to express very deep appreciation to your development knowledge. Library is outstanding. You have even thought on Android accessibility suite screen readers users. So if text to speech engine speak playback is being set to have a lower volume automatically. You have also included Stop method to stop The live stream. I can tell you. Very well done, because your library is The big evidence, that you are professional developer. You have brought this library for free to every users of B4A. Because I do not see at all, multimedia related apps focused on sound support are having big meaning for Me. So thanks to your professional library, I can finally make my INternet radio player for free for some of my visually impaired friends. And sure. I will add important information to The app GUI that program can run thanks to your library and I will add B4A forum thread direct link about your library. Thank you. You are also using B44Xpages library in your sample without .bal file and I like this approach very much.
I Am only sad, that you are calling something from Java, that I can not use your library on my old Android 4.1 based phone. But I will accept this reality, because many API functions are much more advanced than in such old Android.
I have tested your library on device with Android 8.0 and 6.0. Exoplayer produces very smooth output with focus on echo and soft basses. And because Exoplayer is being constantly improved, it is a good future for all multimedia based apps developers.
So thank you again ddear MR Pendrush
 
have a kind plea for The developer of this library. How complex would be to extend your library so it could detect, if user has disconnected wired head phones or wired headset? If it would be even possible to detect if those wired based devices have been connected it would be ideal. I have tested wired headsets and play /pause detection work. I will now try BLuetooth headsets from HBM or HBN company I can not recall The exact name. It contain next and previous buttons. Thank you for adding meta data support, especially genre and song name meta data. For every one of us, who would like to prevent many media live streams from being auto terminated /auto suspended by energy savers build in to some Android versions.
Add The following line to The serviceplayer.bas file from library example.

Sub Service_Start (StartingIntent As Intent)
StartServiceAt("", DateTime.Now + 10 * DateTime.TicksPerSecond, True)

Add to The
Sub Service_Destroy
StopService("")
CancelScheduledService("")
I have very good experience with this algorithm. May be, that it is not ideal solution, but it do not require to recall Ignore battery optimisations dialog box or to work with wakeloks. Unfortunately, I do not know, what would happen, if I would try that on Android 12.0. May be, that build in energy savers are even more advanced as in 8.0, so somebody would had to invent new background routine to prevent from player auto suspend when screen is turned off.
 

Pendrush

Well-Known Member
Licensed User
Longtime User
How complex would be to extend your library so it could detect, if user has disconnected wired head phones or wired headset?
Use BroadCastReceiver libarary:

 
Top