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 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 39import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 40 41// Start to create and activate an AVSession object. 42// Create an AVSession object. 43let context: Context = getContext(this); 44async 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 68import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 69import { BusinessError } from '@kit.BasicServicesKit'; 70 71let context: Context = getContext(this); 72async 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 mediaImage: 'IMAGE', 80 artist: 'ARTIST', 81 }; 82 session.setAVMetadata(metadata).then(() => { 83 console.info(`SetAVMetadata successfully`); 84 }).catch((err: BusinessError) => { 85 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 86 }); 87 } 88``` 89 90### Setting Lyrics 91 92The 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. 93 94```ts 95import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 96import { BusinessError } from '@kit.BasicServicesKit'; 97 98let context: Context = getContext(this); 99async function setListener() { 100 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 101 let type: AVSessionManager.AVSessionType = 'audio'; 102 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 103 104 // Set the lyric to AVSession. 105 let metadata: AVSessionManager.AVMetadata = { 106 assetId: '0', 107 title: 'TITLE', 108 mediaImage: 'IMAGE', 109 // The LRC contains two types of elements: time tag + lyrics, and ID tag. 110 // Example: [00:25.44]xxx\r\n[00:26.44]xxx\r\n 111 lyric: "Lyrics in LRC format", 112 }; 113 session.setAVMetadata(metadata).then(() => { 114 console.info(`SetAVMetadata successfully`); 115 }).catch((err: BusinessError) => { 116 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 117 }); 118 119} 120``` 121 122<!--RP1--> 123<!--RP1End--> 124 125### Display Tags of Media Assets 126 127The controller displays a special type identifier for long-duration media assets. Currently, only the AudioVivid identifier is displayed. 128 129The 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. 130 131```ts 132import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 133import { BusinessError } from '@kit.BasicServicesKit'; 134 135let context: Context = getContext(this); 136async function setListener() { 137 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 138 let type: AVSessionManager.AVSessionType = 'audio'; 139 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 140 141 // Set the media audio source information to AVSession. 142 let metadata: AVSessionManager.AVMetadata = { 143 assetId: '0', 144 title: 'TITLE', 145 mediaImage: 'IMAGE', 146 // The display tag of the audio source is AudioVivid. 147 displayTags: AVSessionManager.DisplayTag.TAG_AUDIO_VIVID, 148 }; 149 session.setAVMetadata(metadata).then(() => { 150 console.info(`SetAVMetadata successfully`); 151 }).catch((err: BusinessError) => { 152 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 153 }); 154} 155``` 156 157## Setting Playback State Information 158 159### Setting General State Information 160 161The 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. 162 163Generally, 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. 164 165```ts 166import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 167import { BusinessError } from '@kit.BasicServicesKit'; 168 169let context: Context = getContext(this); 170async function setSessionInfo() { 171 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 172 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', 'audio'); 173 174 // The player logic that triggers changes in the AVSession metadata and playback state information is omitted here. 175 // Set the playback state to paused and set isFavorite to false. 176 let playbackState: AVSessionManager.AVPlaybackState = { 177 state:AVSessionManager.PlaybackState.PLAYBACK_STATE_PAUSE, 178 isFavorite:false 179 }; 180 session.setAVPlaybackState(playbackState, (err: BusinessError) => { 181 if (err) { 182 console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 183 } else { 184 console.info(`SetAVPlaybackState successfully`); 185 } 186 }); 187} 188``` 189 190### Setting the Progress Bar 191 192To 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. 193 194```ts 195import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 196import { BusinessError } from '@kit.BasicServicesKit'; 197 198let context: Context = getContext(this); 199async function setListener() { 200 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 201 let type: AVSessionManager.AVSessionType = 'audio'; 202 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 203 204 // Set the media resource duration. 205 let metadata: AVSessionManager.AVMetadata = { 206 assetId: '0', 207 title: 'TITLE', 208 mediaImage: 'IMAGE', 209 duration: 23000, // Duration of the media asset, in milliseconds. 210 }; 211 session.setAVMetadata(metadata).then(() => { 212 console.info(`SetAVMetadata successfully`); 213 }).catch((err: BusinessError) => { 214 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 215 }); 216 217 // Set the playback state information, including the playback state, position, speed, and buffered time. 218 let playbackState: AVSessionManager.AVPlaybackState = { 219 state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY, // Playing state. 220 position: { 221 elapsedTime: 1000, // Playback position, in milliseconds. 222 updateTime: new Date().getTime(), // Timestamp when the application updates the current position, in milliseconds. 223 }, 224 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. 225 bufferedTime: 14000, // Optional. Buffered time, in milliseconds. 226 }; 227 session.setAVPlaybackState(playbackState, (err) => { 228 if (err) { 229 console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 230 } else { 231 console.info(`SetAVPlaybackState successfully`); 232 } 233 }); 234} 235``` 236 237The 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. 238However, it needs to update the playback state when the following information changes to avid calculation errors: 239 240- state 241- position 242- speed 243 244The 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. 245 246Certain special processing is required when setting the progress bar. 247 2481. Songs that can be previewed 249 250 (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. 251 252 (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. 253 2542. Songs that do not support preview 255 256 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. 257 2583. Special contents such as ads 259 260 For media assets with pre-roll or post-roll ads, you are advised to: 261 - Set the ad duration separately. 262 - Set a new duration for the actual content, to distinguish it from the ad. 263 264## Registering Control Commands 265 266The 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). 267> **NOTE** 268> 269> After an AVSession object is created, register control commands supported by the application before activating the object. 270 271The table below lists the control commands supported by media assets. 272 273| Control Command| Description | 274| ------ | -------------------------| 275| play | Plays the media.| 276| pause | Pauses the playback.| 277| stop | Stops the playback.| 278| playNext | Plays the next media asset.| 279| playPrevious | Plays the previous media asset.| 280| fastForward | Fast-forwards.| 281| rewind | Rewinds.| 282| playFromAssetId | Plays a media asset with a given asset ID.| 283| seek | Seeks to a playback position. | 284| setSpeed | Sets the playback speed.| 285| setLoopMode | Sets the loop mode.| 286| toggleFavorite | Favorites or unfavorites a media asset.| 287| skipToQueueItem | Selects an item in the playlist.| 288| handleKeyEvent | Sets a key event.| 289| commonCommand | Customizes a control command.| 290 291The table below lists the control commands for calling applications. 292 293| Control Command| Description | 294| ------ | -------------------------| 295| answer | Answers a call.| 296| hangUp | Ends a call.| 297| toggleCallMute | Mutes or unmutes a call.| 298 299### Handling Unsupported Commands 300 301If 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. 302 303```ts 304import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 305 306let context: Context = getContext(this); 307async function unregisterSessionListener() { 308 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 309 let type: AVSessionManager.AVSessionType = 'audio'; 310 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 311 312 // Cancel the listener of the AVSession object. 313 session.off('play'); 314 session.off('pause'); 315 session.off('stop'); 316 session.off('playNext'); 317 session.off('playPrevious'); 318} 319``` 320 321### Setting Fast-Forward or Rewind 322 323The 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. 324 325```ts 326import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 327import { BusinessError } from '@kit.BasicServicesKit'; 328 329let context: Context = getContext(this); 330async function unregisterSessionListener() { 331 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 332 let type: AVSessionManager.AVSessionType = 'audio'; 333 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 334 335 // Set the supported fast-forward or rewind duration for AVSession. 336 let metadata: AVSessionManager.AVMetadata = { 337 assetId: '0', // Specified by the application, used to identify the media asset in the application media library. 338 title: 'TITLE', 339 mediaImage: 'IMAGE', 340 skipIntervals: AVSessionManager.SkipIntervals.SECONDS_10, 341 }; 342 session.setAVMetadata(metadata).then(() => { 343 console.info(`SetAVMetadata successfully`); 344 }).catch((err: BusinessError) => { 345 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 346 }); 347 348 session.on('fastForward', (time ?: number) => { 349 console.info(`on fastForward , do fastForward task`); 350 // do some tasks ··· 351 }); 352 session.on('rewind', (time ?: number) => { 353 console.info(`on rewind , do rewind task`); 354 // do some tasks ··· 355 }); 356} 357``` 358 359### Favoriting Media Assets 360 361To implement favoriting, a music application must call [on('toggleFavorite')](../../reference/apis-avsession-kit/js-apis-avsession.md#ontogglefavorite10) to register the **toggleFavorite** control command. 362 363```ts 364import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 365import { BusinessError } from '@kit.BasicServicesKit'; 366 367let context: Context = getContext(this); 368async 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 session.on('toggleFavorite', (assetId) => { 373 console.info(`on toggleFavorite `); 374 // The application receives the toggleFavorite command and favorites or unfavorites the media asset. 375 376 // Set the new state to AVSession after the application finishes favoriting or unfavoriting. 377 let playbackState: AVSessionManager.AVPlaybackState = { 378 isFavorite:true, 379 }; 380 session.setAVPlaybackState(playbackState).then(() => { 381 console.info(`SetAVPlaybackState successfully`); 382 }).catch((err: BusinessError) => { 383 console.info(`SetAVPlaybackState BusinessError: code: ${err.code}, message: ${err.message}`); 384 }); 385 386 }); 387} 388``` 389 390### Setting the Loop Mode 391 392For 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. 393 394Even if the application does not support the four fixed loop modes, it must report one of them to the system. 395 396Refer to the code snippet below: 397 398```ts 399import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 400import { BusinessError } from '@kit.BasicServicesKit'; 401 402let context: Context = getContext(this); 403async function setListener() { 404 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 405 let type: AVSessionManager.AVSessionType = 'audio'; 406 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 407 408 // When the application starts or switches the loop mode, it sets the loop mode in use to the AVSession. 409 let playBackState: AVSessionManager.AVPlaybackState = { 410 loopMode: AVSessionManager.LoopMode.LOOP_MODE_SINGLE, 411 }; 412 session.setAVPlaybackState(playBackState).then(() => { 413 console.info(`set AVPlaybackState successfully`); 414 }).catch((err: BusinessError) => { 415 console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 416 }); 417 418 // The application listens for loop mode changes. 419 session.on('setLoopMode', (mode) => { 420 console.info(`on setLoopMode ${mode}`); 421 // 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. 422 let playBackState: AVSessionManager.AVPlaybackState = { 423 loopMode: AVSessionManager.LoopMode.LOOP_MODE_SINGLE, 424 }; 425 session.setAVPlaybackState(playBackState).then(() => { 426 console.info(`set AVPlaybackState successfully`); 427 }).catch((err: BusinessError) => { 428 console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 429 }); 430 }); 431 432} 433``` 434 435### Performing Progress Control 436 437An 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: 438 439```ts 440import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 441 442let context: Context = getContext(this); 443async function setListener() { 444 // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. 445 let type: AVSessionManager.AVSessionType = 'audio'; 446 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 447 448 session.on('seek', (position: number) => { 449 console.info(`on seek , the time is ${JSON.stringify(position)}`); 450 451 // The seek operation may trigger a long buffering time. You can set the playback state to PLAYBACK_STATE_BUFFERING. 452 let playbackState: AVSessionManager.AVPlaybackState = { 453 state: AVSessionManager.PlaybackState.PLAYBACK_STATE_BUFFERING, // Buffering state. 454 }; 455 session.setAVPlaybackState(playbackState, (err) => { 456 if (err) { 457 console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 458 } else { 459 console.info(`SetAVPlaybackState successfully`); 460 } 461 }); 462 463 // The application responds to the seek command and seeks to the specified position. 464 465 // After seeking to the specified position, the application synchronizes the new position to the system. 466 playbackState.state = AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY; // Playing state. 467 playbackState.position = { 468 elapsedTime: position, // Playback position, in milliseconds. 469 updateTime: new Date().getTime(), // Timestamp when the application updates the current position, in milliseconds. 470 } 471 session.setAVPlaybackState(playbackState, (err) => { 472 if (err) { 473 console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); 474 } else { 475 console.info(`SetAVPlaybackState successfully`); 476 } 477 }); 478 479 }); 480} 481``` 482 483## Adapting to Media Notification 484 485Currently, the system does not provide APIs for proactively sending control notifications to applications. When an application that has integrated the media controller enters the playing state, the system automatically sends a notification and displays the notification in the notification center and on the lock screen. 486 487> **NOTE** 488> 489> The system sends playback control widgets in the notification center and on the lock screen and controls their lifecycle. 490 491## Adapting to Bluetooth and Wired Key Events 492 493Currently, the system does not provide APIs for listening for multimodal key events for applications. If an application needs to listen for media key events from Bluetooth and wired headsets, the application can register control commands with AVSession. AVSession provides the following two methods for implementation: 494- Method 1 (recommended) 495 496 Integrate the media controller based on service requirements, [register the required control commands](#registering-control-commands), and implement the corresponding functionalities. AVSession listens for multimodal key events, converts them into AVSession control commands, and sends them to the application. The application does not need to differentiate between various key events. Instead, it processes the key events based on the callback of AVSession. Implementing play and pause functions through this method also adapts to the wear detection of Bluetooth headsets, with play and pause commands received upon wearing or removing both earpieces. Currently, the following AVSession control commands can be converted: 497 | Control Command| Description | 498 | ------ | -------------------------| 499 | play | Plays the media.| 500 | pause | Pauses the playback.| 501 | stop | Stops the playback.| 502 | playNext | Plays the next media asset.| 503 | playPrevious | Plays the previous media asset.| 504 | fastForward | Fast-forwards.| 505 | rewind | Rewinds.| 506 507 ```ts 508 import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 509 510 let context: Context = getContext(this); 511 async function setListenerForMesFromController() { 512 let type: AVSessionManager.AVSessionType = 'audio'; 513 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 514 // Set the necessary media information. This step is mandatory. Otherwise, the application cannot receive control events. 515 let metadata: AVSessionManager.AVMetadata = { 516 assetId: '0', // Specified by the application, used to identify the media asset in the application media library. 517 title: 'TITLE', 518 mediaImage: 'IMAGE', 519 artist: 'ARTIST' 520 }; 521 session.setAVMetadata(metadata).then(() => { 522 console.info(`SetAVMetadata successfully`); 523 }).catch((err: BusinessError) => { 524 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 525 }); 526 // Generally, logic processing on the player is implemented in the listener. 527 // After the processing is complete, use the setter to synchronize the playback information. For details, see the code snippet above. 528 session.on('play', () => { 529 console.info(`on play , do play task`); 530 // 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. 531 // After the processing is complete, call SetAVPlayState to report the playback state. 532 }); 533 session.on('pause', () => { 534 console.info(`on pause , do pause task`); 535 // 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. 536 // After the processing is complete, call SetAVPlayState to report the playback state. 537 }); 538 } 539 ``` 540 541- Method 2 542 543 Register the [HandleMediaKeyEvent](../../reference/apis-avsession-kit/js-apis-avsession.md#onhandlekeyevent10) callback through AVSession. The callback directly forwards the [KeyEvent](../../reference/apis-input-kit/js-apis-keyevent.md). The application is required to identify the type of the key event and implement the corresponding functionalities. Currently, the following key events can be forwarded: 544 | Key Type ([KeyCode](../../reference/apis-input-kit/js-apis-keycode.md#keycode))| Description | 545 | ------ | -------------------------| 546 | KEYCODE_MEDIA_PLAY_PAUSE | Play/Pause key. | 547 | KEYCODE_MEDIA_STOP | Stop key. | 548 | KEYCODE_MEDIA_NEXT | Next key. | 549 | KEYCODE_MEDIA_PREVIOUS | Previous key. | 550 | KEYCODE_MEDIA_REWIND | Rewind key. | 551 | KEYCODE_MEDIA_FAST_FORWARD | Fast forward key. | 552 | KEYCODE_MEDIA_PLAY | Play key. | 553 | KEYCODE_MEDIA_PAUSE | Pause key. | 554 555 ```ts 556 import { avSession as AVSessionManager } from '@kit.AVSessionKit'; 557 558 let context: Context = getContext(this); 559 async function setListenerForMesFromController() { 560 let type: AVSessionManager.AVSessionType = 'audio'; 561 let session = await AVSessionManager.createAVSession(context, 'SESSION_NAME', type); 562 // Set the necessary media information. This step is mandatory. Otherwise, the application cannot receive key events. 563 let metadata: AVSessionManager.AVMetadata = { 564 assetId: '0', // Specified by the application, used to identify the media asset in the application media library. 565 title: 'TITLE', 566 mediaImage: 'IMAGE', 567 artist: 'ARTIST' 568 }; 569 session.setAVMetadata(metadata).then(() => { 570 console.info(`SetAVMetadata successfully`); 571 }).catch((err: BusinessError) => { 572 console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); 573 }); 574 session.on('handleKeyEvent', (event) => { 575 // Parse the key code. The application must perform logic processing on the player based on the key code. 576 console.info(`on handleKeyEvent, keyCode=${event.key.code}`); 577 }); 578 } 579 ``` 580 581> **NOTE** 582> 583> 1. Both methods require the accurate configuration of media information AVMetadata and the registration of corresponding control interfaces to receive control commands and key events. 584> 2. Choose either method for integration. Method 1 is recommended. 585 586<!--RP2--> 587<!--RP2End--> 588