1e41f4b71Sopenharmony_ci# Accessing AVSession 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciIn addition to the implementation of audio and video playback, media applications may need to access AVSession provided by AVSession Kit for display and control purposes. This topic describes typical display and control scenarios of accessing AVSession. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ciIn different access scenarios, different UIs are displayed in the controller of the system, and different specifications are posed for application access processing. 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci## Scenarios That Require AVSession Access 8e41f4b71Sopenharmony_ci 9e41f4b71Sopenharmony_ciAVSession restricts background audio playback and VoIP calls. As such, applications that provide long-duration audio or video playback, audiobook applications, and VoIP applications need to access AVSession. If such an application does not access AVSession, the system stops its audio playback or mutes the ongoing call when detecting that the application is running in the background. In this way, the application behavior is restricted. You can verify the restriction locally before the application is released. 10e41f4b71Sopenharmony_ci 11e41f4b71Sopenharmony_ciFor applications that may use audio playback, such as gaming and live broadcast applications, accessing AVSession is optional. However, if they want to continue audio playback after switching to the background, they must access AVSession. 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ciTo implement background playback, the application must also use [Background Tasks Kit](../../task-management/background-task-overview.md) to request a continuous task to avoid being suspended. 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci## Access Process 16e41f4b71Sopenharmony_ci 17e41f4b71Sopenharmony_ciThe process for implementing AVSession access is as follows: 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci1. Determine the type of AVSession to be created for the application, and then [create one](#creating-avsession). The AVSession type determines the style of the control template displayed in the controller. 20e41f4b71Sopenharmony_ci2. [Create a background task](#creating-a-background-task). 21e41f4b71Sopenharmony_ci3. [Set necessary metadata](#setting-metadata), which is the response information displayed in the controller. The metadata includes the IDs of the current media asset (assetId), previous media asset (previousAssetId), and next media asset (nextAssetId), title, author, album, writer, and duration. 22e41f4b71Sopenharmony_ci4. [Set playback state information](#setting-playback-state-information). The information includes 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). 23e41f4b71Sopenharmony_ci5. [Register control commands](#registering-control-commands). The control commands include **play**, **pause**, **previous**, **next**, **fastForward**, **rewind**, **toggleFavorite**, **setLoopMode**, and **seek**. 24e41f4b71Sopenharmony_ci6. Destroy AVSession when the application exits or stops providing service. 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci## Creating AVSession 27e41f4b71Sopenharmony_ci 28e41f4b71Sopenharmony_ci[AVSessionType](../../reference/apis-avsession-kit/js-apis-avsession.md#avsessiontype10) in the constructor determines the type of AVSession to create. Different AVSession types represent the control capabilities in various scenarios and display different control templates in the controller. 29e41f4b71Sopenharmony_ci 30e41f4b71Sopenharmony_ci- For audio AVSession, the controller provides the following control buttons: favorite, previous, play/pause, next, and loop mode. 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ci- For video AVSession, the controller provides the following control buttons: rewind, previous, play/pause, next, and fast-forward. 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci- For voice_call AVSession, the application is not displayed in the controller. 35e41f4b71Sopenharmony_ci 36e41f4b71Sopenharmony_ciRefer to the code snippet below: 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci```ts 39e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci// Start to create and activate an AVSession object. 42e41f4b71Sopenharmony_ci// Create an AVSession object. 43e41f4b71Sopenharmony_cilet context: Context = getContext(this); 44e41f4b71Sopenharmony_ciasync function createSession() { 45e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 46e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context,'SESSION_NAME', type); 47e41f4b71Sopenharmony_ci 48e41f4b71Sopenharmony_ci // Call activate() after the metadata and control commands are registered. 49e41f4b71Sopenharmony_ci await session.activate(); 50e41f4b71Sopenharmony_ci console.info(`session create done : sessionId : ${session.sessionId}`); 51e41f4b71Sopenharmony_ci} 52e41f4b71Sopenharmony_ci``` 53e41f4b71Sopenharmony_ci 54e41f4b71Sopenharmony_ci## Creating a Background Task 55e41f4b71Sopenharmony_ci 56e41f4b71Sopenharmony_ciTo implement background playback, the application must also use [Background Tasks Kit](../../task-management/background-task-overview.md) to request a continuous task to avoid being suspended. 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ciMedia playback applications must request a continuous task of the [AUDIO_PLAYBACK](../../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-backgroundTaskManager.md#backgroundmode) background mode. 59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci## Setting Metadata 62e41f4b71Sopenharmony_ci 63e41f4b71Sopenharmony_ci### Setting Common Metadata 64e41f4b71Sopenharmony_ci 65e41f4b71Sopenharmony_ciThe application can call **setAVMetadata()** to set AVSession metadata to the system so that the metadata can be displayed in the controller. The metadata includes the IDs of the current media asset (assetId), previous media asset (previousAssetId), and next media asset (nextAssetId), title, author, album, writer, and duration. 66e41f4b71Sopenharmony_ci 67e41f4b71Sopenharmony_ci```ts 68e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 69e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 70e41f4b71Sopenharmony_ci 71e41f4b71Sopenharmony_cilet context: Context = getContext(this); 72e41f4b71Sopenharmony_ciasync function setSessionInfo() { 73e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 74e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', 'audio'); 75e41f4b71Sopenharmony_ci // Set necessary AVSession metadata. 76e41f4b71Sopenharmony_ci let metadata: AVSessionManager.AVMetadata = { 77e41f4b71Sopenharmony_ci assetId: '0', // Specified by the application, used to identify the media asset in the application media library. 78e41f4b71Sopenharmony_ci title: 'TITLE', 79e41f4b71Sopenharmony_ci mediaImage: 'IMAGE', 80e41f4b71Sopenharmony_ci artist: 'ARTIST', 81e41f4b71Sopenharmony_ci }; 82e41f4b71Sopenharmony_ci session.setAVMetadata(metadata).then(() => { 83e41f4b71Sopenharmony_ci console.info(`SetAVMetadata successfully`); 84e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 85e41f4b71Sopenharmony_ci console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 86e41f4b71Sopenharmony_ci }); 87e41f4b71Sopenharmony_ci } 88e41f4b71Sopenharmony_ci``` 89e41f4b71Sopenharmony_ci 90e41f4b71Sopenharmony_ci### Setting Lyrics 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ciThe controller provides the UI to show lyrics. The application only needs to set the lyrics content. The controller parses the lyrics content and displays it based on the playback progress. 93e41f4b71Sopenharmony_ci 94e41f4b71Sopenharmony_ci```ts 95e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 96e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 97e41f4b71Sopenharmony_ci 98e41f4b71Sopenharmony_cilet context: Context = getContext(this); 99e41f4b71Sopenharmony_ciasync function setListener() { 100e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 101e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 102e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ci // Set the lyric to AVSession. 105e41f4b71Sopenharmony_ci let metadata: AVSessionManager.AVMetadata = { 106e41f4b71Sopenharmony_ci assetId: '0', 107e41f4b71Sopenharmony_ci title: 'TITLE', 108e41f4b71Sopenharmony_ci mediaImage: 'IMAGE', 109e41f4b71Sopenharmony_ci // The LRC contains two types of elements: time tag + lyrics, and ID tag. 110e41f4b71Sopenharmony_ci // Example: [00:25.44]xxx\r\n[00:26.44]xxx\r\n 111e41f4b71Sopenharmony_ci lyric: "Lyrics in LRC format", 112e41f4b71Sopenharmony_ci }; 113e41f4b71Sopenharmony_ci session.setAVMetadata(metadata).then(() => { 114e41f4b71Sopenharmony_ci console.info(`SetAVMetadata successfully`); 115e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 116e41f4b71Sopenharmony_ci console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 117e41f4b71Sopenharmony_ci }); 118e41f4b71Sopenharmony_ci 119e41f4b71Sopenharmony_ci} 120e41f4b71Sopenharmony_ci``` 121e41f4b71Sopenharmony_ci 122e41f4b71Sopenharmony_ci<!--RP1--> 123e41f4b71Sopenharmony_ci<!--RP1End--> 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ci### Display Tags of Media Assets 126e41f4b71Sopenharmony_ci 127e41f4b71Sopenharmony_ciThe controller displays a special type identifier for long-duration media assets. Currently, only the AudioVivid identifier is displayed. 128e41f4b71Sopenharmony_ci 129e41f4b71Sopenharmony_ciThe application notifies the system of the display tag of the media asset through the AVMetadata during the access, and the controller displays the tag when the media asset is being played. 130e41f4b71Sopenharmony_ci 131e41f4b71Sopenharmony_ci```ts 132e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 133e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 134e41f4b71Sopenharmony_ci 135e41f4b71Sopenharmony_cilet context: Context = getContext(this); 136e41f4b71Sopenharmony_ciasync function setListener() { 137e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 138e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 139e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 140e41f4b71Sopenharmony_ci 141e41f4b71Sopenharmony_ci // Set the media audio source information to AVSession. 142e41f4b71Sopenharmony_ci let metadata: AVSessionManager.AVMetadata = { 143e41f4b71Sopenharmony_ci assetId: '0', 144e41f4b71Sopenharmony_ci title: 'TITLE', 145e41f4b71Sopenharmony_ci mediaImage: 'IMAGE', 146e41f4b71Sopenharmony_ci // The display tag of the audio source is AudioVivid. 147e41f4b71Sopenharmony_ci displayTags: AVSessionManager.DisplayTag.TAG_AUDIO_VIVID, 148e41f4b71Sopenharmony_ci }; 149e41f4b71Sopenharmony_ci session.setAVMetadata(metadata).then(() => { 150e41f4b71Sopenharmony_ci console.info(`SetAVMetadata successfully`); 151e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 152e41f4b71Sopenharmony_ci console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 153e41f4b71Sopenharmony_ci }); 154e41f4b71Sopenharmony_ci} 155e41f4b71Sopenharmony_ci``` 156e41f4b71Sopenharmony_ci 157e41f4b71Sopenharmony_ci## Setting Playback State Information 158e41f4b71Sopenharmony_ci 159e41f4b71Sopenharmony_ci### Setting General State Information 160e41f4b71Sopenharmony_ci 161e41f4b71Sopenharmony_ciThe application can call [setAVPlaybackState()](../../reference/apis-avsession-kit/js-apis-avsession.md#setavplaybackstate10) to set the playback state information to the system so that the information can be displayed in the controller. 162e41f4b71Sopenharmony_ci 163e41f4b71Sopenharmony_ciGenerally, the playback state information includes 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). It changes during the playback. 164e41f4b71Sopenharmony_ci 165e41f4b71Sopenharmony_ci```ts 166e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 167e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 168e41f4b71Sopenharmony_ci 169e41f4b71Sopenharmony_cilet context: Context = getContext(this); 170e41f4b71Sopenharmony_ciasync function setSessionInfo() { 171e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 172e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', 'audio'); 173e41f4b71Sopenharmony_ci 174e41f4b71Sopenharmony_ci // The player logic that triggers changes in the AVSession metadata and playback state information is omitted here. 175e41f4b71Sopenharmony_ci // Set the playback state to paused and set isFavorite to false. 176e41f4b71Sopenharmony_ci let playbackState: AVSessionManager.AVPlaybackState = { 177e41f4b71Sopenharmony_ci state:AVSessionManager.PlaybackState.PLAYBACK_STATE_PAUSE, 178e41f4b71Sopenharmony_ci isFavorite:false 179e41f4b71Sopenharmony_ci }; 180e41f4b71Sopenharmony_ci session.setAVPlaybackState(playbackState, (err: BusinessError) => { 181e41f4b71Sopenharmony_ci if (err) { 182e41f4b71Sopenharmony_ci console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 183e41f4b71Sopenharmony_ci } else { 184e41f4b71Sopenharmony_ci console.info(`SetAVPlaybackState successfully`); 185e41f4b71Sopenharmony_ci } 186e41f4b71Sopenharmony_ci }); 187e41f4b71Sopenharmony_ci} 188e41f4b71Sopenharmony_ci``` 189e41f4b71Sopenharmony_ci 190e41f4b71Sopenharmony_ci### Setting the Progress Bar 191e41f4b71Sopenharmony_ci 192e41f4b71Sopenharmony_ciTo display a progress bar in the controller, the application must set the duration, playback state (pause or play), playback position, and playback speed. The controller displays the progress bar based on the information. 193e41f4b71Sopenharmony_ci 194e41f4b71Sopenharmony_ci```ts 195e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 196e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 197e41f4b71Sopenharmony_ci 198e41f4b71Sopenharmony_cilet context: Context = getContext(this); 199e41f4b71Sopenharmony_ciasync function setListener() { 200e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 201e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 202e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 203e41f4b71Sopenharmony_ci 204e41f4b71Sopenharmony_ci // Set the media resource duration. 205e41f4b71Sopenharmony_ci let metadata: AVSessionManager.AVMetadata = { 206e41f4b71Sopenharmony_ci assetId: '0', 207e41f4b71Sopenharmony_ci title: 'TITLE', 208e41f4b71Sopenharmony_ci mediaImage: 'IMAGE', 209e41f4b71Sopenharmony_ci duration: 23000, // Duration of the media asset, in milliseconds. 210e41f4b71Sopenharmony_ci }; 211e41f4b71Sopenharmony_ci session.setAVMetadata(metadata).then(() => { 212e41f4b71Sopenharmony_ci console.info(`SetAVMetadata successfully`); 213e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 214e41f4b71Sopenharmony_ci console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 215e41f4b71Sopenharmony_ci }); 216e41f4b71Sopenharmony_ci 217e41f4b71Sopenharmony_ci // Set the playback state information, including the playback state, position, speed, and buffered time. 218e41f4b71Sopenharmony_ci let playbackState: AVSessionManager.AVPlaybackState = { 219e41f4b71Sopenharmony_ci state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY, // Playing state. 220e41f4b71Sopenharmony_ci position: { 221e41f4b71Sopenharmony_ci elapsedTime: 1000, // Playback position, in milliseconds. 222e41f4b71Sopenharmony_ci updateTime: new Date().getTime(), // Timestamp when the application updates the current position, in milliseconds. 223e41f4b71Sopenharmony_ci }, 224e41f4b71Sopenharmony_ci speed: 1.0, // Optional. The default value is 1.0. The playback speed is set based on the speed supported by the application. The system does not verify the speed. 225e41f4b71Sopenharmony_ci bufferedTime: 14000, // Optional. Buffered time, in milliseconds. 226e41f4b71Sopenharmony_ci }; 227e41f4b71Sopenharmony_ci session.setAVPlaybackState(playbackState, (err) => { 228e41f4b71Sopenharmony_ci if (err) { 229e41f4b71Sopenharmony_ci console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 230e41f4b71Sopenharmony_ci } else { 231e41f4b71Sopenharmony_ci console.info(`SetAVPlaybackState successfully`); 232e41f4b71Sopenharmony_ci } 233e41f4b71Sopenharmony_ci }); 234e41f4b71Sopenharmony_ci} 235e41f4b71Sopenharmony_ci``` 236e41f4b71Sopenharmony_ci 237e41f4b71Sopenharmony_ciThe controller calculates the playback progress based on the information set by the application. The application does not need to update the playback progress in real time. 238e41f4b71Sopenharmony_ciHowever, it needs to update the playback state when the following information changes to avid calculation errors: 239e41f4b71Sopenharmony_ci 240e41f4b71Sopenharmony_ci- state 241e41f4b71Sopenharmony_ci- position 242e41f4b71Sopenharmony_ci- speed 243e41f4b71Sopenharmony_ci 244e41f4b71Sopenharmony_ciThe application reports the start position of the progress once the actual playback starts. If the playback is in the buffer state, the application can report **AVSessionManager.PlaybackState.PLAYBACK_STATE_BUFFERING** to instruct the system not to update the progress. 245e41f4b71Sopenharmony_ci 246e41f4b71Sopenharmony_ciCertain special processing is required when setting the progress bar. 247e41f4b71Sopenharmony_ci 248e41f4b71Sopenharmony_ci1. Songs that can be previewed 249e41f4b71Sopenharmony_ci 250e41f4b71Sopenharmony_ci (1) The application sets the preview duration, rather than the total duration, for a song. In this case, when the user performs progress control in the controller, the application receives the relative timestamp within the preview duration, rather than that within the total duration. The application needs to calculate the absolute timestamp from the very beginning of the song. 251e41f4b71Sopenharmony_ci 252e41f4b71Sopenharmony_ci (2) The application sets the total duration for a song but requires the system to provide preview, the application can report the start position of the progress when the playback starts, and report the end position when the received seek instruction is not within the preview duration. In the latter case, the playback control progress of the system rebounds. 253e41f4b71Sopenharmony_ci 254e41f4b71Sopenharmony_ci2. Songs that do not support preview 255e41f4b71Sopenharmony_ci 256e41f4b71Sopenharmony_ci If a song cannot be previewed, it cannot be displayed by the application. In this case, the application should set the duration to **-1**, so the system does not display the actual duration. 257e41f4b71Sopenharmony_ci 258e41f4b71Sopenharmony_ci3. Special contents such as ads 259e41f4b71Sopenharmony_ci 260e41f4b71Sopenharmony_ci For media assets with pre-roll or post-roll ads, you are advised to: 261e41f4b71Sopenharmony_ci - Set the ad duration separately. 262e41f4b71Sopenharmony_ci - Set a new duration for the actual content, to distinguish it from the ad. 263e41f4b71Sopenharmony_ci 264e41f4b71Sopenharmony_ci## Registering Control Commands 265e41f4b71Sopenharmony_ci 266e41f4b71Sopenharmony_ciThe application can register different control commands through **on()** to implement control operations in the controller. For details, see the [API reference](../../reference/apis-avsession-kit/js-apis-avsession.md#onplay10). 267e41f4b71Sopenharmony_ci> **NOTE** 268e41f4b71Sopenharmony_ci> 269e41f4b71Sopenharmony_ci> After an AVSession object is created, register control commands supported by the application before activating the object. 270e41f4b71Sopenharmony_ci 271e41f4b71Sopenharmony_ciThe table below lists the control commands supported by media assets. 272e41f4b71Sopenharmony_ci 273e41f4b71Sopenharmony_ci| Control Command| Description | 274e41f4b71Sopenharmony_ci| ------ | -------------------------| 275e41f4b71Sopenharmony_ci| play | Plays the media.| 276e41f4b71Sopenharmony_ci| pause | Pauses the playback.| 277e41f4b71Sopenharmony_ci| stop | Stops the playback.| 278e41f4b71Sopenharmony_ci| playNext | Plays the next media asset.| 279e41f4b71Sopenharmony_ci| playPrevious | Plays the previous media asset.| 280e41f4b71Sopenharmony_ci| fastForward | Fast-forwards.| 281e41f4b71Sopenharmony_ci| rewind | Rewinds.| 282e41f4b71Sopenharmony_ci| playFromAssetId | Plays a media asset with a given asset ID.| 283e41f4b71Sopenharmony_ci| seek | Seeks to a playback position. | 284e41f4b71Sopenharmony_ci| setSpeed | Sets the playback speed.| 285e41f4b71Sopenharmony_ci| setLoopMode | Sets the loop mode.| 286e41f4b71Sopenharmony_ci| toggleFavorite | Favorites or unfavorites a media asset.| 287e41f4b71Sopenharmony_ci| skipToQueueItem | Selects an item in the playlist.| 288e41f4b71Sopenharmony_ci| handleKeyEvent | Sets a key event.| 289e41f4b71Sopenharmony_ci| commonCommand | Customizes a control command.| 290e41f4b71Sopenharmony_ci 291e41f4b71Sopenharmony_ciThe table below lists the control commands for calling applications. 292e41f4b71Sopenharmony_ci 293e41f4b71Sopenharmony_ci| Control Command| Description | 294e41f4b71Sopenharmony_ci| ------ | -------------------------| 295e41f4b71Sopenharmony_ci| answer | Answers a call.| 296e41f4b71Sopenharmony_ci| hangUp | Ends a call.| 297e41f4b71Sopenharmony_ci| toggleCallMute | Mutes or unmutes a call.| 298e41f4b71Sopenharmony_ci 299e41f4b71Sopenharmony_ci### Handling Unsupported Commands 300e41f4b71Sopenharmony_ci 301e41f4b71Sopenharmony_ciIf the application does not support a control command supported by the system, for example, the **playPrevious** command, it can use **off()** to deregister the control command. Then the controller grays out the control page accordingly, so that users know that the control command is not supported. 302e41f4b71Sopenharmony_ci 303e41f4b71Sopenharmony_ci```ts 304e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 305e41f4b71Sopenharmony_ci 306e41f4b71Sopenharmony_cilet context: Context = getContext(this); 307e41f4b71Sopenharmony_ciasync function unregisterSessionListener() { 308e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 309e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 310e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 311e41f4b71Sopenharmony_ci 312e41f4b71Sopenharmony_ci // Cancel the listener of the AVSession object. 313e41f4b71Sopenharmony_ci session.off('play'); 314e41f4b71Sopenharmony_ci session.off('pause'); 315e41f4b71Sopenharmony_ci session.off('stop'); 316e41f4b71Sopenharmony_ci session.off('playNext'); 317e41f4b71Sopenharmony_ci session.off('playPrevious'); 318e41f4b71Sopenharmony_ci} 319e41f4b71Sopenharmony_ci``` 320e41f4b71Sopenharmony_ci 321e41f4b71Sopenharmony_ci### Setting Fast-Forward or Rewind 322e41f4b71Sopenharmony_ci 323e41f4b71Sopenharmony_ciThe application can call APIs to set the fast-forward or rewind intervals in three different ways. It also registers the fast-forward or rewind control command to respond to user operations. 324e41f4b71Sopenharmony_ci 325e41f4b71Sopenharmony_ci```ts 326e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 327e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 328e41f4b71Sopenharmony_ci 329e41f4b71Sopenharmony_cilet context: Context = getContext(this); 330e41f4b71Sopenharmony_ciasync function unregisterSessionListener() { 331e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 332e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 333e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 334e41f4b71Sopenharmony_ci 335e41f4b71Sopenharmony_ci // Set the supported fast-forward or rewind duration for AVSession. 336e41f4b71Sopenharmony_ci let metadata: AVSessionManager.AVMetadata = { 337e41f4b71Sopenharmony_ci assetId: '0', // Specified by the application, used to identify the media asset in the application media library. 338e41f4b71Sopenharmony_ci title: 'TITLE', 339e41f4b71Sopenharmony_ci mediaImage: 'IMAGE', 340e41f4b71Sopenharmony_ci skipIntervals: AVSessionManager.SkipIntervals.SECONDS_10, 341e41f4b71Sopenharmony_ci }; 342e41f4b71Sopenharmony_ci session.setAVMetadata(metadata).then(() => { 343e41f4b71Sopenharmony_ci console.info(`SetAVMetadata successfully`); 344e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 345e41f4b71Sopenharmony_ci console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 346e41f4b71Sopenharmony_ci }); 347e41f4b71Sopenharmony_ci 348e41f4b71Sopenharmony_ci session.on('fastForward', (time ?: number) => { 349e41f4b71Sopenharmony_ci console.info(`on fastForward , do fastForward task`); 350e41f4b71Sopenharmony_ci // do some tasks ··· 351e41f4b71Sopenharmony_ci }); 352e41f4b71Sopenharmony_ci session.on('rewind', (time ?: number) => { 353e41f4b71Sopenharmony_ci console.info(`on rewind , do rewind task`); 354e41f4b71Sopenharmony_ci // do some tasks ··· 355e41f4b71Sopenharmony_ci }); 356e41f4b71Sopenharmony_ci} 357e41f4b71Sopenharmony_ci``` 358e41f4b71Sopenharmony_ci 359e41f4b71Sopenharmony_ci### Favoriting Media Assets 360e41f4b71Sopenharmony_ci 361e41f4b71Sopenharmony_ciTo implement favoriting, a music application must call [on('toggleFavorite')](../../reference/apis-avsession-kit/js-apis-avsession.md#ontogglefavorite10) to register the **toggleFavorite** control command. 362e41f4b71Sopenharmony_ci 363e41f4b71Sopenharmony_ci```ts 364e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 365e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 366e41f4b71Sopenharmony_ci 367e41f4b71Sopenharmony_cilet context: Context = getContext(this); 368e41f4b71Sopenharmony_ciasync function setListener() { 369e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 370e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 371e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 372e41f4b71Sopenharmony_ci session.on('toggleFavorite', (assetId) => { 373e41f4b71Sopenharmony_ci console.info(`on toggleFavorite `); 374e41f4b71Sopenharmony_ci // The application receives the toggleFavorite command and favorites or unfavorites the media asset. 375e41f4b71Sopenharmony_ci 376e41f4b71Sopenharmony_ci // Set the new state to AVSession after the application finishes favoriting or unfavoriting. 377e41f4b71Sopenharmony_ci let playbackState: AVSessionManager.AVPlaybackState = { 378e41f4b71Sopenharmony_ci isFavorite:true, 379e41f4b71Sopenharmony_ci }; 380e41f4b71Sopenharmony_ci session.setAVPlaybackState(playbackState).then(() => { 381e41f4b71Sopenharmony_ci console.info(`SetAVPlaybackState successfully`); 382e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 383e41f4b71Sopenharmony_ci console.info(`SetAVPlaybackState BusinessError: code: ${err.code}, message: ${err.message}`); 384e41f4b71Sopenharmony_ci }); 385e41f4b71Sopenharmony_ci 386e41f4b71Sopenharmony_ci }); 387e41f4b71Sopenharmony_ci} 388e41f4b71Sopenharmony_ci``` 389e41f4b71Sopenharmony_ci 390e41f4b71Sopenharmony_ci### Setting the Loop Mode 391e41f4b71Sopenharmony_ci 392e41f4b71Sopenharmony_ciFor music applications, the controller displays control operations in loop mode by default. Currently, the system supports four fixed [loop modes](../../reference/apis-avsession-kit/js-apis-avsession.md#loopmode10), namely, shuffle, sequential playback, single loop, and playlist loop. After switching the loop mode as instructed, the application needs to report the new loop mode. 393e41f4b71Sopenharmony_ci 394e41f4b71Sopenharmony_ciEven if the application does not support the four fixed loop modes, it must report one of them to the system. 395e41f4b71Sopenharmony_ci 396e41f4b71Sopenharmony_ciRefer to the code snippet below: 397e41f4b71Sopenharmony_ci 398e41f4b71Sopenharmony_ci```ts 399e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 400e41f4b71Sopenharmony_ciimport { BusinessError } from '@kit.BasicServicesKit'; 401e41f4b71Sopenharmony_ci 402e41f4b71Sopenharmony_cilet context: Context = getContext(this); 403e41f4b71Sopenharmony_ciasync function setListener() { 404e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 405e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 406e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 407e41f4b71Sopenharmony_ci 408e41f4b71Sopenharmony_ci // When the application starts or switches the loop mode, it sets the loop mode in use to the AVSession. 409e41f4b71Sopenharmony_ci let playBackState: AVSessionManager.AVPlaybackState = { 410e41f4b71Sopenharmony_ci loopMode: AVSessionManager.LoopMode.LOOP_MODE_SINGLE, 411e41f4b71Sopenharmony_ci }; 412e41f4b71Sopenharmony_ci session.setAVPlaybackState(playBackState).then(() => { 413e41f4b71Sopenharmony_ci console.info(`set AVPlaybackState successfully`); 414e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 415e41f4b71Sopenharmony_ci console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 416e41f4b71Sopenharmony_ci }); 417e41f4b71Sopenharmony_ci 418e41f4b71Sopenharmony_ci // The application listens for loop mode changes. 419e41f4b71Sopenharmony_ci session.on('setLoopMode', (mode) => { 420e41f4b71Sopenharmony_ci console.info(`on setLoopMode ${mode}`); 421e41f4b71Sopenharmony_ci // After receiving the instruction for setting the loop mode, the application determines the next mode. After the switching is complete, the application reports the new loop mode through AVPlaybackState. 422e41f4b71Sopenharmony_ci let playBackState: AVSessionManager.AVPlaybackState = { 423e41f4b71Sopenharmony_ci loopMode: AVSessionManager.LoopMode.LOOP_MODE_SINGLE, 424e41f4b71Sopenharmony_ci }; 425e41f4b71Sopenharmony_ci session.setAVPlaybackState(playBackState).then(() => { 426e41f4b71Sopenharmony_ci console.info(`set AVPlaybackState successfully`); 427e41f4b71Sopenharmony_ci }).catch((err: BusinessError) => { 428e41f4b71Sopenharmony_ci console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 429e41f4b71Sopenharmony_ci }); 430e41f4b71Sopenharmony_ci }); 431e41f4b71Sopenharmony_ci 432e41f4b71Sopenharmony_ci} 433e41f4b71Sopenharmony_ci``` 434e41f4b71Sopenharmony_ci 435e41f4b71Sopenharmony_ci### Performing Progress Control 436e41f4b71Sopenharmony_ci 437e41f4b71Sopenharmony_ciAn application that supports progress display can further supports progress control. To support progress control, the application must respond to the **seek** control command. When users drag the progress bar in the controller, the application receives a callback. Refer to the code snippet below: 438e41f4b71Sopenharmony_ci 439e41f4b71Sopenharmony_ci```ts 440e41f4b71Sopenharmony_ciimport { avSession as AVSessionManager } from '@kit.AVSessionKit'; 441e41f4b71Sopenharmony_ci 442e41f4b71Sopenharmony_cilet context: Context = getContext(this); 443e41f4b71Sopenharmony_ciasync function setListener() { 444e41f4b71Sopenharmony_ci // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 445e41f4b71Sopenharmony_ci let type: AVSessionManager.AVSessionType = 'audio'; 446e41f4b71Sopenharmony_ci let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 447e41f4b71Sopenharmony_ci 448e41f4b71Sopenharmony_ci session.on('seek', (position: number) => { 449e41f4b71Sopenharmony_ci console.info(`on seek , the time is ${JSON.stringify(position)}`); 450e41f4b71Sopenharmony_ci 451e41f4b71Sopenharmony_ci // The seek operation may trigger a long buffering time. You can set the playback state to PLAYBACK_STATE_BUFFERING. 452e41f4b71Sopenharmony_ci let playbackState: AVSessionManager.AVPlaybackState = { 453e41f4b71Sopenharmony_ci state: AVSessionManager.PlaybackState.PLAYBACK_STATE_BUFFERING, // Buffering state. 454e41f4b71Sopenharmony_ci }; 455e41f4b71Sopenharmony_ci session.setAVPlaybackState(playbackState, (err) => { 456e41f4b71Sopenharmony_ci if (err) { 457e41f4b71Sopenharmony_ci console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 458e41f4b71Sopenharmony_ci } else { 459e41f4b71Sopenharmony_ci console.info(`SetAVPlaybackState successfully`); 460e41f4b71Sopenharmony_ci } 461e41f4b71Sopenharmony_ci }); 462e41f4b71Sopenharmony_ci 463e41f4b71Sopenharmony_ci // The application responds to the seek command and seeks to the specified position. 464e41f4b71Sopenharmony_ci 465e41f4b71Sopenharmony_ci // After seeking to the specified position, the application synchronizes the new position to the system. 466e41f4b71Sopenharmony_ci playbackState.state = AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY; // Playing state. 467e41f4b71Sopenharmony_ci playbackState.position = { 468e41f4b71Sopenharmony_ci elapsedTime: position, // Playback position, in milliseconds. 469e41f4b71Sopenharmony_ci updateTime: new Date().getTime(), // Timestamp when the application updates the current position, in milliseconds. 470e41f4b71Sopenharmony_ci } 471e41f4b71Sopenharmony_ci session.setAVPlaybackState(playbackState, (err) => { 472e41f4b71Sopenharmony_ci if (err) { 473e41f4b71Sopenharmony_ci console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 474e41f4b71Sopenharmony_ci } else { 475e41f4b71Sopenharmony_ci console.info(`SetAVPlaybackState successfully`); 476e41f4b71Sopenharmony_ci } 477e41f4b71Sopenharmony_ci }); 478e41f4b71Sopenharmony_ci 479e41f4b71Sopenharmony_ci }); 480e41f4b71Sopenharmony_ci} 481e41f4b71Sopenharmony_ci``` 482e41f4b71Sopenharmony_ci 483e41f4b71Sopenharmony_ci## Adapting to Media Notification 484e41f4b71Sopenharmony_ci 485e41f4b71Sopenharmony_ciCurrently, the system does not provide APIs for proactively sending control notifications to applications. When an application enters the playing state, the system automatically sends a notification and displays the notification in the notification center and on the lock screen. 486e41f4b71Sopenharmony_ci 487e41f4b71Sopenharmony_ci> **NOTE** 488e41f4b71Sopenharmony_ci> 489e41f4b71Sopenharmony_ci> Currently, notifications are displayed for audio AVSession, but not video AVSession. 490e41f4b71Sopenharmony_ci> 491e41f4b71Sopenharmony_ci> The system sends playback control widgets in the notification center and on the lock screen and controls their lifecycle. 492