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