Playlist - Audio/Video

Say you have a bunch of hosted audio/video files you want to play for everyone in the room. The playlist feature gives a first class support for this. Supported actions -

  • Initialise with a list of video or audio playlist items which can be played
  • Choose the currently playing one
  • Play, Pause, Next, Previous
  • Seeking forward/backward or to a specific position
  • Letting sdk play in sequence or shuffling per your logic
  • Volume control
  • Playback rate control - slow down or speed up

API

The SDK deals with an array of what we'll call HMSPlaylistItem. This is how the interface looks for it looks like. There are 4 mandatory fields described in the schema below.

enum HMSPlaylistType { audio = 'audio', video = 'video' } interface HMSPlaylistItem<T> { /** * uniquely identifies a playlist item */ id: string; name: string; type: HMSPlaylistType; /** * the url to play from, local files are not supported currently. */ url: string; /** * any additional info, for eg. composer, musician etc. */ metadata?: T; /** * duration in seconds */ duration?: number; }

Once you have made such an array of your playlist items, you can then give it to sdk as below, and you'll be ready to go.

const audioPlayList: HMSPlaylistItem[] = getMyAudioPlaylist(); const videoPlayList: HMSPlaylistItem[] = getMyVideoPlaylist(); hmsActions.audioPlaylist.setList(audioPlayList); hmsActions.videoPlaylist.setList(videoPlayList);

Actions on the Playlist

Once the playlist is ready and given to the sdk, play/pause etc. can be done through calling different functions on hmsActions.audioPlaylist or hmsActions.videoPlaylist. The below interface shows all the functions which can be called. Do note that these will work only if you have already joined the room.

export interface IHMSPlaylistActions { /** * Plays the item whose id is passed. * @param {string} id - the id as given while initialising the list */ play(id: string): Promise<void>; /** * Pauses the current playing item */ pause(): Promise<void>; /** * Plays the next item in the queue(order decided by original array) */ playNext(): Promise<void>; /** * Plays the previous item in the queue(order decided by original array) */ playPrevious(): Promise<void>; /** * seek forward or backward relative to current position * @param {number} seekValue - number in seconds to move forward(pass negative values to move backwards) */ seek(seekValue: number): void; /** * seek to a specific position - seekValue will be absolute * @param {number} seekValue - value in seconds of the absolute position in the playlist item duration */ seekTo(seekValue: number): void; /** * set volume passing volume * @param {number} volume - number between 0-100 */ setVolume(volume: number): void; /** * pass list of playlist items to set playlist * @param {HMSPlaylistItem[]} - list of playlist items */ setList<T>(list: HMSPlaylistItem<T>[]): void; /** * Stop the current playback and unpublish the tracks. */ stop(): Promise<void>; /** * set whether to autoplay next item in playlist after the current one ends. You can disable this * if you want to implement any custom ordering or shuffling on your side. By default sdk will play the next * item in the queue once the current ends. * @param {boolean} autoplay */ setIsAutoplayOn(autoplay: boolean): void; /** * Control the playback speed - 1.0 being normal, less than 1.0 will play it slowly * and more than 1.0 will play it faster. * @param playbackRate - value from 0.25 and 2.0 */ setPlaybackRate(playbackRate: number): void; /** * Remove a single item from the playlist. This will stop the track if it is the current playing one and remove the item * returns a promise that resolves to true if the item was removed */ removeItem(id: string): Promise<boolean>; /** * Clear the entire playlist. This will stop the playing track(if any) */ clearList(): Promise<void>; }

Accessing Audio/Video Playlist information

Once audio/video playlist item is played, a track will be obtained and added to peer.auxiliaryTracks. We also expose a bunch of helpful selectors similar to those for screenshare tracks for getting the current state.

playlist.js
import { hmsActions, hmsStore } from './hms'; // audioListItems, videoListItems should have HMSPlaylistItem[] interface hmsActions.audioPlaylist.setList(audioListItems); hmsActions.videoPlaylist.setList(videoListItems); // Accessing playlist list set above const audioList = hmsStore.getState(selectAudioPlaylist.list); const videoList = hmsStore.getState(selectVideoPlaylist.list); // Accessing current selectedItem const selectedAudio = hmsStore.getState(selectAudioPlaylist.selectedItem); const selectedVideo = hmsStore.getState(selectVideoPlaylist.selectedItem); // Accessing current selection - { id, hasNext, hasPrevious } const audioSelection = hmsStore.getState(selectAudioPlaylist.selection); const videoSelection = hmsStore.getState(selectVideoPlaylist.selection); // Accessing current volume const audioVolume = hmsStore.getState(selectAudioPlaylist.volume); const videoVolume = hmsStore.getState(selectVideoPlaylist.volume); // Accessing current progress percentage - value between 0-100 const audioProgress = hmsStore.getState(selectAudioPlaylist.progress); const videoProgress = hmsStore.getState(selectVideoPlaylist.progress); // Accessing current time in seconds, 0-duration const audioCurrentTime = hmsStore.getState(selectAudioPlaylist.currentTime); const videoCurrentTime = hmsStore.getState(selectVideoPlaylist.currentTime); // Accessing current playback rate - value between 0.25-2.0 const audioPlaybackRate = hmsStore.getState(selectAudioPlaylist.playbackRate); const videoPlaybackRate = hmsStore.getState(selectVideoPlaylist.playbackRate); // Accessing Tracks for playlist peer = hmsStore.getState(selectPeerSharingAudioPlaylist); peer = hmsStore.getState(selectPeerSharingVideoPlaylist); const videoTrack = hmsStore.getState( selectVideoPlaylistVideoTrackByPeerID(peer.id), ); const videoPlaylistAudioTrack = hmsStore.getState( selectVideoPlaylistAudioTrackByPeerID(peer.id), ); const audioPlaylistAudioTrack = hmsStore.getState( selectAudioPlaylistTrackByPeerID(peer.id), );

Playing Next item in the playlist

By default, when the current item ends, the next item is played automatically. if you wish to control what you play next, you can do the following.

hmsActions.audioPlaylist.setIsAutoplayOn(false); hmsActions.videoPlaylist.setIsAutoplayOn(false);

You can then listen to a notification of type HMSNotificationTypes.PLAYLIST_TRACK_ENDED when current track ends and play the next track. The notification also contains the playlist item that has ended.

If you're also using SDKs of any other platform do note that the playlist tracks will come with source as "audioplaylist"/"videoplaylist".

Ideas

  • Play background music for everyone in the room from a playlist.
  • Allow for teachers to play educations videos for students from a pre selected list and without worrying about screenshare etc.
  • Watch videos together with friends, with some help from the Chat API, controls like play/pause can also be shared between the peers.
  • Play videos from mobile web browsers which don't support screenshare.

Limitations

  • Playing from local file is not yet supported.
  • No custom encoders/decoders, only file formats supported by native audio and video tags will work.