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