▶ MediaSessionPlayer - Play audio in the background, with a media session

MediaSessionPlayer

An extension that creates media sessions with the media library browser. It allows you to play the audio file database even after closing the application. It is based on the session module from the Media3 library.

With this extension it is possible to build an application recognized by Android Auto. Currently extensions cannot add xml files to the application resources, so without manually editing the APK file it is not possible automatically. If anyone is interested I can add a description of how to do it.

Built with Fast.

Events

OnResumeApp

This event is triggered when the application starts and when the application comes back to the foreground.

OnPauseApp

This event is triggered when an application moves from the foreground to the background.

OnGetChildren

This event is dispatched after the GetRootChildren and GetChildren functions are called. Returns a dictionary containing information about media elements.

Returns:
  • mediaItems: list

OnGetItem

This event is raised after the GetItem function is called. It returns a dictionary containing information about the media item, and a list of parents.

Returns:
  • item: dictionary
  • stock: list

ServiceStarted

This event is triggered after the service is started with the StartService function.

PlaylistIsReady

This event will be called when the internal playlist is created and ready to play.

OnPlay

An event triggered when the player starts playing.

OnPause

Event fired when the player pauses, also returns whether the pause was due to a media item ending.

Returns:
  • endOfMediaItems: boolean

OnNext

An event triggered by clicking the next multimedia button, in a notification or e.g. in headphones.

OnPrevious

An event triggered by clicking the previous multimedia button, in a notification or e.g. in headphones.

OnMediaItemTransition

An event triggered after switching to another media item in the list, as well as after changing the list in the player.

Returns:
  • reason: number

OnRepeatModeChanged

An event triggered after the repeat mode is changed.

Returns:
  • repeatMode: number

OnShuffleEnabledChanged

An event triggered after changing shuffle mode.

Returns:
  • shuffleEnabled: boolean

OnDeviceVolumeChanged

An event triggered after device volume changes. Returns current volume and whether device is muted.

Returns:
  • volume: number
  • muted: boolean

OnReady

An event triggered when the player is ready to play.

OnError

An event triggered when an error occurs in the player. The block returns the error number, the error name, and a message describing the error.

Returns:
  • errorNumber: number
  • errorName: text
  • message: text

Methods

CreatePlaylistFromJson

Creates a playlist from a json file.

Parameters:
  • json: text

CreatePlaylistFromDevice

It creates a playlist from audio files available on your device. It also searches for metadata along with a cover image so it may take a few dozen seconds.

Parameters:
  • withCovers: boolean

GetSongsCountFromDevice

Returns the number of songs found on the device.

GetItem

Searches for a media item with the given id. When the item is found, the OnGetItem event is triggered.

Parameters:
  • id: text

GetRootChildren

Gets the list of children of the root media folder. The list of children will be passed in the OnGetList event. We need this to further explore the playlist.

GetChildren

Gets a list of children from the folder with the given id. The list of children will be passed in the OnGetList event. We need this to further explore the playlist.

Parameters:
  • id: text

Prepare

Loads the media list into the player and prepares it for playback.

GetDuration

Returns the duration of the current media item in milliseconds, or 0 if the duration is not known.

GetBufferedPosition

Returns an estimate of the position in the current media item up to which data is buffered in milliseconds.

GetCurrentPosition

Returns the playback position in the current media item, in milliseconds.

GetCurrentArtwork

Gets the cover image of the currently playing media item.

GetCurrentTitle

Gets the title of the currently playing media item.

GetCurrentArtist

Gets the artist of the currently playing media item.

GetCurrentAlbum

Gets the album of the currently playing media item.

GetCurrentGenre

Gets the genre of the currently playing media item.

IsPlaying

Returns whether the player is playing, i.e. GetCurrentPosition is advancing.

GetCurrentMediaItemId

Gets the identifier of the currently playing media item.

GetCurrentMediaItemIndex

Gets the index of the currently playing media item.

GetMediaItemCount

Gets the number of total media items loaded into the player.

Release

Removes the application's connection to the service. The block should be used in the OnPause event.

PlayWhenReady

Sets whether playback should proceed when player is ready.

Parameters:
  • play: boolean

SeekTo

Seek to the media item at the specified index.

Parameters:
  • index: number

SeekToPosition

Seeks to a position specified in milliseconds in the current media item.

Parameters:
  • position: number

SeekToPrevious

Seeks to the default position of the previous media item.

SeekToNext

Seeks to the default position of the next media item.

ClearMediaItems

Clears the list loaded into the player.

HasPermission

Returns whether a given permission has been granted.

Parameters:
  • permission: text

Returns: boolean


StartService

Starts the service along with the media browser. When the service is started, the ServiceStarted event is raised.

Properties

RepeatMode

Sets the repeat mode to be used for playback. Off - Normal playback without repetition (integer value - 0). One - Repeats the currently playing media item infinitely (integer value - 1). All - Repeats the entire playlist infinitely (integer value - 2).

Options:
  • Off: 0
  • One: 1
  • All: 2

ShuffleEnabled

Sets whether shuffling of media items is enabled.

PlaybackSpeed

Sets the factor by which playback will be sped up. The value must be greater than 0.

PlaybackPitch

Sets the factor by which pitch will be shifted. The value must be greater than 0.

SdkVersion

Returns the SDK version of the software currently running on this hardware device.

PlaylistExist

Returns whether an internal playlist exists.

IsMediaStoreChanged

Returns whether the media store on the device has changed. This may mean that the songs have changed and need to be rescanned.

SmallIcon

The small icon for notification.

ArtworkPlaceholder

Sets a placeholder image when a cover image is not available in the audio file.

MiniPlayer

A module that adds a default system mini audio player that can be launched by clicking an audio file in any file manager.

Properties

PercentageWidth

Set the view width as a percentage of the screen width.

CornerRadius

Sets the radius of the rounded corners in a view.

BackgroundColor

Sets the background color of the view.

TextContentColor

Sets the color of texts in the view.

PlayButtonColor

Sets the color of the play/pause button in a view.

ProgressBackgroundColor

Sets the background color of the seek bar.

ProgressColor

Sets the progress color of the seek bar.

ThumbColor

Sets the thumb color of the seek bar.

TimeBar

A module that extends the Slider component, enabling it to work correctly as a time bar.

Events

TouchDown

An event triggered when we start touching the time bar.

TouchUp

An event triggered when we stop touching the time bar.

ChangedPosition

An event triggered when we change the position of the time bar. When we do it manually with our finger, the fromUser variable returns true. The event also returns the current position of the bar.

Returns:
  • position: number
  • fromUser: boolean

Methods

FormatTime

Converts duration in milliseconds to human-readable time in hours, minutes, and seconds.

Parameters:
  • millis: number

Returns: text


Properties

SetSlider

Set the Slider component that will be used as the time bar.

BufferingBarColor

Sets the color for the buffering bar in the Slider component.

BufferingPosition

Set the current buffering position of the media item in the Slider component.

CurrentPosition

Set the current position of the media item in the Slider component.

Max

Set the upper range of the TimeBarr max.



Download:

- Extension:

- Sample project:

The test application searches for files on the device, so the test requires audio files on the device memory.

I invite you to test and submit your comments. There are certainly use cases I haven't anticipated, so suggestions are also welcome. We cannot test the extension in Companion, only in compiled APKs.

7 Likes

Why did you set DefaultFileScope to Legacy in your test aia?

I think I was testing whether it was possible to make the Image component not ask for permissions. And I left it that way. You can easily change it, it shouldn't affect the extension's operation.

What does DefaultFileScope = Legacy have to do with it? Nothing. It just ensures that WRITE permission is also declared on Android 11+ (which of course makes no sense at all).

Yes, but it's just a test app for the extension and not an app ready to be sent to google play, so it doesn't affect anything.

Yes, I didn't say that either. It was just a question.

By the way, when I was looking through the manifest, I was surprised that there was a write permission there, and I didn't really know why. Now I know, thanks.

1 Like

To be honest, I still don't know to this day and I've been asking questions about it for years. :upside_down_face:

Hi

On checking the app Settings, there is a foreground service. Do i need to add an additional wakelock extension to keep app from sleeping?

Thanks!

My test app contains blocks that automatically refresh the list when files are deleted or added to the device. Check if it works for you.

I don't think that would be necessary in this case. Music is played in the service, not in the app. Apps can be closed or even removed from the recent list, and the music will continue to play. On my Xiaomi with Android 14 and Samsung with Android 9 the music played for many hours without interruption without any special procedures.

1 Like

Hi Patryk,
Thanks for the reply. :smile:
Will try out the blocks to refresh the database.

Android's "MediaStore" database should refresh automatically when you add/remove files. The extension has a block that you can use to detect if the database has changed. If it has changed, you recreate a new playlist, only this time you don't show it to the app user.

Pixel 2XL (Android 11):

1 Like

I have updated the test application.

1 Like

Now it's fine. :ok_hand:

A small thing. Fast forwarding and rewinding works, but while fast forwarding and rewinding, the music continues playing at the old position and only continues playing at the right place when you lift your finger.

Normally, the progress should be audible even while fast forwarding (for example, to get to a certain position in the music track).

Like this:

I checked in several well-known music applications and this is how it was done there. The progress bar in the notification also behaves this way. When swiping, only the time displayed under the progress bar changes, and the music changes only after releasing the finger. In my opinion, this is a more elegant method. Besides, it is not an extension function, but application logic. Well..., only MiniPlayer uses the same method permanently.

How did you get the song length in your daily challenge example ?

Well, I think every MP3 player and CD player behaves like I say. At least the sound shouldn't continue playing during fast forward/rewind.