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