1e41f4b71Sopenharmony_ci# AVSession Provider 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciAn audio and video application needs to access the AVSession service as a provider in order to display media information in the controller (for example, Media Controller) and respond to playback control commands delivered by the controller. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci## Basic Concepts 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci- AVMetadata: media data related attributes, including the IDs of the current media asset (assetId), previous media asset (previousAssetId), and next media asset (nextAssetId), title, author, album, writer, and duration. 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ci- AVPlaybackState: playback state attributes, including the playback state, position, speed, buffered time, loop mode, media item being played (activeItemId), custom media data (extras), and whether the media asset is favorited (isFavorite). 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ci## Available APIs 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ciThe table below lists the key APIs used by the provider. The APIs use either a callback or promise to return the result. The APIs listed below use a callback. They provide the same functions as their counterparts that use a promise. 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ciFor details, see [AVSession Management](../../reference/apis-avsession-kit/js-apis-avsession.md). 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ci| API | Description | 18e41f4b71Sopenharmony_ci| -------- | -------- | 19e41f4b71Sopenharmony_ci| createAVSession(context: Context, tag: string, type: AVSessionType, callback: AsyncCallback<AVSession>): void<sup>10+<sup> | Creates an AVSession.<br>Only one AVSession can be created for a UIAbility. | 20e41f4b71Sopenharmony_ci| setAVMetadata(data: AVMetadata, callback: AsyncCallback<void>): void<sup>10+<sup> | Sets AVSession metadata. | 21e41f4b71Sopenharmony_ci| setAVPlaybackState(state: AVPlaybackState, callback: AsyncCallback<void>): void<sup>10+<sup> | Sets the AVSession playback state. | 22e41f4b71Sopenharmony_ci| setLaunchAbility(ability: WantAgent, callback: AsyncCallback<void>): void<sup>10+<sup> | Starts a UIAbility. | 23e41f4b71Sopenharmony_ci| getController(callback: AsyncCallback<AVSessionController>): void<sup>10+<sup> | Obtains the controller of the AVSession. | 24e41f4b71Sopenharmony_ci| getOutputDevice(callback: AsyncCallback<OutputDeviceInfo>): void<sup>10+<sup> | Obtains the output device information. | 25e41f4b71Sopenharmony_ci| activate(callback: AsyncCallback<void>): void<sup>10+<sup> | Activates the AVSession. | 26e41f4b71Sopenharmony_ci| deactivate(callback: AsyncCallback<void>): void<sup>10+<sup> | Deactivates this session. | 27e41f4b71Sopenharmony_ci| destroy(callback: AsyncCallback<void>): void<sup>10+<sup> | Destroys the AVSession. | 28e41f4b71Sopenharmony_ci| setAVQueueItems(items: Array<AVQueueItem>, callback: AsyncCallback<void>): void <sup>10+<sup> | Sets a playlist. | 29e41f4b71Sopenharmony_ci| setAVQueueTitle(title: string, callback: AsyncCallback<void>): void<sup>10+<sup> | Sets a name for the playlist. | 30e41f4b71Sopenharmony_ci| dispatchSessionEvent(event: string, args: {[key: string]: Object}, callback: AsyncCallback<void>): void<sup>10+<sup> | Dispatches a custom session event. | 31e41f4b71Sopenharmony_ci| setExtras(extras: {[key: string]: Object}, callback: AsyncCallback<void>): void<sup>10+<sup> | Sets a custom media packet in the form of a key-value pair.| 32e41f4b71Sopenharmony_ci| getOutputDeviceSync(): OutputDeviceInfo<sup>10+<sup> | Obtains the output device information. This API is a synchronous API. | 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci## How to Develop 35e41f4b71Sopenharmony_ci 36e41f4b71Sopenharmony_ciTo enable an audio and video application to access the AVSession service as a provider, proceed as follows: 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci1. Call an API in the **AVSessionManager** class to create and activate an **AVSession** object. 39e41f4b71Sopenharmony_ci 40e41f4b71Sopenharmony_ci ```ts 41e41f4b71Sopenharmony_ci import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci // Start to create and activate an AVSession object. 44e41f4b71Sopenharmony_ci // Create an AVSession object. 45e41f4b71Sopenharmony_ci let context: Context = getContext(this); 46e41f4b71Sopenharmony_ci async function createSession() { 47e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 48e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 49e41f4b71Sopenharmony_ci await session.activate(); 50e41f4b71Sopenharmony_ci console.info(`session create done : sessionId : ${session.sessionId}`); 51e41f4b71Sopenharmony_ci } 52e41f4b71Sopenharmony_ci ``` 53e41f4b71Sopenharmony_ci 54e41f4b71Sopenharmony_ci2. Set AVSession information, which includes: 55e41f4b71Sopenharmony_ci - AVMetadata 56e41f4b71Sopenharmony_ci - AVPlaybackState 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ci The controller will call an API in the **AVSessionController** class to obtain the information and display or process the information. 59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci ```ts 61e41f4b71Sopenharmony_ci import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 62e41f4b71Sopenharmony_ci import { BusinessError } from '@kit.BasicServicesKit'; 63e41f4b71Sopenharmony_ci 64e41f4b71Sopenharmony_ci let context: Context = getContext(this); 65e41f4b71Sopenharmony_ci async function setSessionInfo() { 66e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet in step 1. 67e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', 'audio'); 68e41f4b71Sopenharmony_ci // The player logic that triggers changes in the session metadata and playback state is omitted here. 69e41f4b71Sopenharmony_ci // Set necessary session metadata. 70e41f4b71Sopenharmony_ci let metadata: AVSessionManager.AVMetadata = { 71e41f4b71Sopenharmony_ci assetId: '0', // Specified by the application, used to identify the media asset in the application media library. 72e41f4b71Sopenharmony_ci title: 'TITLE', 73e41f4b71Sopenharmony_ci mediaImage: 'IMAGE', 74e41f4b71Sopenharmony_ci artist: 'ARTIST' 75e41f4b71Sopenharmony_ci }; 76e41f4b71Sopenharmony_ci session.setAVMetadata(metadata).then(() => { 77e41f4b71Sopenharmony_ci console.info(`SetAVMetadata successfully`); 78e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 79e41f4b71Sopenharmony_ci console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 80e41f4b71Sopenharmony_ci }); 81e41f4b71Sopenharmony_ci // Set the playback state to paused and set isFavorite to false. 82e41f4b71Sopenharmony_ci let playbackState: AVSessionManager.AVPlaybackState = { 83e41f4b71Sopenharmony_ci state:AVSessionManager.PlaybackState.PLAYBACK_STATE_PAUSE, 84e41f4b71Sopenharmony_ci isFavorite:false 85e41f4b71Sopenharmony_ci }; 86e41f4b71Sopenharmony_ci session.setAVPlaybackState(playbackState, (err) => { 87e41f4b71Sopenharmony_ci if (err) { 88e41f4b71Sopenharmony_ci console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 89e41f4b71Sopenharmony_ci } else { 90e41f4b71Sopenharmony_ci console.info(`SetAVPlaybackState successfully`); 91e41f4b71Sopenharmony_ci } 92e41f4b71Sopenharmony_ci }); 93e41f4b71Sopenharmony_ci // Set a playlist. 94e41f4b71Sopenharmony_ci let queueItemDescription_1: AVSessionManager.AVMediaDescription = { 95e41f4b71Sopenharmony_ci assetId: '001', 96e41f4b71Sopenharmony_ci title: 'music_name', 97e41f4b71Sopenharmony_ci subtitle: 'music_sub_name', 98e41f4b71Sopenharmony_ci description: 'music_description', 99e41f4b71Sopenharmony_ci mediaImage: "PIXELMAP_OBJECT", 100e41f4b71Sopenharmony_ci extras: {'extras':'any'} 101e41f4b71Sopenharmony_ci }; 102e41f4b71Sopenharmony_ci let queueItem_1: AVSessionManager.AVQueueItem = { 103e41f4b71Sopenharmony_ci itemId: 1, 104e41f4b71Sopenharmony_ci description: queueItemDescription_1 105e41f4b71Sopenharmony_ci }; 106e41f4b71Sopenharmony_ci let queueItemDescription_2: AVSessionManager.AVMediaDescription = { 107e41f4b71Sopenharmony_ci assetId: '002', 108e41f4b71Sopenharmony_ci title: 'music_name', 109e41f4b71Sopenharmony_ci subtitle: 'music_sub_name', 110e41f4b71Sopenharmony_ci description: 'music_description', 111e41f4b71Sopenharmony_ci mediaImage: "PIXELMAP_OBJECT", 112e41f4b71Sopenharmony_ci extras: {'extras':'any'} 113e41f4b71Sopenharmony_ci }; 114e41f4b71Sopenharmony_ci let queueItem_2: AVSessionManager.AVQueueItem = { 115e41f4b71Sopenharmony_ci itemId: 2, 116e41f4b71Sopenharmony_ci description: queueItemDescription_2 117e41f4b71Sopenharmony_ci }; 118e41f4b71Sopenharmony_ci let queueItemsArray = [queueItem_1, queueItem_2]; 119e41f4b71Sopenharmony_ci session.setAVQueueItems(queueItemsArray).then(() => { 120e41f4b71Sopenharmony_ci console.info(`SetAVQueueItems successfully`); 121e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 122e41f4b71Sopenharmony_ci console.error(`Failed to set AVQueueItem, error code: ${err.code}, error message: ${err.message}`); 123e41f4b71Sopenharmony_ci }); 124e41f4b71Sopenharmony_ci // Set a name for the playlist. 125e41f4b71Sopenharmony_ci let queueTitle = 'QUEUE_TITLE'; 126e41f4b71Sopenharmony_ci session.setAVQueueTitle(queueTitle).then(() => { 127e41f4b71Sopenharmony_ci console.info(`SetAVQueueTitle successfully`); 128e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 129e41f4b71Sopenharmony_ci console.info(`Failed to set AVQueueTitle, error code: ${err.code}, error message: ${err.message}`); 130e41f4b71Sopenharmony_ci }); 131e41f4b71Sopenharmony_ci } 132e41f4b71Sopenharmony_ci ``` 133e41f4b71Sopenharmony_ci 134e41f4b71Sopenharmony_ci3. Set the UIAbility to be started by the controller. The UIAbility configured here is started when a user operates the UI of the controller, for example, clicking a widget in Media Controller. 135e41f4b71Sopenharmony_ci The UIAbility is set through the **WantAgent** API. For details, see [WantAgent](../../reference/apis-ability-kit/js-apis-app-ability-wantAgent.md). 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_ci ```ts 138e41f4b71Sopenharmony_ci import { wantAgent } from '@kit.AbilityKit'; 139e41f4b71Sopenharmony_ci ``` 140e41f4b71Sopenharmony_ci 141e41f4b71Sopenharmony_ci ```ts 142e41f4b71Sopenharmony_ci import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 143e41f4b71Sopenharmony_ci import { wantAgent } from '@kit.AbilityKit'; 144e41f4b71Sopenharmony_ci 145e41f4b71Sopenharmony_ci let context: Context = getContext(this); 146e41f4b71Sopenharmony_ci async function getWantAgent() { 147e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 148e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet in step 1. 149e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 150e41f4b71Sopenharmony_ci let wantAgentInfo: wantAgent.WantAgentInfo = { 151e41f4b71Sopenharmony_ci wants: [ 152e41f4b71Sopenharmony_ci { 153e41f4b71Sopenharmony_ci bundleName: 'com.example.musicdemo', 154e41f4b71Sopenharmony_ci abilityName: 'MainAbility' 155e41f4b71Sopenharmony_ci } 156e41f4b71Sopenharmony_ci ], 157e41f4b71Sopenharmony_ci operationType: wantAgent.OperationType.START_ABILITIES, 158e41f4b71Sopenharmony_ci requestCode: 0, 159e41f4b71Sopenharmony_ci wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] 160e41f4b71Sopenharmony_ci } 161e41f4b71Sopenharmony_ci wantAgent.getWantAgent(wantAgentInfo).then((agent) => { 162e41f4b71Sopenharmony_ci session.setLaunchAbility(agent); 163e41f4b71Sopenharmony_ci }) 164e41f4b71Sopenharmony_ci } 165e41f4b71Sopenharmony_ci ``` 166e41f4b71Sopenharmony_ci 167e41f4b71Sopenharmony_ci4. Set a custom session event. The controller performs an operation after receiving the event. 168e41f4b71Sopenharmony_ci 169e41f4b71Sopenharmony_ci > **NOTE** 170e41f4b71Sopenharmony_ci > 171e41f4b71Sopenharmony_ci > The data set through **dispatchSessionEvent** is not saved in the **AVSession** object or AVSession service. 172e41f4b71Sopenharmony_ci 173e41f4b71Sopenharmony_ci ```ts 174e41f4b71Sopenharmony_ci 175e41f4b71Sopenharmony_ci import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 176e41f4b71Sopenharmony_ci import { BusinessError } from '@kit.BasicServicesKit'; 177e41f4b71Sopenharmony_ci 178e41f4b71Sopenharmony_ci let context: Context = getContext(this); 179e41f4b71Sopenharmony_ci async function dispatchSessionEvent() { 180e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet in step 1. 181e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 182e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 183e41f4b71Sopenharmony_ci let eventName = 'dynamic_lyric'; 184e41f4b71Sopenharmony_ci await session.dispatchSessionEvent(eventName, {lyric : 'This is my lyric'}).then(() => { 185e41f4b71Sopenharmony_ci console.info(`Dispatch session event successfully`); 186e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 187e41f4b71Sopenharmony_ci console.error(`Failed to dispatch session event. Code: ${err.code}, message: ${err.message}`); 188e41f4b71Sopenharmony_ci }) 189e41f4b71Sopenharmony_ci } 190e41f4b71Sopenharmony_ci 191e41f4b71Sopenharmony_ci ``` 192e41f4b71Sopenharmony_ci 193e41f4b71Sopenharmony_ci5. Set a custom media packet. The controller performs an operation after receiving the event. 194e41f4b71Sopenharmony_ci 195e41f4b71Sopenharmony_ci > **NOTE** 196e41f4b71Sopenharmony_ci > 197e41f4b71Sopenharmony_ci > The data set by using **setExtras** is stored in the AVSession service. The data lifecycle is the same as that of the **AVSession** object, and the controller corresponding to the object can use **getExtras** to obtain the data. 198e41f4b71Sopenharmony_ci 199e41f4b71Sopenharmony_ci ```ts 200e41f4b71Sopenharmony_ci import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 201e41f4b71Sopenharmony_ci import { BusinessError } from '@kit.BasicServicesKit'; 202e41f4b71Sopenharmony_ci 203e41f4b71Sopenharmony_ci let context: Context = getContext(this); 204e41f4b71Sopenharmony_ci async function setExtras() { 205e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet in step 1. 206e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 207e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 208e41f4b71Sopenharmony_ci await session.setExtras({extra : 'This is my custom meida packet'}).then(() => { 209e41f4b71Sopenharmony_ci console.info(`Set extras successfully`); 210e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 211e41f4b71Sopenharmony_ci console.error(`Failed to set extras. Code: ${err.code}, message: ${err.message}`); 212e41f4b71Sopenharmony_ci }) 213e41f4b71Sopenharmony_ci } 214e41f4b71Sopenharmony_ci ``` 215e41f4b71Sopenharmony_ci 216e41f4b71Sopenharmony_ci6. Listen for playback control commands or events delivered by the controller, for example, Media Controller. 217e41f4b71Sopenharmony_ci 218e41f4b71Sopenharmony_ci Both fixed playback control commands and advanced playback control events can be listened for. 219e41f4b71Sopenharmony_ci 220e41f4b71Sopenharmony_ci 6.1 Listening for Fixed Playback Control Commands 221e41f4b71Sopenharmony_ci 222e41f4b71Sopenharmony_ci > **NOTE** 223e41f4b71Sopenharmony_ci > 224e41f4b71Sopenharmony_ci > After the provider registers a listener for fixed playback control commands, the commands will be reflected in **getValidCommands()** of the controller. In other words, the controller determines that the command is valid and triggers the corresponding event (not used temporarily) as required. To ensure that the playback control commands delivered by the controller can be executed normally, the provider should not use a null implementation for listening. 225e41f4b71Sopenharmony_ci 226e41f4b71Sopenharmony_ci Fixed playback control commands on the session side include basic operation commands such as play, pause, previous, and next. For details, see [AVControlCommand](../../reference/apis-avsession-kit/js-apis-avsession.md). 227e41f4b71Sopenharmony_ci 228e41f4b71Sopenharmony_ci ```ts 229e41f4b71Sopenharmony_ci import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 230e41f4b71Sopenharmony_ci 231e41f4b71Sopenharmony_ci let context: Context = getContext(this); 232e41f4b71Sopenharmony_ci async function setListenerForMesFromController() { 233e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet in step 1. 234e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 235e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 236e41f4b71Sopenharmony_ci // Generally, logic processing on the player is implemented in the listener. 237e41f4b71Sopenharmony_ci // After the processing is complete, use the setter to synchronize the playback information. For details, see the code snippet above. 238e41f4b71Sopenharmony_ci session.on('play', () => { 239e41f4b71Sopenharmony_ci console.info(`on play , do play task`); 240e41f4b71Sopenharmony_ci // If this command is not supported, do not register it. If the command has been registered but is not used temporarily, use session.off('play') to cancel listening. 241e41f4b71Sopenharmony_ci // After the processing is complete, call SetAVPlayState to report the playback state. 242e41f4b71Sopenharmony_ci }); 243e41f4b71Sopenharmony_ci session.on('pause', () => { 244e41f4b71Sopenharmony_ci console.info(`on pause , do pause task`); 245e41f4b71Sopenharmony_ci // If this command is not supported, do not register it. If the command has been registered but is not used temporarily, use session.off('pause') to cancel listening. 246e41f4b71Sopenharmony_ci // After the processing is complete, call SetAVPlayState to report the playback state. 247e41f4b71Sopenharmony_ci }); 248e41f4b71Sopenharmony_ci session.on('stop', () => { 249e41f4b71Sopenharmony_ci console.info(`on stop , do stop task`); 250e41f4b71Sopenharmony_ci // If this command is not supported, do not register it. If the command has been registered but is not used temporarily, use session.off('stop') to cancel listening. 251e41f4b71Sopenharmony_ci // After the processing is complete, call SetAVPlayState to report the playback state. 252e41f4b71Sopenharmony_ci }); 253e41f4b71Sopenharmony_ci session.on('playNext', () => { 254e41f4b71Sopenharmony_ci console.info(`on playNext , do playNext task`); 255e41f4b71Sopenharmony_ci // If this command is not supported, do not register it. If the command has been registered but is not used temporarily, use session.off('playNext') to cancel listening. 256e41f4b71Sopenharmony_ci // After the processing is complete, call SetAVPlayState to report the playback state and call SetAVMetadata to report the media information. 257e41f4b71Sopenharmony_ci }); 258e41f4b71Sopenharmony_ci session.on('playPrevious', () => { 259e41f4b71Sopenharmony_ci console.info(`on playPrevious , do playPrevious task`); 260e41f4b71Sopenharmony_ci // If this command is not supported, do not register it. If the command has been registered but is not used temporarily, use session.off('playPrevious') to cancel listening. 261e41f4b71Sopenharmony_ci // After the processing is complete, call SetAVPlayState to report the playback state and call SetAVMetadata to report the media information. 262e41f4b71Sopenharmony_ci }); 263e41f4b71Sopenharmony_ci session.on('fastForward', () => { 264e41f4b71Sopenharmony_ci console.info(`on fastForward , do fastForward task`); 265e41f4b71Sopenharmony_ci // If this command is not supported, do not register it. If the command has been registered but is not used temporarily, use session.off('fastForward') to cancel listening. 266e41f4b71Sopenharmony_ci // After the processing is complete, call SetAVPlayState to report the playback state and position. 267e41f4b71Sopenharmony_ci }); 268e41f4b71Sopenharmony_ci session.on('rewind', () => { 269e41f4b71Sopenharmony_ci console.info(`on rewind , do rewind task`); 270e41f4b71Sopenharmony_ci // If this command is not supported, do not register it. If the command has been registered but is not used temporarily, use session.off('rewind') to cancel listening. 271e41f4b71Sopenharmony_ci // After the processing is complete, call SetAVPlayState to report the playback state and position. 272e41f4b71Sopenharmony_ci }); 273e41f4b71Sopenharmony_ci 274e41f4b71Sopenharmony_ci session.on('seek', (time) => { 275e41f4b71Sopenharmony_ci console.info(`on seek , the seek time is ${time}`); 276e41f4b71Sopenharmony_ci // If this command is not supported, do not register it. If the command has been registered but is not used temporarily, use session.off('seek') to cancel listening. 277e41f4b71Sopenharmony_ci // After the processing is complete, call SetAVPlayState to report the playback state and position. 278e41f4b71Sopenharmony_ci }); 279e41f4b71Sopenharmony_ci session.on('setSpeed', (speed) => { 280e41f4b71Sopenharmony_ci console.info(`on setSpeed , the speed is ${speed}`); 281e41f4b71Sopenharmony_ci // do some tasks ··· 282e41f4b71Sopenharmony_ci }); 283e41f4b71Sopenharmony_ci session.on('setLoopMode', (mode) => { 284e41f4b71Sopenharmony_ci console.info(`on setLoopMode , the loop mode is ${mode}`); 285e41f4b71Sopenharmony_ci // If this command is not supported, do not register it. If the command has been registered but is not used temporarily, use session.off('setLoopMode') to cancel listening. 286e41f4b71Sopenharmony_ci // The application determines the next loop mode. After the processing is complete, call SetAVPlayState to report the new loop mode. 287e41f4b71Sopenharmony_ci }); 288e41f4b71Sopenharmony_ci session.on('toggleFavorite', (assetId) => { 289e41f4b71Sopenharmony_ci console.info(`on toggleFavorite , the target asset Id is ${assetId}`); 290e41f4b71Sopenharmony_ci // If this command is not supported, do not register it. If the command has been registered but is not used temporarily, use session.off('toggleFavorite') to cancel listening. 291e41f4b71Sopenharmony_ci // After the processing is complete, call SetAVPlayState to report the value of isFavorite. 292e41f4b71Sopenharmony_ci }); 293e41f4b71Sopenharmony_ci } 294e41f4b71Sopenharmony_ci ``` 295e41f4b71Sopenharmony_ci 296e41f4b71Sopenharmony_ci 6.2 Listening for Advanced Playback Control Events 297e41f4b71Sopenharmony_ci 298e41f4b71Sopenharmony_ci The following advanced playback control events can be listened for: 299e41f4b71Sopenharmony_ci 300e41f4b71Sopenharmony_ci - **skipToQueueItem**: triggered when an item in the playlist is selected. 301e41f4b71Sopenharmony_ci - **handleKeyEvent**: triggered when a key is pressed. 302e41f4b71Sopenharmony_ci - **outputDeviceChange**: triggered when the output device changes. 303e41f4b71Sopenharmony_ci - **commonCommand**: triggered when a custom playback control command changes. 304e41f4b71Sopenharmony_ci 305e41f4b71Sopenharmony_ci ```ts 306e41f4b71Sopenharmony_ci import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 307e41f4b71Sopenharmony_ci 308e41f4b71Sopenharmony_ci let context: Context = getContext(this); 309e41f4b71Sopenharmony_ci async function setListenerForMesFromController() { 310e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet in step 1. 311e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 312e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 313e41f4b71Sopenharmony_ci // Generally, logic processing on the player is implemented in the listener. 314e41f4b71Sopenharmony_ci // After the processing is complete, use the setter to synchronize the playback information. For details, see the code snippet above. 315e41f4b71Sopenharmony_ci session.on('skipToQueueItem', (itemId) => { 316e41f4b71Sopenharmony_ci console.info(`on skipToQueueItem , do skip task`); 317e41f4b71Sopenharmony_ci // do some tasks ··· 318e41f4b71Sopenharmony_ci }); 319e41f4b71Sopenharmony_ci session.on('handleKeyEvent', (event) => { 320e41f4b71Sopenharmony_ci console.info(`on handleKeyEvent , the event is ${JSON.stringify(event)}`); 321e41f4b71Sopenharmony_ci // do some tasks ··· 322e41f4b71Sopenharmony_ci }); 323e41f4b71Sopenharmony_ci session.on('outputDeviceChange', (device) => { 324e41f4b71Sopenharmony_ci console.info(`on outputDeviceChange , the device info is ${JSON.stringify(device)}`); 325e41f4b71Sopenharmony_ci // do some tasks ··· 326e41f4b71Sopenharmony_ci }); 327e41f4b71Sopenharmony_ci session.on('commonCommand', (commandString, args) => { 328e41f4b71Sopenharmony_ci console.info(`on commonCommand , command is ${commandString}, args are ${JSON.stringify(args)}`); 329e41f4b71Sopenharmony_ci // do some tasks ··· 330e41f4b71Sopenharmony_ci }); 331e41f4b71Sopenharmony_ci } 332e41f4b71Sopenharmony_ci ``` 333e41f4b71Sopenharmony_ci 334e41f4b71Sopenharmony_ci7. Obtain an **AVSessionController** object for this **AVSession** object for interaction. 335e41f4b71Sopenharmony_ci 336e41f4b71Sopenharmony_ci ```ts 337e41f4b71Sopenharmony_ci import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 338e41f4b71Sopenharmony_ci 339e41f4b71Sopenharmony_ci let context: Context = getContext(this); 340e41f4b71Sopenharmony_ci async function createControllerFromSession() { 341e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet in step 1. 342e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 343e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 344e41f4b71Sopenharmony_ci 345e41f4b71Sopenharmony_ci // Obtain an AVSessionController object for this AVSession object. 346e41f4b71Sopenharmony_ci let controller = await session.getController(); 347e41f4b71Sopenharmony_ci 348e41f4b71Sopenharmony_ci // The AVSessionController object can interact with the AVSession object, for example, by delivering a playback control command. 349e41f4b71Sopenharmony_ci let avCommand: AVSessionManager.AVControlCommand = {command:'play'}; 350e41f4b71Sopenharmony_ci controller.sendControlCommand(avCommand); 351e41f4b71Sopenharmony_ci 352e41f4b71Sopenharmony_ci // Alternatively, listen for state changes. 353e41f4b71Sopenharmony_ci controller.on('playbackStateChange', 'all', (state) => { 354e41f4b71Sopenharmony_ci 355e41f4b71Sopenharmony_ci // do some things 356e41f4b71Sopenharmony_ci }); 357e41f4b71Sopenharmony_ci 358e41f4b71Sopenharmony_ci // The AVSessionController object can perform many operations. For details, see the description of the controller. 359e41f4b71Sopenharmony_ci } 360e41f4b71Sopenharmony_ci ``` 361e41f4b71Sopenharmony_ci 362e41f4b71Sopenharmony_ci8. When the audio and video application exits and does not need to continue playback, cancel the listener and destroy the **AVSession** object. 363e41f4b71Sopenharmony_ci 364e41f4b71Sopenharmony_ci The code snippet below is used for canceling the listener for playback control commands: 365e41f4b71Sopenharmony_ci 366e41f4b71Sopenharmony_ci ```ts 367e41f4b71Sopenharmony_ci import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 368e41f4b71Sopenharmony_ci 369e41f4b71Sopenharmony_ci let context: Context = getContext(this); 370e41f4b71Sopenharmony_ci async function unregisterSessionListener() { 371e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet in step 1. 372e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 373e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 374e41f4b71Sopenharmony_ci 375e41f4b71Sopenharmony_ci // Cancel the listener of the AVSession object. 376e41f4b71Sopenharmony_ci session.off('play'); 377e41f4b71Sopenharmony_ci session.off('pause'); 378e41f4b71Sopenharmony_ci session.off('stop'); 379e41f4b71Sopenharmony_ci session.off('playNext'); 380e41f4b71Sopenharmony_ci session.off('playPrevious'); 381e41f4b71Sopenharmony_ci session.off('skipToQueueItem'); 382e41f4b71Sopenharmony_ci session.off('handleKeyEvent'); 383e41f4b71Sopenharmony_ci session.off('outputDeviceChange'); 384e41f4b71Sopenharmony_ci session.off('commonCommand'); 385e41f4b71Sopenharmony_ci } 386e41f4b71Sopenharmony_ci ``` 387e41f4b71Sopenharmony_ci 388e41f4b71Sopenharmony_ci The code snippet below is used for destroying the AVSession object: 389e41f4b71Sopenharmony_ci 390e41f4b71Sopenharmony_ci ```ts 391e41f4b71Sopenharmony_ci import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 392e41f4b71Sopenharmony_ci 393e41f4b71Sopenharmony_ci let context: Context = getContext(this); 394e41f4b71Sopenharmony_ci async function destroySession() { 395e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet in step 1. 396e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 397e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 398e41f4b71Sopenharmony_ci // Destroy the AVSession object. 399e41f4b71Sopenharmony_ci session.destroy((err) => { 400e41f4b71Sopenharmony_ci if (err) { 401e41f4b71Sopenharmony_ci console.error(`Failed to destroy session. Code: ${err.code}, message: ${err.message}`); 402e41f4b71Sopenharmony_ci } else { 403e41f4b71Sopenharmony_ci console.info(`Destroy : SUCCESS `); 404e41f4b71Sopenharmony_ci } 405e41f4b71Sopenharmony_ci }); 406e41f4b71Sopenharmony_ci } 407e41f4b71Sopenharmony_ci ``` 408