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