Skip to main content
Version: Android SDK v1.3.0

Playlists

Playlists are reactive lists of videos that can be played and observed efficiently, with built-in support for pagination, caching and preloading. This is the recommended way of fetching and playing videos through our player.

As with querying videos, the start point is the video store (VideoKit.videos()). Also, to fetch playlist you will need a valid session or the call will return an error.

Inspecting playlists

Every playlist holds a list of videos in memory. At first, this list represent the first "page" of results that were retrieved from server. These videos can be retrieved with the operator function Playlist.get:

val playlist: Playlist = ...
val size: Int = playlist.size
val firstVideo: Video? = playlist[0]

Pagination

If get is called with an index bigger than playlist.size, it will throw an exception. If you need more videos than those available at the moment, you can request a new batch of results by using Playlist.loadMore():

// Load next page
val nextPage: Call<Unit> = playlist.loadMore()
nextPage.onSuccess {
// Got new videos!
}

Coroutine users can use loadMoreSuspending() too.

Note that if Playlist.loadMoreOnAccess is true (default), the playlist will automatically load new pages as you consume the playlist with get, checking if you are getting close enough to the last available video. This makes it easy to show a list of videos without worrying about dynamic contents.

In case you want to access a video without triggering the "load more" logic, you have two choices:

  • set playlist.loadMoreOnAccess to false
  • access playlist.videos directly

Observing playlists

At any time, you can use Playlist.videos and Playlist.flow to retreive the current list of videos and, in case of the flow, to observe changes in it.

val playlist: Playlist = ...
val videos: List<Video> = playlist.video // won't trigger pagination
val flow: Flow<List<Video>> = playlist.flow

In addition, granular updates can be received by registering a Playlist.Observer. This is extremely useful when videos are shown in a RecyclerView, for example, so that you can call the appropriate notify* methods whenever something changes.

val playlist: Playlist = ...
playlist.addObserver(object: Playlist.Observer {
override fun onVideoInserted(id: String, index: Int) { ... }
override fun onVideoRemoved(id: String, index: Int) { ... }
override fun onVideoChanged(id: String, index: Int) { ... }
override fun onVideoMoved(id: String, fromIndex: Int, toIndex: Int) { ... }
})

Obtain playlists

As with other APIs, we use objects to define the query parameters. All such objects for playlists extend the PlaylistSpec interface. We expose several types of specs, each one with different configuration options.

Once you have the spec, just call getPlaylist:

val videos: VideoStore = VideoKit.videos()
val playlist = videos.getPlaylist(spec)

A similar function called loadPlaylist will act just like getPlaylist, but will also ensure that the first batch of videos is loaded from network (or local database) before returning a result.

Loading is of course asynchronous. Coroutine projects can use loadPlaylistSuspending() as well.

By user

You can filter by user using UserPlaylistSpec:

val spec = UserPlaylistSpec(userIdentity)
val spec = UserPlaylistSpec.builder(userIdentity) {
order(SortOrder.DESC)
pageSize(50)
}

By metadata and tags

You can filter by metadata and tags using FilteredPlaylistSpec:

val spec = FilteredPlaylistSpec(tags = tags, metadata = metadata)
val spec = FilteredPlaylistSpec.builder {
tags("tag1", "tag2")
metadata("key", "value")
order(SortOrder.DESC)
pageSize(50)
}

Custom playlists

You can create a playlist with custom videos using CustomPlaylistSpec:

val spec = CustomPlaylistSpec(name = "MyVideos", ids = listOf("videoId1", "videoId2"))

This is a special type of playlist which can be controlled by the user. As you can imagine, the playlist is mutable. You can use add, remove, set functions to mutate the set of desired ids and missing videos will be loaded accordingly.

val playlist: CustomPlaylist = ...

// add video by ID. This is asynchronous
playlist.add(id = "videoId", position = 1).onSuccess { 

}

Custom playlists have no built-in concept of pagination, so by default loadMore() does nothing. You can, however, pass a custom loader to playlist.loader: in this case, the playlist will trigger the loader whenever it thinks that a new page is needed, using the same triggering logic that is used by other playlists.