1# Accessing AVSession 2 3In addition to the implementation of audio and video playback, media applications may need to access AVSession provided by [AVSession Kit](../kit-readme/Readme-Avsession-Kit.md) for display and control purposes. This topic describes typical display and control scenarios of accessing AVSession. 4 5In different access scenarios, different UIs are displayed in the controller of the system, and different specifications are posed for application access processing. 6 7## Scenarios That Require AVSession Access 8 9AVSession 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. 10 11For 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. 12 13To 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. 14 15## Access Process 16 17The process for implementing AVSession access is as follows: 18 191. 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. 202. [Create a background task](#creating-a-background-task). 213. [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. 224. [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). 235. [Register control commands](#registering-control-commands). The control commands include **play**, **pause**, **previous**, **next**, **fastForward**, **rewind**, **toggleFavorite**, **setLoopMode**, and **seek**. 246. Destroy AVSession when the application exits or stops providing service. 25 26## Creating AVSession 27 28[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. 29 30- For audio AVSession, the controller provides the following control buttons: favorite, previous, play/pause, next, and loop mode. 31 32- For video AVSession, the controller provides the following control buttons: rewind, previous, play/pause, next, and fast-forward. 33 34- For voice_call AVSession, the application is not displayed in the controller. 35 36Refer to the code snippet below: 37 38```ts 39 import AVSessionManager from '@ohos.multimedia.avsession'; 40 41 // Start to create and activate an AVSession object. 42 // Create an AVSession object. 43 let context: Context = getContext(this); 44 async function createSession() { 45 let type: AVSessionManager.AVSessionType = 'audio'; 46 let session = await AVSessionManager.createAVSession(context,'SESSION_NAME', type); 47 48 // Call activate() after the metadata and control commands are registered. 49 await session.activate(); 50 console.info(`session create done : sessionId : ${session.sessionId}`); 51 } 52``` 53 54## Creating a Background Task 55 56To 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. 57 58Media playback applications must request a continuous task of the [AUDIO_PLAYBACK](../reference/apis-backgroundtasks-kit/js-apis-resourceschedule-backgroundTaskManager.md#backgroundmode) background mode. 59 60 61## Setting Metadata 62 63### Setting Common Metadata 64 65The 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. 66 67```ts 68 import AVSessionManager from '@ohos.multimedia.avsession'; 69 import { BusinessError } from '@ohos.base'; 70 71 let context: Context = getContext(this); 72 async function setSessionInfo() { 73 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 74 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', 'audio'); 75 // Set necessary AVSession metadata. 76 let metadata: AVSessionManager.AVMetadata = { 77 assetId: '0', // Specified by the application, used to identify the media asset in the application media library. 78 title: 'TITLE', 79 artist: 'ARTIST' 80 }; 81 session.setAVMetadata(metadata).then(() => { 82 console.info(`SetAVMetadata successfully`); 83 }).catch((err: BusinessError) => { 84 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 85 }); 86 } 87``` 88### Setting Lyrics 89 90The 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. 91 92```ts 93 import AVSessionManager from '@ohos.multimedia.avsession'; 94 95 let context: Context = getContext(this); 96 async function setListener() { 97 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 98 let type: AVSessionManager.AVSessionType = 'audio'; 99 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 100 101 // Set the lyric to AVSession. 102 let metadata: AVSessionManager.AVMetadata = { 103 assetId: '0', 104 lyric: 'http://www.test.lyric', 105 }; 106 session.setAVMetadata(metadata).then(() => { 107 console.info(`SetAVMetadata successfully`); 108 }).catch((err: BusinessError) => { 109 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 110 }); 111 112 } 113``` 114 115### Display Tags of Media Assets 116The controller displays a special type identifier for long-duration media assets. Currently, only the AudioVivid identifier is displayed. 117 118The 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. 119 120```ts 121 import AVSessionManager from '@ohos.multimedia.avsession'; 122 123 let context: Context = getContext(this); 124 async function setListener() { 125 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 126 let type: AVSessionManager.AVSessionType = 'audio'; 127 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 128 129 // Set the media audio source information to AVSession. 130 let metadata: AVSessionManager.AVMetadata = { 131 assetId: '0', 132 // The display tag of the audio source is AudioVivid. 133 displayTags: AVSessionManager.DisplayTag.TAG_AUDIO_VIVID, 134 }; 135 session.setAVMetadata(metadata).then(() => { 136 console.info(`SetAVMetadata successfully`); 137 }).catch((err: BusinessError) => { 138 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 139 }); 140 141 } 142``` 143 144## Setting Playback State Information 145 146### Setting General State Information 147 148The 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. 149 150Generally, 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. 151 152```ts 153 import AVSessionManager from '@ohos.multimedia.avsession'; 154 import { BusinessError } from '@ohos.base'; 155 156 let context: Context = getContext(this); 157 async function setSessionInfo() { 158 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 159 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', 'audio'); 160 161 // The player logic that triggers changes in the AVSession metadata and playback state information is omitted here. 162 // Set the playback state to paused and set isFavorite to false. 163 let playbackState: AVSessionManager.AVPlaybackState = { 164 state:AVSessionManager.PlaybackState.PLAYBACK_STATE_PAUSE, 165 isFavorite:false 166 }; 167 session.setAVPlaybackState(playbackState, (err) => { 168 if (err) { 169 console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 170 } else { 171 console.info(`SetAVPlaybackState successfully`); 172 } 173 }); 174 } 175``` 176 177### Setting the Progress Bar 178 179To 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. 180 181```ts 182 import AVSessionManager from '@ohos.multimedia.avsession'; 183 184 let context: Context = getContext(this); 185 async function setListener() { 186 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 187 let type: AVSessionManager.AVSessionType = 'audio'; 188 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 189 190 // Set the playback state information, including the playback state, position, speed, buffered time, and duration. 191 let playbackState: AVSessionManager.AVPlaybackState = { 192 state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY, // Playing state. 193 position: { 194 elapsedTime: 1000, // Playback position, in milliseconds. 195 updateTime: 30000, // Timestamp when the application updates the current position, in milliseconds. 196 } 197 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. 198 bufferedTime: 14000, // Optional. Buffered time, in milliseconds. 199 duration: 23000, // Duration of the media asset, in milliseconds. 200 }; 201 session.setAVPlaybackState(playbackState, (err) => { 202 if (err) { 203 console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 204 } else { 205 console.info(`SetAVPlaybackState successfully`); 206 } 207 }); 208 } 209``` 210 211The 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. 212However, it needs to update the playback state when the following information changes to avid calculation errors: 213 214- state 215- position 216- speed 217 218Certain special processing is required when setting the progress bar. 219 2201. Songs that can be previewed 221 222 If a VIP song can be previewed, the application should set the preview duration of the song, rather than the total duration. 223 224 If only the preview duration is set, when the user triggers 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. 225 2262. Songs that do not support preview 227 228 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. 229 2303. Special contents such as ads 231 232 For media assets with pre-roll or post-roll ads, you are advised to: 233 - Set the ad duration separately. 234 - Set a new duration for the actual content, to distinguish it from the ad. 235 236## Registering Control Commands 237 238The 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). 239> **NOTE** 240> 241> After an AVSession object is created, register control commands supported by the application before activating the object. 242 243The table below lists the control commands supported by media assets. 244 245| Control Command| Description | 246| ------ | -------------------------| 247| play | Plays the media.| 248| pause | Pauses the playback.| 249| stop | Stops the playback.| 250| playNext | Plays the next media asset.| 251| playPrevious | Plays the previous media asset.| 252| fastForward | Fast-forwards.| 253| rewind | Rewinds.| 254| playFromAssetId | Plays a media asset with a given asset ID.| 255| seek | Seeks to a playback position. | 256| setSpeed | Sets the playback speed.| 257| setLoopMode | Sets the loop mode.| 258| toggleFavorite | Favorites or unfavorites a media asset.| 259| skipToQueueItem | Selects an item in the playlist.| 260| handleKeyEvent | Sets a key event.| 261| commonCommand | Customizes a control command.| 262 263The table below lists the control commands for calling applications. 264 265| Control Command| Description | 266| ------ | -------------------------| 267| answer | Answers a call.| 268| hangUp | Ends a call.| 269| toggleCallMute | Mutes or unmutes a call.| 270 271### Handling Unsupported Commands 272 273If 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. 274 275```ts 276import AVSessionManager from '@ohos.multimedia.avsession'; 277 278let context: Context = getContext(this); 279async function unregisterSessionListener() { 280 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 281 let type: AVSessionManager.AVSessionType = 'audio'; 282 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 283 284 // Cancel the listener of the AVSession object. 285 session.off('play'); 286 session.off('pause'); 287 session.off('stop'); 288 session.off('playNext'); 289 session.off('playPrevious'); 290} 291``` 292 293### Setting Fast-Forward or Rewind 294 295The 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. 296 297```ts 298import AVSessionManager from '@ohos.multimedia.avsession'; 299 300let context: Context = getContext(this); 301async function unregisterSessionListener() { 302 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 303 let type: AVSessionManager.AVSessionType = 'audio'; 304 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 305 306 // Set the supported fast-forward or rewind duration for AVSession. 307 let metadata: AVSessionManager.AVMetadata = { 308 assetId: '0', // Specified by the application, used to identify the media asset in the application media library. 309 skipIntervals: SkipIntervals.SECONDS_10, 310 }; 311 session.setAVMetadata(metadata).then(() => { 312 console.info(`SetAVMetadata successfully`); 313 }).catch((err: BusinessError) => { 314 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 315 }); 316 317 session.on('fastForward', (time ?: number) => { 318 console.info(`on fastForward , do fastForward task`); 319 // do some tasks ··· 320 }); 321 session.on('rewind', (time ?: number) => { 322 console.info(`on rewind , do rewind task`); 323 // do some tasks ··· 324 }); 325} 326``` 327 328### Favoriting Media Assets 329 330To implement favoriting, a music application must call [on('toggleFavorite')](../reference/apis-avsession-kit/js-apis-avsession.md#ontogglefavorite10) to register the **toggleFavorite** control command. 331 332```ts 333 import AVSessionManager from '@ohos.multimedia.avsession'; 334 335 let context: Context = getContext(this); 336 async function setListener() { 337 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 338 let type: AVSessionManager.AVSessionType = 'audio'; 339 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 340 session.on('toggleFavorite', (assetId) => { 341 console.info(`on toggleFavorite `); 342 // The application receives the toggleFavorite command and favorites or unfavorites the media asset. 343 344 // Set the new state to AVSession after the application finishes favoriting or unfavoriting. 345 let playbackState: avSession.AVPlaybackState = { 346 isFavorite:true, 347 }; 348 session.setAVPlaybackState(playbackState).then(() => { 349 console.info(`SetAVPlaybackState successfully`); 350 }).catch((err: BusinessError) => { 351 console.info(`SetAVPlaybackState BusinessError: code: ${err.code}, message: ${err.message}`); 352 }); 353 354 }); 355 } 356``` 357 358### Setting the Loop Mode 359 360For 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. The controller notifies the application of the loop mode changes, and the application responds accordingly. 361 362Refer to the code snippet below: 363 364```ts 365 import AVSessionManager from '@ohos.multimedia.avsession'; 366 367 let context: Context = getContext(this); 368 async function setListener() { 369 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 370 let type: AVSessionManager.AVSessionType = 'audio'; 371 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 372 373 // When the application starts, it sets the loop mode to AVSession. 374 let metadata: AVSessionManager.AVMetadata = { 375 assetId: '0', // Specified by the application, used to identify the media asset in the application media library. 376 loopMode: AVSessionManager.LoopMode.LOOP_MODE_SINGLE, 377 }; 378 session.setAVMetadata(metadata).then(() => { 379 console.info(`SetAVMetadata successfully`); 380 }).catch((err: BusinessError) => { 381 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 382 }); 383 384 // The application listens for loop mode changes. 385 session.on('setLoopMode', (mode) => { 386 console.info(`on setLoopMode ${mode}`); 387 // After receiving the setLoopMode command, the application switches to the corresponding loop mode. 388 }); 389 390 } 391``` 392 393### Performing Progress Control 394 395An 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: 396 397```ts 398 import AVSessionManager from '@ohos.multimedia.avsession'; 399 400 let context: Context = getContext(this); 401 async function setListener() { 402 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 403 let type: AVSessionManager.AVSessionType = 'audio'; 404 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 405 406 session.on('seek', (time: number) => { 407 console.info(`on seek , the time is ${JSON.stringify(time)}`); 408 409 // The seek operation may trigger a long buffering time. Generally, set the playback state to PLAYBACK_STATE_BUFFERING. 410 let playbackState: AVSessionManager.AVPlaybackState = { 411 state: AVSessionManager.PlaybackState.PLAYBACK_STATE_BUFFERING, // Buffering state. 412 }; 413 session.setAVPlaybackState(playbackState, (err) => { 414 if (err) { 415 console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 416 } else { 417 console.info(`SetAVPlaybackState successfully`); 418 } 419 }); 420 421 // The application responds to the seek command and seeks to the specified position. 422 423 // After seeking to the specified position, the application synchronizes the new position to the system. 424 playbackState.state = AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY; // Playing state. 425 playbackState.position = { 426 elapsedTime: 4000, // Playback position, in milliseconds. 427 updateTime: 34000, // Timestamp when the application updates the current position, in milliseconds. 428 } 429 session.setAVPlaybackState(playbackState, (err) => { 430 if (err) { 431 console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 432 } else { 433 console.info(`SetAVPlaybackState successfully`); 434 } 435 }); 436 437 }); 438 } 439``` 440 441## Adapting to Media Notification 442 443Currently, 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. 444 445> **NOTE** 446> 447> Currently, notifications are displayed for audio AVSession, but not video AVSession. 448> 449> The system sends playback control widgets in the notification center and on the lock screen and controls their lifecycle. 450