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