diff --git a/en/application-dev/media/audio-playback-concurrency.md b/en/application-dev/media/audio-playback-concurrency.md index 0b36594f6bef62c7ba7588bc8977af67609a6c9d..fee7e776d68914ad376e01b8fe40ee84e3da4224 100644 --- a/en/application-dev/media/audio-playback-concurrency.md +++ b/en/application-dev/media/audio-playback-concurrency.md @@ -14,7 +14,7 @@ The audio interruption policy determines the operations (for example, pause, res Two audio interruption modes, specified by [InterruptMode](../reference/apis/js-apis-audio.md#interruptmode9), are preset in the audio interruption policy: -- **SHARED_MODE**: Multiple audio streams created by an application share one audio focus. The concurrency rules between these audio streams are determined by the application, without the use of the audio interruption policy. However, if another application needs to play audio while one of these audio streams is being played, the audio interruption policy is triggered. +- **SHARE_MODE**: Multiple audio streams created by an application share one audio focus. The concurrency rules between these audio streams are determined by the application, without the use of the audio interruption policy. However, if another application needs to play audio while one of these audio streams is being played, the audio interruption policy is triggered. - **INDEPENDENT_MODE**: Each audio stream created by an application has an independent audio focus. When multiple audio streams are played concurrently, the audio interruption policy is triggered. diff --git a/en/application-dev/media/audio-playback-overview.md b/en/application-dev/media/audio-playback-overview.md index d17970d6de9b8b238db74d971ad5f58c605462eb..5ef7a6f9c4d08719a71c9e07f34fa1104802fcc6 100644 --- a/en/application-dev/media/audio-playback-overview.md +++ b/en/application-dev/media/audio-playback-overview.md @@ -8,7 +8,7 @@ OpenHarmony provides multiple classes for you to develop audio playback applicat - [AudioRenderer](using-audiorenderer-for-playback.md): provides ArkTS and JS API to implement audio output. It supports only the PCM format and requires applications to continuously write audio data. The applications can perform data preprocessing, for example, setting the sampling rate and bit width of audio files, before audio input. This class can be used to develop more professional and diverse playback applications. To use this class, you must have basic audio processing knowledge. -- [OpenSLES](using-opensl-es-for-playback.md): provides a set of standard, cross-platform, yet unique native audio APIs. It supports audio output in PCM format and is applicable to playback applications that are ported from other embedded platforms or that implements audio output at the native layer. +- [OpenSL ES](using-opensl-es-for-playback.md): provides a set of standard, cross-platform, yet unique native audio APIs. It supports audio output in PCM format and is applicable to playback applications that are ported from other embedded platforms or that implements audio output at the native layer. - [TonePlayer](using-toneplayer-for-playback.md): provides ArkTS and JS API to implement the playback of dialing tones and ringback tones. It can be used to play the content selected from a fixed type range, without requiring the input of media assets or audio data. This class is application to specific scenarios where dialing tones and ringback tones are played. is available only to system applications. diff --git a/en/application-dev/media/audio-recording-overview.md b/en/application-dev/media/audio-recording-overview.md index 698255fddd78d98f9e635b16b3db94e6980bd4a0..2c6fb6fe5b8ffd0e82478d450e64bfc0e10257c6 100644 --- a/en/application-dev/media/audio-recording-overview.md +++ b/en/application-dev/media/audio-recording-overview.md @@ -8,7 +8,7 @@ OpenHarmony provides multiple classes for you to develop audio recording applica - [AudioCapturer](using-audiocapturer-for-recording.md): provides ArkTS and JS API to implement audio input. It supports only the PCM format and requires applications to continuously read audio data. The application can perform data processing after audio output. This class can be used to develop more professional and diverse recording applications. To use this class, you must have basic audio processing knowledge. -- [OpenSLES](using-opensl-es-for-recording.md): provides a set of standard, cross-platform, yet unique native audio APIs. It supports audio input in PCM format and is applicable to recording applications that are ported from other embedded platforms or that implements audio input at the native layer. +- [OpenSL ES](using-opensl-es-for-recording.md): provides a set of standard, cross-platform, yet unique native audio APIs. It supports audio input in PCM format and is applicable to recording applications that are ported from other embedded platforms or that implements audio input at the native layer. ## Precautions for Developing Audio Recording Applications diff --git a/en/application-dev/media/avplayer-avrecorder-overview.md b/en/application-dev/media/avplayer-avrecorder-overview.md index 051ca3b66ce1839046a2e783a8c274c304625045..3bf9b785b93a32b60b73c902449b9b019e651a2b 100644 --- a/en/application-dev/media/avplayer-avrecorder-overview.md +++ b/en/application-dev/media/avplayer-avrecorder-overview.md @@ -59,6 +59,7 @@ The table below lists the supported protocols. | -------- | -------- | | Local VOD| The file descriptor is supported, but the file path is not.| | Network VoD| HTTP, HTTPS, and HLS are supported.| +| Live webcasting| HLS is supported.| The table below lists the supported audio playback formats. diff --git a/en/application-dev/media/figures/audiocapturer-status-change.png b/en/application-dev/media/figures/audiocapturer-status-change.png index aadbc4fb6470b7cdc0f399ee5954a96c01a7f7c3..ff76a8414f7a254af7d2796e44f2c2555dc9185f 100644 Binary files a/en/application-dev/media/figures/audiocapturer-status-change.png and b/en/application-dev/media/figures/audiocapturer-status-change.png differ diff --git a/en/application-dev/media/media-application-overview.md b/en/application-dev/media/media-application-overview.md index d350482e61e7bc9659054b0426c10ce07da88045..6ca7bbd61bccab668076da76841e785d1918abe9 100644 --- a/en/application-dev/media/media-application-overview.md +++ b/en/application-dev/media/media-application-overview.md @@ -2,7 +2,7 @@ ## Multimedia Subsystem Architecture -The multimedia subsystem provides the capability of processing users' visual and auditory information. For example, it can be used to collect, compress, store, decompress, and play audio and video information. Based on the type of media information to process, the media system is usually divided into four modules: audio, media, camera, and image. +The multimedia subsystem provides the capability of processing users' visual and auditory information. For example, it can be used to collect, compress, store, decompress, and play audio and video information. Based on the type of media information to process, the multimedia subsystem subsystem is usually divided into four modules: audio, media, camera, and image. As shown in the figure below, the multimedia subsystem provides APIs for developing audio/video, camera, and gallery applications, and provides adaptation and acceleration for different hardware chips. In the middle part, it provides core media functionalities and management mechanisms in the form of services. diff --git a/en/application-dev/media/using-audiorenderer-for-playback.md b/en/application-dev/media/using-audiorenderer-for-playback.md index 11934e669813fa7a89ceef43bd2c3795db6bad75..d72637819259e3752a33b37d6f645786793cfc38 100644 --- a/en/application-dev/media/using-audiorenderer-for-playback.md +++ b/en/application-dev/media/using-audiorenderer-for-playback.md @@ -151,9 +151,6 @@ export default class AudioRendererDemo { console.info(`${TAG}: creating AudioRenderer success`); this.renderModel = renderer; this.renderModel.on('stateChange', (state) => { // Set the events to listen for. A callback is invoked when the AudioRenderer is switched to the specified state. - if (state == 1) { - console.info('audio renderer state is: STATE_PREPARED'); - } if (state == 2) { console.info('audio renderer state is: STATE_RUNNING'); } diff --git a/en/application-dev/media/using-avplayer-for-playback.md b/en/application-dev/media/using-avplayer-for-playback.md index 6cb6ab1e67ef0ae8a44e04fa915ad87bcc9ed024..9af55fb71b489f7b3ece342969c72d18ed90eaab 100644 --- a/en/application-dev/media/using-avplayer-for-playback.md +++ b/en/application-dev/media/using-avplayer-for-playback.md @@ -12,7 +12,7 @@ During application development, you can use the **state** attribute of the AVPla **Figure 1** Playback state transition -![Playback state change](figures/playback-status-change.png) +![Playback status change](figures/playback-status-change.png) For details about the state, see [AVPlayerState](../reference/apis/js-apis-media.md#avplayerstate9). When the AVPlayer is in the **prepared**, **playing**, **paused**, or **completed** state, the playback engine is working and a large amount of RAM is occupied. If your application does not need to use the AVPlayer, call **reset()** or **release()** to release the instance. @@ -68,7 +68,9 @@ import common from '@ohos.app.ability.common'; export class AVPlayerDemo { private avPlayer; private count: number = 0; - + private isSeek: boolean = true; // Specify whether the seek operation is supported. + private fileSize: number = -1; + private fd: number = 0; // Set AVPlayer callback functions. setAVPlayerCallback() { // Callback function for the seek operation. @@ -102,8 +104,13 @@ export class AVPlayerDemo { case 'playing': // This state is reported upon a successful callback of play(). console.info('AVPlayer state playing called.'); if (this.count !== 0) { - console.info('AVPlayer start to seek.'); - this.avPlayer.seek (this.avPlayer.duration); // Call seek() to seek to the end of the audio clip. + if (this.isSeek) { + console.info('AVPlayer start to seek.'); + this.avPlayer.seek (this.avPlayer.duration); // Call seek() to seek to the end of the audio clip. + } else { + // When the seek operation is not supported, the playback continues until it reaches the end. + console.info('AVPlayer wait to play end.'); + } } else { this.avPlayer.pause(); // Call pause() to pause the playback. } @@ -145,6 +152,7 @@ export class AVPlayerDemo { // Open the corresponding file address to obtain the file descriptor and assign a value to the URL to trigger the reporting of the initialized state. let file = await fs.open(path); fdPath = fdPath + '' + file.fd; + this.isSeek = true; // The seek operation is supported. this.avPlayer.url = fdPath; } @@ -158,10 +166,85 @@ export class AVPlayerDemo { // The return type is {fd,offset,length}, where fd indicates the file descriptor address of the HAP file, offset indicates the media asset offset, and length indicates the duration of the media asset to play. let context = getContext(this) as common.UIAbilityContext; let fileDescriptor = await context.resourceManager.getRawFd('01.mp3'); + this.isSeek = true; // The seek operation is supported. // Assign a value to fdSrc to trigger the reporting of the initialized state. this.avPlayer.fdSrc = fileDescriptor; } + + // The following demo shows how to use the file system to open the sandbox address, obtain the media file address, and play the media file with the seek operation using the dataSrc attribute. + async avPlayerDataSrcSeekDemo() { + // Create an AVPlayer instance. + this.avPlayer = await media.createAVPlayer(); + // Set a callback function for state changes. + this.setAVPlayerCallback(); + // dataSrc indicates the playback source address. When the seek operation is supported, fileSize indicates the size of the file to be played. The following describes how to assign a value to fileSize. + let src = { + fileSize: -1, + callback: (buf, length, pos) => { + let num = 0; + if (buf == undefined || length == undefined || pos == undefined) { + return -1; + } + num = fs.readSync(this.fd, buf, { offset: pos, length: length }); + if (num > 0 && (this.fileSize >= pos)) { + return num; + } + return -1; + } + } + let context = getContext(this) as common.UIAbilityContext; + // Obtain the sandbox address filesDir through UIAbilityContext. The stage model is used as an example. + let pathDir = context.filesDir; + let path = pathDir + '/01.mp3'; + await fs.open(path).then((file) => { + this.fd = file.fd; + }) + // Obtain the size of the file to be played. + this.fileSize = fs.statSync(path).size; + src.fileSize = this.fileSize; + this.isSeek = true; // The seek operation is supported. + this.avPlayer.dataSrc = src; + } + + // The following demo shows how to use the file system to open the sandbox address, obtain the media file address, and play the media file without the seek operation using the dataSrc attribute. + async avPlayerDataSrcNoSeekDemo() { + // Create an AVPlayer instance. + this.avPlayer = await media.createAVPlayer(); + // Set a callback function for state changes. + this.setAVPlayerCallback(); + let context = getContext(this) as common.UIAbilityContext; + let src: object = { + fileSize: -1, + callback: (buf, length, pos) => { + let num = 0; + if (buf == undefined || length == undefined) { + return -1; + } + num = fs.readSync(this.fd, buf); + if (num > 0) { + return num; + } + return -1; + } + } + // Obtain the sandbox address filesDir through UIAbilityContext. The stage model is used as an example. + let pathDir = context.filesDir; + let path = pathDir + '/01.mp3'; + await fs.open(path).then((file) => { + this.fd = file.fd; + }) + this.isSeek = false; // The seek operation is not supported. + this.avPlayer.dataSrc = src; + } + + // The following demo shows how to play live streams by setting the network address through the URL. + async avPlayerLiveDemo() { + // Create an AVPlayer instance. + this.avPlayer = await media.createAVPlayer(); + // Set a callback function for state changes. + this.setAVPlayerCallback(); + this.isSeek = false; // The seek operation is not supported. + this.avPlayer.url = 'http://xxx.xxx.xxx.xxx:xx/xx/index.m3u8'; + } } ``` - - \ No newline at end of file diff --git a/en/application-dev/media/using-avsession-controller.md b/en/application-dev/media/using-avsession-controller.md index 5e4b69d8b48f5acad64f120892062e66d67c6b12..958661d90cec031cbbca1bb7c11ccb80e4dc0e66 100644 --- a/en/application-dev/media/using-avsession-controller.md +++ b/en/application-dev/media/using-avsession-controller.md @@ -1,6 +1,6 @@ # AVSession Controller -Media Controller preset in OpenHarmony functions as the controller to interact with audio and video applications, for example, obtaining and displaying media information and delivering control commands. +Media Controller preset in OpenHarmony functions as the controller to interact with audio and video applications, for example, obtaining and displaying media information and delivering playback control commands. You can develop a system application (for example, a new playback control center or voice assistant) as the controller to interact with audio and video applications in the system. @@ -8,24 +8,50 @@ You can develop a system application (for example, a new playback control center - AVSessionDescriptor: session information, including the session ID, session type (audio/video), custom session name (**sessionTag**), information about the corresponding application (**elementName**), and whether the session is pined on top (isTopSession). -- Top session: session with the highest priority in the system, for example, a session that is being played. Generally, the controller must hold an **AVSessionController** object to communicate with a session. However, the controller can directly communicate with the top session, for example, directly sending a control command or key event, without holding an **AVSessionController** object. +- Top session: session with the highest priority in the system, for example, a session that is being played. Generally, the controller must hold an **AVSessionController** object to communicate with a session. However, the controller can directly communicate with the top session, for example, directly sending a playback control command or key event, without holding an **AVSessionController** object. ## Available APIs -The table below lists the key APIs used by the controller. 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. +The key APIs used by the controller are classified into the following types: +1. APIs called by the **AVSessionManager** object, which is obtained by means of import. An example API is **AVSessionManager.createController(sessionId)**. +2. APIs called by the **AVSessionController** object. An example API is **controller.getAVPlaybackState()**. + +Asynchronous JavaScript 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. For details, see [AVSession Management](../reference/apis/js-apis-avsession.md). -| API| Description| +### APIs Called by the AVSessionManager Object + +| API| Description| +| -------- | -------- | +| getAllSessionDescriptors(callback: AsyncCallback<Array<Readonly<AVSessionDescriptor>>>): void | Obtains the descriptors of all AVSessions in the system.| +| createController(sessionId: string, callback: AsyncCallback<AVSessionController>): void | Creates an AVSessionController.| +| getValidCommands(callback: AsyncCallback<Array<AVControlCommandType>>): void | Obtains valid commands supported by the AVSession.
Playback control commands listened by an audio and video application when it accesses the AVSession are considered as valid commands supported by the AVSession. For details, see [Provider of AVSession](using-avsession-developer.md).| +| getLaunchAbility(callback: AsyncCallback<WantAgent>): void | Obtains the UIAbility that is configured in the AVSession and can be started.
The UIAbility configured here is started when a user operates the UI of the controller, for example, clicking a widget in Media Controller.| +| sendAVKeyEvent(event: KeyEvent, callback: AsyncCallback<void>): void | Sends a key event to an AVSession through the AVSessionController object.| +| sendSystemAVKeyEvent(event: KeyEvent, callback: AsyncCallback<void>): void | Sends a key event to the top session.| +| sendControlCommand(command: AVControlCommand, callback: AsyncCallback<void>): void | Sends a playback control command to an AVSession through the AVSessionController object.| +| sendSystemControlCommand(command: AVControlCommand, callback: AsyncCallback<void>): void | Sends a playback control command to the top session.| +| getHistoricalSessionDescriptors(maxSize: number, callback: AsyncCallback\>>): void10+ | Obtains the descriptors of historical sessions.| + +### APIs Called by the AVSessionController Object + +| API| Description| | -------- | -------- | -| getAllSessionDescriptors(callback: AsyncCallback<Array<Readonly<AVSessionDescriptor>>>): void | Obtains the descriptors of all AVSessions in the system.| -| createController(sessionId: string, callback: AsyncCallback<AVSessionController>): void | Creates an AVSessionController.| -| getValidCommands(callback: AsyncCallback<Array<AVControlCommandType>>): void | Obtains valid commands supported by the AVSession.
Control commands listened by an audio and video application when it accesses the AVSession are considered as valid commands supported by the AVSession. For details, see [Provider of AVSession](using-avsession-developer.md).| -| getLaunchAbility(callback: AsyncCallback<WantAgent>): void | Obtains the UIAbility that is configured in the AVSession and can be started.
The UIAbility configured here is started when a user operates the UI of the controller, for example, clicking a widget in Media Controller.| -| sendAVKeyEvent(event: KeyEvent, callback: AsyncCallback<void>): void | Sends a key event to an AVSession through the AVSessionController object.| -| sendSystemAVKeyEvent(event: KeyEvent, callback: AsyncCallback<void>): void | Sends a key event to the top session.| -| sendControlCommand(command: AVControlCommand, callback: AsyncCallback<void>): void | Sends a control command to an AVSession through the AVSessionController object.| -| sendSystemControlCommand(command: AVControlCommand, callback: AsyncCallback<void>): void | Sends a control command to the top session.| +| getAVPlaybackState(callback: AsyncCallback<AVPlaybackState>): void | Obtains the information related to the playback state.| +| getAVMetadata(callback: AsyncCallback<AVMetadata>): void | Obtains the session metadata.| +| getOutputDevice(callback: AsyncCallback<OutputDeviceInfo>): void | Obtains the output device information.| +| sendAVKeyEvent(event: KeyEvent, callback: AsyncCallback<void>): void | Sends a key event to the session corresponding to this controller.| +| getLaunchAbility(callback: AsyncCallback<WantAgent>): void | Obtains the **WantAgent** object saved by the application in the session.| +| isActive(callback: AsyncCallback<boolean>): void | Checks whether the session is activated.| +| destroy(callback: AsyncCallback<void>): void | Destroys this controller. A controller can no longer be used after being destroyed.| +| getValidCommands(callback: AsyncCallback<Array<AVControlCommandType>>): void | Obtains valid commands supported by the session.| +| sendControlCommand(command: AVControlCommand, callback: AsyncCallback<void>): void | Sends a playback control command to the session through the controller.| +| sendCommonCommand(command: string, args: {[key: string]: Object}, callback: AsyncCallback<void>): void10+ | Sends a custom playback control command to the session through the controller.| +| getAVQueueItems(callback: AsyncCallback<Array<AVQueueItem>>): void10+ | Obtains the information related to the items in the playlist.| +| getAVQueueTitle(callback: AsyncCallback<string>): void10+ | Obtains the name of the playlist.| +| skipToQueueItem(itemId: number, callback: AsyncCallback<void>): void10+ | Sends the ID of an item in the playlist to the session for processing. The session can play the song.| +| getExtras(callback: AsyncCallback<{[key: string]: Object}>): void10+ | Obtains the custom media packet set by the provider.| ## How to Develop @@ -48,13 +74,26 @@ To enable a system application to access the AVSession service as a controller, AVSessionManager.createController(descriptor.sessionId).then((controller) => { g_controller.push(controller); }).catch((err) => { - console.error(`createController : ERROR : ${err.message}`); + console.error(`Failed to create controller. Code: ${err.code}, message: ${err.message}`); }); }); }).catch((err) => { - console.error(`getAllSessionDescriptors : ERROR : ${err.message}`); + console.error(`Failed to get all session descriptors. Code: ${err.code}, message: ${err.message}`); }); + // Obtain the descriptors of historical sessions. + avSession.getHistoricalSessionDescriptors().then((descriptors) => { + console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors.length : ${descriptors.length}`); + if (descriptors.length > 0){ + console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].isActive : ${descriptors[0].isActive}`); + console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].type : ${descriptors[0].type}`); + console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].sessionTag : ${descriptors[0].sessionTag}`); + console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].sessionId : ${descriptors[0].sessionId}`); + console.info(`getHistoricalSessionDescriptors : SUCCESS : descriptors[0].elementName.bundleName : ${descriptors[0].elementName.bundleName}`); + } + }).catch((err) => { + console.error(`Failed to get historical session descriptors, error code: ${err.code}, error message: ${err.message}`); + }); ``` 2. Listen for the session state and service state events. @@ -74,7 +113,7 @@ To enable a system application to access the AVSession service as a controller, AVSessionManager.createController(session.sessionId).then((controller) => { g_controller.push(controller); }).catch((err) => { - console.info(`createController : ERROR : ${err.message}`); + console.error(`Failed to create controller. Code: ${err.code}, message: ${err.message}`); }); }); @@ -103,7 +142,7 @@ To enable a system application to access the AVSession service as a controller, // Subscribe to the 'sessionServiceDie' event. AVSessionManager.on('sessionServiceDie', () => { // The server is abnormal, and the application clears resources. - console.info("Server exception."); + console.info(`Server exception.`); }) ``` @@ -117,6 +156,10 @@ To enable a system application to access the AVSession service as a controller, - **validCommandChange**: triggered when the valid commands supported by the session changes. - **outputDeviceChange**: triggered when the output device changes. - **sessionDestroy**: triggered when a session is destroyed. + - **sessionEvent**: triggered when the custom session event changes. + - **extrasChange**: triggered when the custom media packet of the session changes. + - **queueItemsChange**: triggered when one or more items in the custom playlist of the session changes. + - **queueTitleChange**: triggered when the custom playlist name of the session changes. The controller can listen for events as required. @@ -124,18 +167,18 @@ To enable a system application to access the AVSession service as a controller, // Subscribe to the 'activeStateChange' event. controller.on('activeStateChange', (isActive) => { if (isActive) { - console.info("The widget corresponding to the controller is highlighted."); + console.info(`The widget corresponding to the controller is highlighted.`); } else { - console.info("The widget corresponding to the controller is invalid."); + console.info(`The widget corresponding to the controller is invalid.`); } }); // Subscribe to the 'sessionDestroy' event to enable the controller to get notified when the session dies. controller.on('sessionDestroy', () => { - console.info('on sessionDestroy : SUCCESS '); + info(`on sessionDestroy : SUCCESS `); controller.destroy().then(() => { - console.info('destroy : SUCCESS '); + console.info(`destroy : SUCCESS`); }).catch((err) => { - console.info(`destroy : ERROR :${err.message}`); + console.error(`Failed to destroy session. Code: ${err.code}, message: ${err.message}`); }); }); @@ -164,10 +207,26 @@ To enable a system application to access the AVSession service as a controller, controller.on('outputDeviceChange', (device) => { console.info(`on outputDeviceChange device isRemote : ${device.isRemote}`); }); + // Subscribe to custom session event changes. + controller.on('sessionEvent', (eventName, eventArgs) => { + console.info(`Received new session event, event name is ${eventName}, args are ${JSON.stringify(eventArgs)}`); + }); + // Subscribe to custom media packet changes. + controller.on('extrasChange', (extras) => { + console.info(`Received custom media packet, packet data is ${JSON.stringify(extras)}`); + }); + // Subscribe to custom playlist item changes. + controller.on('queueItemsChange', (items) => { + console.info(`Caught queue items change, items length is ${items.length}`); + }); + // Subscribe to custom playback name changes. + controller.on('queueTitleChange', (title) => { + console.info(`Caught queue title change, title is ${title}`); + }); ``` 4. Obtain the media information transferred by the provider for display on the UI, for example, displaying the track being played and the playback state in Media Controller. - + ```ts async getInfoFromSessionByController() { // It is assumed that an AVSessionController object corresponding to the session already exists. For details about how to create an AVSessionController object, see the code snippet above. @@ -186,19 +245,36 @@ To enable a system application to access the AVSession service as a controller, let avPlaybackState: AVSessionManager.AVPlaybackState = await controller.getAVPlaybackState(); console.info(`get playbackState by controller : ${avPlaybackState.state}`); console.info(`get favoriteState by controller : ${avPlaybackState.isFavorite}`); + // Obtain the playlist items of the session. + let queueItems: Array = await controller.getAVQueueItems(); + console.info(`get queueItems length by controller : ${queueItems.length}`); + // Obtain the playlist name of the session. + let queueTitle: string = await controller.getAVQueueTitle(); + console.info(`get queueTitle by controller : ${queueTitle}`); + // Obtain the custom media packet of the session. + let extras: any = await controller.getExtras(); + console.info(`get custom media packets by controller : ${JSON.stringify(extras)}`); + // Obtain the ability information provided by the application corresponding to the session. + let agent: WantAgent = await controller.getLaunchAbility(); + console.info(`get want agent info by controller : ${JSON.stringify(agent)}`); + // Obtain the current playback position of the session. + let currentTime: number = controller.getRealPlaybackPositionSync(); + console.info(`get current playback time by controller : ${currentTime}`); + // Obtain valid commands supported by the session. + let validCommands: Array = await controller.getValidCommands(); + console.info(`get valid commands by controller : ${JSON.stringify(validCommands)}`); } ``` 5. Control the playback behavior, for example, sending a command to operate (play/pause/previous/next) the item being played in Media Controller. - After listening for the control command event, the audio and video application serving as the provider needs to implement the corresponding operation. + After listening for the playback control command event, the audio and video application serving as the provider needs to implement the corresponding operation. - ```ts async sendCommandToSessionByController() { // It is assumed that an AVSessionController object corresponding to the session already exists. For details about how to create an AVSessionController object, see the code snippet above. let controller: AVSessionManager.AVSessionController = ALLREADY_HAVE_A_CONTROLLER; - // Obtain the commands supported by the session. + // Obtain valid commands supported by the session. let validCommandTypeArray: Array = await controller.getValidCommands(); console.info(`get validCommandArray by controller : length : ${validCommandTypeArray.length}`); // Deliver the 'play' command. @@ -222,11 +298,28 @@ To enable a system application to access the AVSession service as a controller, let avCommand: AVSessionManager.AVControlCommand = {command:'playNext'}; controller.sendControlCommand(avCommand); } + // Deliver a custom playback control command. + let commandName: string = 'custom command'; + let args = { + command : 'This is my custom command' + } + await controller.sendCommonCommand(commandName, args).then(() => { + console.info(`SendCommonCommand successfully`); + }).catch((err) => { + console.error(`Failed to send common command. Code: ${err.code}, message: ${err.message}`); + }) + // Set the ID of an item in the specified playlist for the session to play. + let queueItemId: number = 0; + await controller.skipToQueueItem(queueItemId).then(() => { + console.info(`SkipToQueueItem successfully`); + }).catch((err) => { + console.error(`Failed to skip to queue item. Code: ${err.code}, message: ${err.message}`); + }); } ``` 6. When the audio and video application exits, cancel the listener and release the resources. - + ```ts async destroyController() { // It is assumed that an AVSessionController object corresponding to the session already exists. For details about how to create an AVSessionController object, see the code snippet above. @@ -235,9 +328,9 @@ To enable a system application to access the AVSession service as a controller, // Destroy the AVSessionController object. After being destroyed, it is no longer available. controller.destroy(function (err) { if (err) { - console.info(`Destroy controller ERROR : code: ${err.code}, message: ${err.message}`); + console.error(`Failed to destroy controller. Code: ${err.code}, message: ${err.message}`); } else { - console.info('Destroy controller SUCCESS'); + console.info(`Destroy controller SUCCESS`); } }); } diff --git a/en/application-dev/media/using-avsession-developer.md b/en/application-dev/media/using-avsession-developer.md index 077f0b956a5fb6abaf26c647132bdbb81e78fc63..bf0b914647b9c364bea0ac86a30def88fe3c0f52 100644 --- a/en/application-dev/media/using-avsession-developer.md +++ b/en/application-dev/media/using-avsession-developer.md @@ -1,12 +1,12 @@ # AVSession Provider -An 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 control commands delivered by the controller. +An 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. ## Basic Concepts - 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. -- AVPlaybackState: playback state attributes, including the playback state, position, speed, buffered time, loop mode, and whether the media asset is favorited (**isFavorite**). +- 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). ## Available APIs @@ -14,28 +14,43 @@ The table below lists the key APIs used by the provider. The APIs use either a c For details, see [AVSession Management](../reference/apis/js-apis-avsession.md). -| API| Description| +| API| Description| | -------- | -------- | -| createAVSession(context: Context, tag: string, type: AVSessionType, callback: AsyncCallback<AVSession>): void | Creates an AVSession.
Only one AVSession can be created for a UIAbility.| -| setAVMetadata(data: AVMetadata, callback: AsyncCallback<void>): void | Sets AVSession metadata.| -| setAVPlaybackState(state: AVPlaybackState, callback: AsyncCallback<void>): void | Sets the AVSession playback state.| -| setLaunchAbility(ability: WantAgent, callback: AsyncCallback<void>): void | Starts a UIAbility.| -| getController(callback: AsyncCallback<AVSessionController>): void | Obtains the controller of the AVSession.| -| activate(callback: AsyncCallback<void>): void | Activates the AVSession.| -| destroy(callback: AsyncCallback<void>): void | Destroys the AVSession.| +| createAVSession(context: Context, tag: string, type: AVSessionType, callback: AsyncCallback<AVSession>): void | Creates an AVSession.
Only one AVSession can be created for a UIAbility.| +| setAVMetadata(data: AVMetadata, callback: AsyncCallback<void>): void | Sets AVSession metadata.| +| setAVPlaybackState(state: AVPlaybackState, callback: AsyncCallback<void>): void | Sets the AVSession playback state.| +| setLaunchAbility(ability: WantAgent, callback: AsyncCallback<void>): void | Starts a UIAbility.| +| getController(callback: AsyncCallback<AVSessionController>): void | Obtains the controller of the AVSession.| +| getOutputDevice(callback: AsyncCallback<OutputDeviceInfo>): void | Obtains the output device information.| +| activate(callback: AsyncCallback<void>): void | Activates the AVSession.| +| deactivate(callback: AsyncCallback<void>): void | Deactivates this session.| +| destroy(callback: AsyncCallback<void>): void | Destroys the AVSession.| +| setAVQueueItems(items: Array<AVQueueItem>, callback: AsyncCallback<void>): void 10+ | Sets a playlist.| +| setAVQueueTitle(title: string, callback: AsyncCallback<void>): void10+ | Sets a name for the playlist.| +| dispatchSessionEvent(event: string, args: {[key: string]: Object}, callback: AsyncCallback<void>): void10+ | Dispatches a custom session event.| +| setExtras(extras: {[key: string]: Object}, callback: AsyncCallback<void>): void10+ | Sets a custom media packet in the form of a key-value pair.| ## How to Develop To enable an audio and video application to access the AVSession service as a provider, proceed as follows: 1. Call an API in the **AVSessionManager** class to create and activate an **AVSession** object. - + ```ts + // To create an AVSession object, you must first obtain the application context. You can set a global variable in the EntryAbility file of the application to store the application context. + export default class EntryAbility extends UIAbility { + onCreate(want, launchParam) { + globalThis.context = this.context; // Set the global variable globalThis.context to store the application context. + } + // Other APIs of the EntryAbility class. + } + + // Start to create and activate an AVSession object. import AVSessionManager from '@ohos.multimedia.avsession'; // Import the AVSessionManager module. // Create an AVSession object. async createSession() { - let session: AVSessionManager.AVSession = await AVSessionManager.createAVSession(this.context, 'SESSION_NAME', 'audio'); + let session: AVSessionManager.AVSession = await AVSessionManager.createAVSession(globalThis.context, 'SESSION_NAME', 'audio'); session.activate(); console.info(`session create done : sessionId : ${session.sessionId}`); } @@ -46,22 +61,22 @@ To enable an audio and video application to access the AVSession service as a pr - AVPlaybackState The controller will call an API in the **AVSessionController** class to obtain the information and display or process the information. - + ```ts async setSessionInfo() { - // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; + // 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. + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; // The player logic that triggers changes in the session metadata and playback state is omitted here. // Set necessary session metadata. let metadata: AVSessionManager.AVMetadata = { - assetId: "0", - title: "TITLE", - artist: "ARTIST" + assetId: '0', + title: 'TITLE', + artist: 'ARTIST' }; session.setAVMetadata(metadata).then(() => { - console.info('SetAVMetadata successfully'); + console.info(`SetAVMetadata successfully`); }).catch((err) => { - console.info(`SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`); + console.error(`Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`); }); // Set the playback state to paused and set isFavorite to false. let playbackState: AVSessionManager.AVPlaybackState = { @@ -70,86 +85,230 @@ To enable an audio and video application to access the AVSession service as a pr }; session.setAVPlaybackState(playbackState, function (err) { if (err) { - console.info(`SetAVPlaybackState BusinessError: code: ${err.code}, message: ${err.message}`); + console.error(`Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`); } else { - console.info('SetAVPlaybackState successfully'); + console.info(`SetAVPlaybackState successfully`); } }); + // Set a playlist. + let queueItemDescription_1 = { + mediaId: '001', + title: 'music_name', + subtitle: 'music_sub_name', + description: 'music_description', + icon: PIXELMAP_OBJECT, + iconUri: 'http://www.xxx.com', + extras: {'extras':'any'} + }; + let queueItem_1 = { + itemId: 1, + description: queueItemDescription_1 + }; + let queueItemDescription_2 = { + mediaId: '002', + title: 'music_name', + subtitle: 'music_sub_name', + description: 'music_description', + icon: PIXELMAP_OBJECT, + iconUri: 'http://www.xxx.com', + extras: {'extras':'any'} + }; + let queueItem_2 = { + itemId: 2, + description: queueItemDescription_2 + }; + let queueItemsArray = [queueItem_1, queueItem_2]; + session.setAVQueueItems(queueItemsArray).then(() => { + console.info(`SetAVQueueItems successfully`); + }).catch((err) => { + console.error(`Failed to set AVQueueItem, error code: ${err.code}, error message: ${err.message}`); + }); + // Set a name for the playlist. + let queueTitle = 'QUEUE_TITLE'; + session.setAVQueueTitle(queueTitle).then(() => { + console.info(`SetAVQueueTitle successfully`); + }).catch((err) => { + console.info(`Failed to set AVQueueTitle, error code: ${err.code}, error message: ${err.message}`); + }); } ``` 3. 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. The UIAbility is set through the **WantAgent** API. For details, see [WantAgent](../reference/apis/js-apis-app-ability-wantAgent.md). - + ```ts - import WantAgent from "@ohos.app.ability.wantAgent"; + import wantAgent from "@ohos.app.ability.wantAgent"; ``` ```ts - // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; + // 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. + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; let wantAgentInfo = { wants: [ { - bundleName: "com.example.musicdemo", - abilityName: "com.example.musicdemo.MainAbility" + bundleName: 'com.example.musicdemo', + abilityName: 'com.example.musicdemo.MainAbility' } ], - operationType: WantAgent.OperationType.START_ABILITIES, + operationType: wantAgent.OperationType.START_ABILITIES, requestCode: 0, - wantAgentFlags: [WantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] + wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] } - WantAgent.getWantAgent(wantAgentInfo).then((agent) => { - session.setLaunchAbility(agent) + wantAgent.getWantAgent(wantAgentInfo).then((agent) => { + session.setLaunchAbility(agent); }) ``` -4. Listen for control commands delivered by the controller, for example, Media Controller. +4. Set a custom session event. The controller performs an operation after receiving the event. + > **NOTE** > - > After the provider registers a listener for the control command event, the event 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 control commands delivered by the controller can be executed normally, the provider should not use a null implementation for listening. - + > The data set through **dispatchSessionEvent** is not saved in the **AVSession** object or AVSession service. + ```ts - async setListenerForMesFromController() { - // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; - // Generally, logic processing on the player is implemented in the listener. - // After the processing is complete, use the setter to synchronize the playback information. For details, see the code snippet above. - session.on('play', () => { - console.info('on play , do play task'); - - // do some tasks ··· - }); - session.on('pause', () => { - console.info('on pause , do pause task'); - // do some tasks ··· - }); - session.on('stop', () => { - console.info('on stop , do stop task'); - // do some tasks ··· - }); - session.on('playNext', () => { - console.info('on playNext , do playNext task'); - // do some tasks ··· - }); - session.on('playPrevious', () => { - console.info('on playPrevious , do playPrevious task'); - // do some tasks ··· - }); + // 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. + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + let eventName = 'dynamic_lyric'; + let args = { + lyric : 'This is my lyric' } + await session.dispatchSessionEvent(eventName, args).then(() => { + console.info(`Dispatch session event successfully`); + }).catch((err) => { + console.error(`Failed to dispatch session event. Code: ${err.code}, message: ${err.message}`); + }) ``` -5. Obtain an **AVSessionController** object for this **AVSession** object for interaction. - +5. Set a custom media packet. The controller performs an operation after receiving the event. + + > **NOTE** + > + > 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. + + ```ts + // 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. + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + let extras = { + extra : 'This is my custom meida packet' + } + await session.setExtras(extras).then(() => { + console.info(`Set extras successfully`); + }).catch((err) => { + console.error(`Failed to set extras. Code: ${err.code}, message: ${err.message}`); + }) + ``` + +6. Listen for playback control commands or events delivered by the controller, for example, Media Controller. + + Both fixed playback control commands and advanced playback control events can be listened for. + + - Listening for Fixed Playback Control Commands + + > **NOTE** + > + > 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. + + 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). + + ```ts + async setListenerForMesFromController() { + // 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. + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + // Generally, logic processing on the player is implemented in the listener. + // After the processing is complete, use the setter to synchronize the playback information. For details, see the code snippet above. + session.on('play', () => { + console.info(`on play , do play task`); + // do some tasks ··· + }); + session.on('pause', () => { + console.info(`on pause , do pause task`); + // do some tasks ··· + }); + session.on('stop', () => { + console.info(`on stop , do stop task`); + // do some tasks ··· + }); + session.on('playNext', () => { + console.info(`on playNext , do playNext task`); + // do some tasks ··· + }); + session.on('playPrevious', () => { + console.info(`on playPrevious , do playPrevious task`); + // do some tasks ··· + }); + session.on('fastForward', () => { + console.info(`on fastForward , do fastForward task`); + // do some tasks ··· + }); + session.on('rewind', () => { + console.info(`on rewind , do rewind task`); + // do some tasks ··· + }); + + session.on('seek', (time) => { + console.info(`on seek , the seek time is ${time}`); + // do some tasks ··· + }); + session.on('setSpeed', (speed) => { + console.info(`on setSpeed , the speed is ${speed}`); + // do some tasks ··· + }); + session.on('setLoopMode', (mode) => { + console.info(`on setLoopMode , the loop mode is ${mode}`); + // do some tasks ··· + }); + session.on('toggleFavorite', (assetId) => { + console.info(`on toggleFavorite , the target asset Id is ${assetId}`); + // do some tasks ··· + }); + } + ``` + + - Listening for Advanced Playback Control Events + + The following advanced playback control events can be listened for: + + - **skipToQueueItem**: triggered when an item in the playlist is selected. + - **handleKeyEvent**: triggered when a key is pressed. + - **outputDeviceChange**: triggered when the output device changes. + - **commonCommand**: triggered when a custom playback control command changes. + + ```ts + async setListenerForMesFromController() { + // 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. + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + // Generally, logic processing on the player is implemented in the listener. + // After the processing is complete, use the setter to synchronize the playback information. For details, see the code snippet above. + session.on('skipToQueueItem', (itemId) => { + console.info(`on skipToQueueItem , do skip task`); + // do some tasks ··· + }); + session.on('handleKeyEvent', (event) => { + console.info(`on handleKeyEvent , the event is ${JSON.stringify(event)}`); + // do some tasks ··· + }); + session.on('outputDeviceChange', (device) => { + console.info(`on outputDeviceChange , the device info is ${JSON.stringify(device)}`); + // do some tasks ··· + }); + session.on('commonCommand', (commandString, args) => { + console.info(`on commonCommand , command is ${commandString}, args are ${JSON.stringify(args)}`); + // do some tasks ··· + }); + } + ``` + +7. Obtain an **AVSessionController** object for this **AVSession** object for interaction. + ```ts async createControllerFromSession() { - // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; + // 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. + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; // Obtain an AVSessionController object for this AVSession object. let controller: AVSessionManager.AVSessionController = await session.getController(); - // The AVSessionController object can interact with the AVSession object, for example, by delivering a control command. + // The AVSessionController object can interact with the AVSession object, for example, by delivering a playback control command. let avCommand: AVSessionManager.AVControlCommand = {command:'play'}; controller.sendControlCommand(avCommand); @@ -163,13 +322,14 @@ To enable an audio and video application to access the AVSession service as a pr } ``` -6. When the audio and video application exits and does not need to continue playback, cancel the listener and destroy the **AVSession** object. - The code snippet below is used for canceling the listener for control commands: +8. When the audio and video application exits and does not need to continue playback, cancel the listener and destroy the **AVSession** object. + + The code snippet below is used for canceling the listener for playback control commands: ```ts async unregisterSessionListener() { - // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; + // 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. + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; // Cancel the listener of the AVSession object. session.off('play'); @@ -177,22 +337,27 @@ To enable an audio and video application to access the AVSession service as a pr session.off('stop'); session.off('playNext'); session.off('playPrevious'); + session.off('skipToQueueItem'); + session.off('handleKeyEvent'); + session.off('outputDeviceChange'); + session.off('commonCommand'); } ``` - - The code snippet below is used for destroying the AVSession object: - - ```ts + + + The code snippet below is used for destroying the AVSession object: + + ```ts async destroySession() { - // It is assumed that an AVSession object has been created. For details about how to create an AVSession object, see the node snippet above. - let session: AVSessionManager.AVSession = ALLREADY_CREATE_A_SESSION; - // Destroy the AVSession object. - session.destroy(function (err) { - if (err) { - console.info(`Destroy BusinessError: code: ${err.code}, message: ${err.message}`); - } else { - console.info('Destroy : SUCCESS '); - } - }); + // 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. + let session: AVSessionManager.AVSession = ALREADY_CREATE_A_SESSION; + // Destroy the AVSession object. + session.destroy(function (err) { + if (err) { + console.error(`Failed to destroy session. Code: ${err.code}, message: ${err.message}`); + } else { + console.info(`Destroy : SUCCESS `); + } + }); } - ``` + ``` \ No newline at end of file diff --git a/en/application-dev/media/using-distributed-avsession.md b/en/application-dev/media/using-distributed-avsession.md index c1835d661fdd2b57b7dce0f2507dbea748eaea7e..fc5c49b9804b67750228a010c1c53d58a2086bbf 100644 --- a/en/application-dev/media/using-distributed-avsession.md +++ b/en/application-dev/media/using-distributed-avsession.md @@ -36,15 +36,15 @@ To enable a system application that accesses the AVSession service as the contro let audioDevices; await audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => { audioDevices = data; - console.info('Promise returned to indicate that the device list is obtained.'); + console.info(`Promise returned to indicate that the device list is obtained.`); }).catch((err) => { - console.info(`getDevices : ERROR : ${err.message}`); + console.error(`Failed to get devices. Code: ${err.code}, message: ${err.message}`); }); AVSessionManager.castAudio('all', audioDevices).then(() => { - console.info('createController : SUCCESS'); + console.info(`createController : SUCCESS`); }).catch((err) => { - console.info(`createController : ERROR : ${err.message}`); + console.error(`Failed to cast audio. Code: ${err.code}, message: ${err.message}`); }); ``` diff --git a/en/application-dev/media/video-playback.md b/en/application-dev/media/video-playback.md index fff4aa830ddc45e7d20e0fd06655adfdc5243fe5..f745f2f25120f7068de6634af56aa1f443c5b5d9 100644 --- a/en/application-dev/media/video-playback.md +++ b/en/application-dev/media/video-playback.md @@ -78,7 +78,9 @@ export class AVPlayerDemo { private avPlayer; private count: number = 0; private surfaceID: string; // The surfaceID parameter specifies the window used to display the video. Its value is obtained through the XComponent. - + private isSeek: boolean = true; // Specify whether the seek operation is supported. + private fileSize: number = -1; + private fd: number = 0; // Set AVPlayer callback functions. setAVPlayerCallback() { // Callback function for the seek operation. @@ -113,8 +115,13 @@ export class AVPlayerDemo { case 'playing': // This state is reported upon a successful callback of play(). console.info('AVPlayer state playing called.'); if (this.count !== 0) { - console.info('AVPlayer start to seek.'); - this.avPlayer.seek (this.avPlayer.duration); // Call seek() to seek to the end of the video clip. + if (this.isSeek) { + console.info('AVPlayer start to seek.'); + this.avPlayer.seek (this.avPlayer.duration); // Call seek() to seek to the end of the video clip. + } else { + // When the seek operation is not supported, the playback continues until it reaches the end. + console.info('AVPlayer wait to play end.'); + } } else { this.avPlayer.pause(); // Call pause() to pause the playback. } @@ -152,10 +159,11 @@ export class AVPlayerDemo { let context = getContext(this) as common.UIAbilityContext; // Obtain the sandbox address filesDir through UIAbilityContext. The stage model is used as an example. let pathDir = context.filesDir; - let path = pathDir + '/H264_AAC.mp4'; + let path = pathDir + '/H264_AAC.mp4'; // Open the corresponding file address to obtain the file descriptor and assign a value to the URL to trigger the reporting of the initialized state. let file = await fs.open(path); fdPath = fdPath + '' + file.fd; + this.isSeek = true; // The seek operation is supported. this.avPlayer.url = fdPath; } @@ -169,9 +177,86 @@ export class AVPlayerDemo { // The return type is {fd,offset,length}, where fd indicates the file descriptor address of the HAP file, offset indicates the media asset offset, and length indicates the duration of the media asset to play. let context = getContext(this) as common.UIAbilityContext; let fileDescriptor = await context.resourceManager.getRawFd('H264_AAC.mp4'); + this.isSeek = true; // The seek operation is supported. // Assign a value to fdSrc to trigger the reporting of the initialized state. this.avPlayer.fdSrc = fileDescriptor; } + + // The following demo shows how to use the file system to open the sandbox address, obtain the media file address, and play the media file with the seek operation using the dataSrc attribute. + async avPlayerDataSrcSeekDemo() { + // Create an AVPlayer instance. + this.avPlayer = await media.createAVPlayer(); + // Set a callback function for state changes. + this.setAVPlayerCallback(); + // dataSrc indicates the playback source address. When the seek operation is supported, fileSize indicates the size of the file to be played. The following describes how to assign a value to fileSize. + let src = { + fileSize: -1, + callback: (buf, length, pos) => { + let num = 0; + if (buf == undefined || length == undefined || pos == undefined) { + return -1; + } + num = fs.readSync(this.fd, buf, { offset: pos, length: length }); + if (num > 0 && (this.fileSize >= pos)) { + return num; + } + return -1; + } + } + let context = getContext(this) as common.UIAbilityContext; + // Obtain the sandbox address filesDir through UIAbilityContext. The stage model is used as an example. + let pathDir = context.filesDir; + let path = pathDir + '/H264_AAC.mp4'; + await fs.open(path).then((file) => { + this.fd = file.fd; + }) + // Obtain the size of the file to be played. + this.fileSize = fs.statSync(path).size; + src.fileSize = this.fileSize; + this.isSeek = true; // The seek operation is supported. + this.avPlayer.dataSrc = src; + } + + // The following demo shows how to use the file system to open the sandbox address, obtain the media file address, and play the media file without the seek operation using the dataSrc attribute. + async avPlayerDataSrcNoSeekDemo() { + // Create an AVPlayer instance. + this.avPlayer = await media.createAVPlayer(); + // Set a callback function for state changes. + this.setAVPlayerCallback(); + let context = getContext(this) as common.UIAbilityContext; + let src: object = { + fileSize: -1, + callback: (buf, length, pos) => { + let num = 0; + if (buf == undefined || length == undefined) { + return -1; + } + num = fs.readSync(this.fd, buf); + if (num > 0) { + return num; + } + return -1; + } + } + // Obtain the sandbox address filesDir through UIAbilityContext. The stage model is used as an example. + let pathDir = context.filesDir; + let path = pathDir + '/H264_AAC.mp4'; + await fs.open(path).then((file) => { + this.fd = file.fd; + }) + this.isSeek = false; // The seek operation is not supported. + this.avPlayer.dataSrc = src; + } + + // The following demo shows how to play live streams by setting the network address through the URL. + async avPlayerLiveDemo() { + // Create an AVPlayer instance. + this.avPlayer = await media.createAVPlayer(); + // Set a callback function for state changes. + this.setAVPlayerCallback(); + this.isSeek = false; // The seek operation is not supported. + this.avPlayer.url = 'http://xxx.xxx.xxx.xxx:xx/xx/index.m3u8'; // Play live webcasting streams using HLS. + } } ``` diff --git a/en/application-dev/reference/apis/js-apis-avsession.md b/en/application-dev/reference/apis/js-apis-avsession.md index 7efa6349694569c43954930e8fafdb8046a2446c..d9a98b7c17e79f588e60b199f8bf4530e781ce83 100644 --- a/en/application-dev/reference/apis/js-apis-avsession.md +++ b/en/application-dev/reference/apis/js-apis-avsession.md @@ -3,6 +3,7 @@ The **avSession** module provides APIs for media playback control so that applications can access the system's Media Controller. This module provides the following typical features related to media sessions: + - [AVSession](#avsession): used to set session metadata, playback state information, and more. - [AVSessionController](#avsessioncontroller): used to obtain session IDs, send commands and events to sessions, and obtain the session metadata and playback state information. @@ -431,7 +432,7 @@ Before calling this API, import the **ohos.multimedia.audio** module to obtain t | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the casting is successful, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the casting is successful, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -453,13 +454,13 @@ let audioRoutingManager = audioManager.getRoutingManager(); let audioDevices; await audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => { audioDevices = data; - console.info('Promise returned to indicate that the device list is obtained.'); + console.info(`Promise returned to indicate that the device list is obtained.`); }).catch((err) => { console.info(`GetDevices BusinessError: code: ${err.code}, message: ${err.message}`); }); avSession.castAudio('all', audioDevices).then(() => { - console.info('CreateController : SUCCESS'); + console.info(`CreateController : SUCCESS`); }).catch((err) => { console.info(`CreateController BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -485,7 +486,7 @@ Before calling this API, import the **ohos.multimedia.audio** module to obtain t | ------------ |--------------------------------------------| ---- | ------------------------------------------------------------ | | session | [SessionToken](#sessiontoken) | 'all' | Yes | Session token. **SessionToken** indicates a specific token, and **'all'** indicates all tokens.| | audioDevices | Array\<[audio.AudioDeviceDescriptor](js-apis-audio.md#audiodevicedescriptor)\> | Yes | Audio devices. | -| callback | AsyncCallback | Yes | Callback used to return the result. If the casting is successful, **err** is **undefined**; otherwise, **err** is an error object. | +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the casting is successful, **err** is **undefined**; otherwise, **err** is an error object. | **Error codes** @@ -507,7 +508,7 @@ let audioRoutingManager = audioManager.getRoutingManager(); let audioDevices; await audioRoutingManager.getDevices(audio.DeviceFlag.OUTPUT_DEVICES_FLAG).then((data) => { audioDevices = data; - console.info('Promise returned to indicate that the device list is obtained.'); + console.info(`Promise returned to indicate that the device list is obtained.`); }).catch((err) => { console.info(`GetDevices BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -516,7 +517,7 @@ avSession.castAudio('all', audioDevices, function (err) { if (err) { console.info(`CastAudio BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('CastAudio : SUCCESS '); + console.info(`CastAudio : SUCCESS `); } }); ``` @@ -634,7 +635,7 @@ For details about the error codes, see [AVSession Management Error Codes](../err ```js avSession.on('sessionServiceDie', () => { - console.info('on sessionServiceDie : session is Died '); + console.info(`on sessionServiceDie : session is Died `); }); ``` @@ -691,7 +692,7 @@ Sends a system key event to the top session. This API uses a promise to return t | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the event is sent, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the event is sent, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -710,7 +711,7 @@ let keyItem = {code:0x49, pressedTime:2, deviceId:0}; let event = {id:1, deviceId:0, actionTime:1, screenId:1, windowId:1, action:2, key:keyItem, unicodeChar:0, keys:[keyItem], ctrlKey:false, altKey:false, shiftKey:false, logoKey:false, fnKey:false, capsLock:false, numLock:false, scrollLock:false}; avSession.sendSystemAVKeyEvent(event).then(() => { - console.info('SendSystemAVKeyEvent Successfully'); + console.info(`SendSystemAVKeyEvent Successfully`); }).catch((err) => { console.info(`SendSystemAVKeyEvent BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -734,7 +735,7 @@ Sends a system key event to the top session. This API uses an asynchronous callb | Name | Type | Mandatory| Description | | -------- | ------------------------------------------------------------ | ---- | ------------------------------------- | | event | [KeyEvent](js-apis-keyevent.md) | Yes | Key event. | -| callback | AsyncCallback | Yes | Callback used to return the result. If the event is sent, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the event is sent, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -755,7 +756,7 @@ avSession.sendSystemAVKeyEvent(event, function (err) { if (err) { console.info(`SendSystemAVKeyEvent BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('SendSystemAVKeyEvent : SUCCESS '); + console.info(`SendSystemAVKeyEvent : SUCCESS `); } }); ``` @@ -782,7 +783,7 @@ Sends a system control command to the top session. This API uses a promise to re | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the command is sent, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the command is sent, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -814,7 +815,7 @@ let avcommand = {command:cmd}; // let cmd : avSession.AVControlCommandType = 'toggleFavorite'; // let avcommand = {command:cmd, parameter:"false"}; avSession.sendSystemControlCommand(avcommand).then(() => { - console.info('SendSystemControlCommand successfully'); + console.info(`SendSystemControlCommand successfully`); }).catch((err) => { console.info(`SendSystemControlCommand BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -837,7 +838,7 @@ Sends a system control command to the top session. This API uses an asynchronous | Name | Type | Mandatory| Description | | -------- | ------------------------------------- | ---- | ------------------------------------- | | command | [AVControlCommand](#avcontrolcommand) | Yes | Command to send. | -| callback | AsyncCallback | Yes | Callback used to return the result. If the command is sent, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the command is sent, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -872,7 +873,7 @@ avSession.sendSystemControlCommand(avcommand, function (err) { if (err) { console.info(`SendSystemControlCommand BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('sendSystemControlCommand successfully'); + console.info(`sendSystemControlCommand successfully`); } }); ``` @@ -918,7 +919,7 @@ Sets session metadata. This API uses a promise to return the result. | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -949,7 +950,7 @@ let metadata = { nextAssetId: "121279", }; session.setAVMetadata(metadata).then(() => { - console.info('SetAVMetadata successfully'); + console.info(`SetAVMetadata successfully`); }).catch((err) => { console.info(`SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -970,7 +971,7 @@ Sets session metadata. This API uses an asynchronous callback to return the resu | Name | Type | Mandatory| Description | | -------- | ------------------------- | ---- | ------------------------------------- | | data | [AVMetadata](#avmetadata) | Yes | Session metadata. | -| callback | AsyncCallback | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -1004,7 +1005,7 @@ session.setAVMetadata(metadata, function (err) { if (err) { console.info(`SetAVMetadata BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('SetAVMetadata successfully'); + console.info(`SetAVMetadata successfully`); } }); ``` @@ -1029,10 +1030,9 @@ Sets information related to the session playback state. This API uses a promise | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| **Error codes** - For details about the error codes, see [AVSession Management Error Codes](../errorcodes/errorcode-avsession.md). | ID| Error Message| @@ -1052,7 +1052,7 @@ let playbackState = { isFavorite:true, }; session.setAVPlaybackState(playbackState).then(() => { - console.info('SetAVPlaybackState successfully'); + console.info(`SetAVPlaybackState successfully`); }).catch((err) => { console.info(`SetAVPlaybackState BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -1073,7 +1073,7 @@ Sets information related to the session playback state. This API uses an asynchr | Name | Type | Mandatory| Description | | -------- | ----------------------------------- | ---- | ---------------------------------------------- | | data | [AVPlaybackState](#avplaybackstate) | Yes | Information related to the session playback state.| -| callback | AsyncCallback | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object. | +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object. | **Error codes** @@ -1099,14 +1099,14 @@ session.setAVPlaybackState(PlaybackState, function (err) { if (err) { console.info(`SetAVPlaybackState BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('SetAVPlaybackState successfully'); + console.info(`SetAVPlaybackState successfully`); } }); ``` ### setAVQueueItems10+ -setAVQueueItems(items: Array\): Promise +setAVQueueItems(items: Array\): Promise\ Sets a playlist. This API uses a promise to return the result. @@ -1124,7 +1124,7 @@ Sets a playlist. This API uses a promise to return the result. | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -1138,12 +1138,14 @@ For details about the error codes, see [AVSession Management Error Codes](../err **Example** ```js +let imageSource : imageImageSource = image.createImageSource(value.buffer); +let imagePixel : image.PixelMap = await imageSource.createPixelMap({desiredSize:{width: 150, height: 150}}); let queueItemDescription_1 = { mediaId: '001', title: 'music_name', subtitle: 'music_sub_name', description: 'music_description', - icon: PIXELMAP_OBJECT, + icon : imagePixel, iconUri: 'http://www.icon.uri.com', extras: {'extras':'any'} }; @@ -1157,7 +1159,7 @@ let queueItemDescription_2 = { subtitle: 'music_sub_name', description: 'music_description', icon: PIXELMAP_OBJECT, - iconUri: 'http://www.icon.uri.com', + iconUri: 'http://www.xxx.com', extras: {'extras':'any'} }; let queueItem_2 = { @@ -1166,7 +1168,7 @@ let queueItem_2 = { }; let queueItemsArray = [queueItem_1, queueItem_2]; session.setAVQueueItems(queueItemsArray).then(() => { - console.info('SetAVQueueItems successfully'); + console.info(`SetAVQueueItems successfully`); }).catch((err) => { console.info(`SetAVQueueItems BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -1174,7 +1176,7 @@ session.setAVQueueItems(queueItemsArray).then(() => { ### setAVQueueItems10+ -setAVQueueItems(items: Array\, callback: AsyncCallback): void +setAVQueueItems(items: Array\, callback: AsyncCallback\): void Sets a playlist. This API uses an asynchronous callback to return the result. @@ -1187,7 +1189,7 @@ Sets a playlist. This API uses an asynchronous callback to return the result. | Name | Type | Mandatory| Description | | -------- | ------------------------------------ | ---- | ----------------------------------------------------------- | | items | Array<[AVQueueItem](#avqueueitem10)\> | Yes | Playlist to set. | -| callback | AsyncCallback | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -1201,12 +1203,14 @@ For details about the error codes, see [AVSession Management Error Codes](../err **Example** ```js +let imageSource : imageImageSource = image.createImageSource(value.buffer); +let imagePixel : image.PixelMap = await imageSource.createPixelMap({desiredSize:{width: 150, height: 150}}); let queueItemDescription_1 = { mediaId: '001', title: 'music_name', subtitle: 'music_sub_name', description: 'music_description', - icon: PIXELMAP_OBJECT, + icon: imagePixel, iconUri: 'http://www.icon.uri.com', extras: {'extras':'any'} }; @@ -1232,7 +1236,7 @@ session.setAVQueueItems(queueItemsArray, function (err) { if (err) { console.info(`SetAVQueueItems BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('SetAVQueueItems successfully'); + console.info(`SetAVQueueItems successfully`); } }); ``` @@ -1257,7 +1261,7 @@ Sets a name for the playlist. This API uses a promise to return the result. | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -1273,7 +1277,7 @@ For details about the error codes, see [AVSession Management Error Codes](../err ```js let queueTitle = 'QUEUE_TITLE'; session.setAVQueueTitle(queueTitle).then(() => { - console.info('SetAVQueueTitle successfully'); + console.info(`SetAVQueueTitle successfully`); }).catch((err) => { console.info(`SetAVQueueTitle BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -1281,7 +1285,7 @@ session.setAVQueueTitle(queueTitle).then(() => { ### setAVQueueTitle10+ -setAVQueueTitle(title: string, callback: AsyncCallback\): void +setAVQueueTitle(title: string, callback: AsyncCallback\): void Sets a name for the playlist. This API uses an asynchronous callback to return the result. @@ -1294,7 +1298,7 @@ Sets a name for the playlist. This API uses an asynchronous callback to return t | Name | Type | Mandatory| Description | | -------- | --------------------- | ---- | ----------------------------------------------------------- | | title | string | Yes | Name of the playlist. | -| callback | AsyncCallback | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -1313,7 +1317,7 @@ session.setAVQueueTitle(queueTitle, function (err) { if (err) { console.info(`SetAVQueueTitle BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('SetAVQueueTitle successfully'); + console.info(`SetAVQueueTitle successfully`); } }); ``` @@ -1338,7 +1342,7 @@ Sets a launcher ability. This API uses a promise to return the result. | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -1384,7 +1388,7 @@ let wantAgentInfo = { wantAgent.getWantAgent(wantAgentInfo).then((agent) => { session.setLaunchAbility(agent).then(() => { - console.info('SetLaunchAbility successfully'); + console.info(`SetLaunchAbility successfully`); }).catch((err) => { console.info(`SetLaunchAbility BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -1406,7 +1410,7 @@ Sets a launcher ability. This API uses an asynchronous callback to return the re | Name | Type | Mandatory| Description | | -------- | --------------------------------------------- | ---- | ------------------------------------------------------------ | | ability | [WantAgent](js-apis-app-ability-wantAgent.md) | Yes | Application attributes, such as the bundle name, ability name, and deviceID. | -| callback | AsyncCallback | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -1455,7 +1459,7 @@ wantAgent.getWantAgent(wantAgentInfo).then((agent) => { if (err) { console.info(`SetLaunchAbility BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('SetLaunchAbility successfully'); + console.info(`SetLaunchAbility successfully`); } }); }); @@ -1465,7 +1469,7 @@ wantAgent.getWantAgent(wantAgentInfo).then((agent) => { dispatchSessionEvent(event: string, args: {[key: string]: Object}): Promise\ -Dispatches a custom event in the session, including the event name and event content in key-value pair format. This API uses a promise to return the result. +Dispatches a custom event in the session, including the event name and event content in key-value pair format. This API uses a promise to return the result. It is called by the provider. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -1478,11 +1482,15 @@ Dispatches a custom event in the session, including the event name and event con | event | string | Yes | Name of the session event.| | args | {[key: string]: any} | Yes | Event content in key-value pair format.| +> **NOTE** +> +> The **args** parameter supports the following data types: string, number, Boolean, object, array, and file descriptor. For details, see [@ohos.app.ability.Want(Want)](./js-apis-app-ability-want.md). + **Return value** | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -1507,9 +1515,9 @@ await session.dispatchSessionEvent(eventName, args).catch((err) => { ### dispatchSessionEvent10+ -dispatchSessionEvent(event: string, args: {[key: string]: Object}, callback: AsyncCallback): void +dispatchSessionEvent(event: string, args: {[key: string]: Object}, callback: AsyncCallback\): void -Dispatches a custom event in the session, including the event name and event content in key-value pair format. This API uses an asynchronous callback to return the result. +Dispatches a custom event in the session, including the event name and event content in key-value pair format. This API uses an asynchronous callback to return the result. It is called by the provider. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -1521,7 +1529,11 @@ Dispatches a custom event in the session, including the event name and event con | ------- | --------------------------------------------- | ---- | ----------------------------------------------------------- | | event | string | Yes | Name of the session event.| | args | {[key: string]: any} | Yes | Event content in key-value pair format.| -| callback | AsyncCallback | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| + +> **NOTE** +> +> The **args** parameter supports the following data types: string, number, Boolean, object, array, and file descriptor. For details, see [@ohos.app.ability.Want(Want)](./js-apis-app-ability-want.md). **Error codes** @@ -1546,6 +1558,93 @@ await session.dispatchSessionEvent(eventName, args, (err) => { }) ``` +### setExtras10+ + +setExtras(extras: {[key: string]: Object}): Promise\ + +Sets a custom media packet in the form of key-value pairs. This API uses a promise to return the result. It is called by the provider. + +**System capability**: SystemCapability.Multimedia.AVSession.Core + +**System API**: This is a system API. + +**Parameters** + +| Name | Type | Mandatory| Description | +| ------- | --------------------------------------------- | ---- | ----------------------------------------------------------- | +| extras | {[key: string]: Object} | Yes | Key-value pairs of the custom media packet.| + +> **NOTE** +> +> The **extras** parameter supports the following data types: string, number, Boolean, object, array, and file descriptor. For details, see [@ohos.app.ability.Want(Want)](./js-apis-app-ability-want.md). + +**Return value** + +| Type | Description | +| -------------- | ----------------------------- | +| Promise\ | Promise used to return the result. If the setting is successful, no value is returned; otherwise, an error object is returned.| + +**Error codes** + +For details about the error codes, see [AVSession Management Error Codes](../errorcodes/errorcode-avsession.md). + +| ID| Error Message| +| -------- | ---------------------------------------- | +| 6600101 | Session service exception. | +| 6600102 | The session does not exist. | + +**Example** + +```js +let extras = { + extras : "This is custom media packet" +} +await session.setExtras(extras).catch((err) => { + console.info(`setExtras BusinessError: code: ${err.code}, message: ${err.message}`); +}) +``` + +### setExtras10+ + +setExtras(extras: {[key: string]: Object}, callback: AsyncCallback\): void + +Sets a custom media packet in the form of key-value pairs. This API uses an asynchronous callback to return the result. It is called by the provider. + +**System capability**: SystemCapability.Multimedia.AVSession.Core + +**Parameters** + +| Name | Type | Mandatory| Description | +| ------- | --------------------------------------------- | ---- | ----------------------------------------------------------- | +| extras | {[key: string]: any} | Yes | Key-value pairs of the custom media packet.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| + +> **NOTE** +> +> The **extras** parameter supports the following data types: string, number, Boolean, object, array, and file descriptor. For details, see [@ohos.app.ability.Want(Want)](./js-apis-app-ability-want.md). + +**Error codes** + +For details about the error codes, see [AVSession Management Error Codes](../errorcodes/errorcode-avsession.md). + +| ID| Error Message| +| -------- | ---------------------------------------- | +| 6600101 | Session service exception. | +| 6600102 | The session does not exist. | + +**Example** + +```js +let extras = { + extras : "This is custom media packet" +} +await session.setExtras(extras, (err) => { + if(err) { + console.info(`setExtras BusinessError: code: ${err.code}, message: ${err.message}`); + } +}) +``` + ### getController getController(): Promise\ @@ -1708,7 +1807,7 @@ Activates this session. A session can be used only after being activated. This A | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the session is activated, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the session is activated, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -1723,7 +1822,7 @@ For details about the error codes, see [AVSession Management Error Codes](../err ```js session.activate().then(() => { - console.info('Activate : SUCCESS '); + console.info(`Activate : SUCCESS `); }).catch((err) => { console.info(`Activate BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -1743,7 +1842,7 @@ Activates this session. A session can be used only after being activated. This A | Name | Type | Mandatory| Description | | -------- | -------------------- | ---- | ---------- | -| callback | AsyncCallback | Yes | Callback used to return the result. If the session is activated, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the session is activated, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -1761,7 +1860,7 @@ session.activate(function (err) { if (err) { console.info(`Activate BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('Activate : SUCCESS '); + console.info(`Activate : SUCCESS `); } }); ``` @@ -1780,7 +1879,7 @@ Deactivates this session. You can use [activate](#activate) to activate the sess | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the session is deactivated, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the session is deactivated, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -1795,7 +1894,7 @@ For details about the error codes, see [AVSession Management Error Codes](../err ```js session.deactivate().then(() => { - console.info('Deactivate : SUCCESS '); + console.info(`Deactivate : SUCCESS `); }).catch((err) => { console.info(`Deactivate BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -1817,7 +1916,7 @@ Deactivates this session. You can use [activate](#activate) to activate the sess | Name | Type | Mandatory| Description | | -------- | -------------------- | ---- | ---------- | -| callback | AsyncCallback | Yes | Callback used to return the result. If the session is deactivated, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the session is deactivated, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -1835,7 +1934,7 @@ session.deactivate(function (err) { if (err) { console.info(`Deactivate BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('Deactivate : SUCCESS '); + console.info(`Deactivate : SUCCESS `); } }); ``` @@ -1854,7 +1953,7 @@ Destroys this session. This API uses a promise to return the result. | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the session is destroyed, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the session is destroyed, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -1869,7 +1968,7 @@ For details about the error codes, see [AVSession Management Error Codes](../err ```js session.destroy().then(() => { - console.info('Destroy : SUCCESS '); + console.info(`Destroy : SUCCESS `); }).catch((err) => { console.info(`Destroy BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -1889,7 +1988,7 @@ Destroys this session. This API uses an asynchronous callback to return the resu | Name | Type | Mandatory| Description | | -------- | -------------------- | ---- | ---------- | -| callback | AsyncCallback | Yes | Callback used to return the result. If the session is destroyed, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the session is destroyed, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -1907,7 +2006,7 @@ session.destroy(function (err) { if (err) { console.info(`Destroy BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('Destroy : SUCCESS '); + console.info(`Destroy : SUCCESS `); } }); ``` @@ -1942,25 +2041,25 @@ For details about the error codes, see [AVSession Management Error Codes](../err ```js session.on('play', () => { - console.info('on play entry'); + console.info(`on play entry`); }); session.on('pause', () => { - console.info('on pause entry'); + console.info(`on pause entry`); }); session.on('stop', () => { - console.info('on stop entry'); + console.info(`on stop entry`); }); session.on('playNext', () => { - console.info('on playNext entry'); + console.info(`on playNext entry`); }); session.on('playPrevious', () => { - console.info('on playPrevious entry'); + console.info(`on playPrevious entry`); }); session.on('fastForward', () => { - console.info('on fastForward entry'); + console.info(`on fastForward entry`); }); session.on('rewind', () => { - console.info('on rewind entry'); + console.info(`on rewind entry`); }); ``` @@ -2217,7 +2316,7 @@ Subscribes to custom control command changes. | Name | Type | Mandatory| Description | | -------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | | type | string | Yes | Event type. The event **'commonCommand'** is reported when a custom control command changes.| -| callback | (commonCommand: string, args: {[key:string]: Object}) => void | Yes | Callback used for subscription. The **commonCommand** parameter in the callback indicates the name of the changed custom control command, and **args** indicates the parameters carried in the command. | +| callback | (commonCommand: string, args: {[key:string]: Object}) => void | Yes | Callback used for subscription. The **commonCommand** parameter in the callback indicates the name of the changed custom control command, and **args** indicates the parameters carried in the command. The parameters must be the same as those set in **sendCommand**. | **Error codes** @@ -2501,7 +2600,7 @@ session.off('outputDeviceChange'); ### off('commonCommand')10+ -off(type: 'commonCommand', callback?: (commonCommand: string, args: {[key:string]: Object}) => void): void +off(type: 'commonCommand', callback?: (command: string, args: {[key:string]: Object}) => void): void Unsubscribes from custom control command changes. @@ -2514,7 +2613,7 @@ Unsubscribes from custom control command changes. | Name | Type | Mandatory| Description | | -------- | ------------------------------------------------------------ | ---- | ----------------------------------------------------- | | type | string | Yes | Event type. The value is fixed at **'commonCommand'**. | -| callback | (commonCommand: string, args: {[key:string]: Object}) => void | No | Callback used for unsubscription. The **commonCommand** parameter in the callback indicates the name of the changed custom control command, and **args** indicates the parameters carried in the command.
The **callback** parameter is optional. If it is not specified, all the subscriptions to the specified event are canceled for this session. | +| callback | (command: string, args: {[key:string]: Object}) => void | No | Callback used for unsubscription. The **command** parameter in the callback indicates the name of the changed custom control command, and **args** indicates the parameters carried in the command.
The **callback** parameter is optional. If it is not specified, all the subscriptions to the specified event are canceled for this session. | **Error codes** @@ -2540,6 +2639,8 @@ An AV session controller is created by calling [avSession.createController](#avs **System capability**: SystemCapability.Multimedia.AVSession.Core +**System API**: This is a system API. + | Name | Type | Readable| Writable| Description | | :-------- | :----- | :--- | :--- | :-------------------------------------- | @@ -2792,7 +2893,7 @@ Sends the ID of an item in the playlist to the session for processing. The sessi | Type | Description | | -------------- | --------------------------------------------------------------- | -| Promise | Promise used to return the result. If the item ID is sent, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the item ID is sent, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -2808,7 +2909,7 @@ For details about the error codes, see [AVSession Management Error Codes](../err ```js let queueItemId = 0; controller.skipToQueueItem(queueItemId).then(() => { - console.info('SkipToQueueItem successfully'); + console.info(`SkipToQueueItem successfully`); }).catch((err) => { console.info(`SkipToQueueItem BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -2829,7 +2930,7 @@ Sends the ID of an item in the playlist to the session for processing. The sessi | Name | Type | Mandatory| Description | | -------- | --------------------- | ---- | ----------------------------------------------------------- | | itemId | number | Yes | ID of an item in the playlist. | -| callback | AsyncCallback | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the setting is successful, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -2848,7 +2949,7 @@ controller.skipToQueueItem(queueItemId, function (err) { if (err) { console.info(`SkipToQueueItem BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('SkipToQueueItem successfully'); + console.info(`SkipToQueueItem successfully`); } }); ``` @@ -2996,6 +3097,92 @@ controller.getOutputDevice(function (err, deviceInfo) { }); ``` +### getExtras10+ + +getExtras(): Promise\<{[key: string]: Object}> + +Obtains the custom media packet set by the provider. This API uses a promise to return the result. + +**System capability**: SystemCapability.Multimedia.AVSession.Core + +**System API**: This is a system API. + +**Return value** + +| Type | Description | +| ----------------------------------- | ----------------------------- | +| Promise<{[key: string]: Object}\> | Promise used to return the custom media packet. The content of the packet is the same as that set in **setExtras**.| + +**Error codes** + +For details about the error codes, see [AVSession Management Error Codes](../errorcodes/errorcode-avsession.md). + +| ID| Error Message| +| -------- | ---------------------------------------- | +| 6600101 | Session service exception. | +| 6600102 | The session does not exist. | +| 6600103 | The session controller does not exist. | + +**Example** +```js +let extras = await controller.getExtras().catch((err) => { + console.info(`getExtras BusinessError: code: ${err.code}, message: ${err.message}`); +}); +``` + +### getExtras10+ + +getExtras(callback: AsyncCallback\<{[key: string]: Object}>): void + +Obtains the custom media packet set by the provider. This API uses an asynchronous callback to return the result. + +**System capability**: SystemCapability.Multimedia.AVSession.Core + +**System API**: This is a system API. + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ----------------------------------------- | ---- | -------------------------- | +| callback | AsyncCallback<{[key: string]: Object}\> | Yes | Callback used to return the custom media packet. The content of the packet is the same as that set in **setExtras**.| + +**Error codes** + +For details about the error codes, see [AVSession Management Error Codes](../errorcodes/errorcode-avsession.md). + +| ID| Error Message| +| -------- | ---------------------------------------- | +| 6600101 | Session service exception. | +| 6600102 | The session does not exist. | +| 6600103 | The session controller does not exist. | + +**Example** +```js +let metadata = { + assetId: "121278", + title: "lose yourself", + artist: "Eminem", + author: "ST", + album: "Slim shady", + writer: "ST", + composer: "ST", + duration: 2222, + mediaImage: "https://www.example.com/example.jpg", + subtitle: "8 Mile", + description: "Rap", + lyric: "https://www.example.com/example.lrc", + previousAssetId: "121277", + nextAssetId: "121279", +}; +controller.getExtras(function (err, extras) { + if (err) { + console.info(`getExtras BusinessError: code: ${err.code}, message: ${err.message}`); + } else { + console.info(`getExtras : SUCCESS : assetId : ${metadata.assetId}`); + } +}); +``` + ### sendAVKeyEvent sendAVKeyEvent(event: KeyEvent): Promise\ @@ -3028,7 +3215,7 @@ For details about the error codes, see [AVSession Management Error Codes](../err | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the event is sent, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the event is sent, no value is returned; otherwise, an error object is returned.| **Example** @@ -3037,7 +3224,7 @@ let keyItem = {code:0x49, pressedTime:2, deviceId:0}; let event = {action:2, key:keyItem, keys:[keyItem]}; controller.sendAVKeyEvent(event).then(() => { - console.info('SendAVKeyEvent Successfully'); + console.info(`SendAVKeyEvent Successfully`); }).catch((err) => { console.info(`SendAVKeyEvent BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -3058,7 +3245,7 @@ Sends a key event to the session corresponding to this controller. This API uses | Name | Type | Mandatory| Description | | -------- | ------------------------------------------------------------ | ---- | ---------- | | event | [KeyEvent](js-apis-keyevent.md) | Yes | Key event.| -| callback | AsyncCallback | Yes | Callback used to return the result. If the event is sent, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the event is sent, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -3082,7 +3269,7 @@ controller.sendAVKeyEvent(event, function (err) { if (err) { console.info(`SendAVKeyEvent BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('SendAVKeyEvent Successfully'); + console.info(`SendAVKeyEvent Successfully`); } }); ``` @@ -3284,7 +3471,7 @@ Destroys this controller. A controller can no longer be used after being destroy | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the controller is destroyed, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the controller is destroyed, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -3299,7 +3486,7 @@ For details about the error codes, see [AVSession Management Error Codes](../err ```js controller.destroy().then(() => { - console.info('Destroy : SUCCESS '); + console.info(`Destroy : SUCCESS `); }).catch((err) => { console.info(`Destroy BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -3319,7 +3506,7 @@ Destroys this controller. A controller can no longer be used after being destroy | Name | Type | Mandatory| Description | | -------- | -------------------- | ---- | ---------- | -| callback | AsyncCallback | Yes | Callback used to return the result. If the controller is destroyed, **err** is **undefined**; otherwise, **err** is an error object.| +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the controller is destroyed, **err** is **undefined**; otherwise, **err** is an error object.| **Error codes** @@ -3337,7 +3524,7 @@ controller.destroy(function (err) { if (err) { console.info(`Destroy BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('Destroy : SUCCESS '); + console.info(`Destroy : SUCCESS `); } }); ``` @@ -3422,6 +3609,10 @@ sendControlCommand(command: AVControlCommand): Promise\ Sends a control command to the session through the controller. This API uses a promise to return the result. +> **NOTE** +> +> Before using **sendControlCommand**, the controller must ensure that the AVSession has registered with the corresponding listener. For details about how to register the listener, see [Registering AVSession Listeners](#onplaypausestopplaynextplaypreviousfastforwardrewind). + **System capability**: SystemCapability.Multimedia.AVSession.Core **System API**: This is a system API. @@ -3436,7 +3627,7 @@ Sends a control command to the session through the controller. This API uses a p | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the command is sent, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the command is sent, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -3466,7 +3657,7 @@ let avCommand = {command:'play'}; // let avCommand = {command:'setLoopMode', parameter:avSession.LoopMode.LOOP_MODE_SINGLE}; // let avCommand = {command:'toggleFavorite', parameter:"false"}; controller.sendControlCommand(avCommand).then(() => { - console.info('SendControlCommand successfully'); + console.info(`SendControlCommand successfully`); }).catch((err) => { console.info(`SendControlCommand BusinessError: code: ${err.code}, message: ${err.message}`); }); @@ -3478,6 +3669,10 @@ sendControlCommand(command: AVControlCommand, callback: AsyncCallback\): v Sends a control command to the session through the controller. This API uses an asynchronous callback to return the result. +> **NOTE** +> +> Before using **sendControlCommand**, the controller must ensure that the AVSession has registered with the corresponding listener. For details about how to register the listener, see [Registering AVSession Listeners](#onplaypausestopplaynextplaypreviousfastforwardrewind). + **System capability**: SystemCapability.Multimedia.AVSession.Core **System API**: This is a system API. @@ -3487,7 +3682,7 @@ Sends a control command to the session through the controller. This API uses an | Name | Type | Mandatory| Description | | -------- | ------------------------------------- | ---- | ------------------------------ | | command | [AVControlCommand](#avcontrolcommand) | Yes | Command to send.| -| callback | AsyncCallback | Yes | Callback used to return the result. If the command is sent, **err** is **undefined**; otherwise, **err** is an error object. | +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the command is sent, **err** is **undefined**; otherwise, **err** is an error object. | **Error codes** @@ -3520,7 +3715,7 @@ controller.sendControlCommand(avCommand, function (err) { if (err) { console.info(`SendControlCommand BusinessError: code: ${err.code}, message: ${err.message}`); } else { - console.info('SendControlCommand successfully'); + console.info(`SendControlCommand successfully`); } }); ``` @@ -3533,6 +3728,8 @@ Sends a custom control command to the session through the controller. This API u **System capability**: SystemCapability.Multimedia.AVSession.Core +**System API**: This is a system API. + **Parameters** | Name | Type | Mandatory| Description | @@ -3540,11 +3737,15 @@ Sends a custom control command to the session through the controller. This API u | command | string | Yes | Name of the custom control command.| | args | {[key: string]: any} | Yes | Parameters in key-value pair format carried in the custom control command.| +> **NOTE** +> +> The **args** parameter supports the following data types: string, number, Boolean, object, array, and file descriptor. For details, see [@ohos.app.ability.Want(Want)](./js-apis-app-ability-want.md). + **Return value** | Type | Description | | -------------- | ----------------------------- | -| Promise | Promise used to return the result. If the command is sent, no value is returned; otherwise, an error object is returned.| +| Promise\ | Promise used to return the result. If the command is sent, no value is returned; otherwise, an error object is returned.| **Error codes** @@ -3579,16 +3780,21 @@ Sends a custom control command to the session through the controller. This API u **System capability**: SystemCapability.Multimedia.AVSession.Core +**System API**: This is a system API. + **Parameters** | Name | Type | Mandatory| Description | | ------- | ------------------------------------- | ---- | ------------------------------ | | command | string | Yes | Name of the custom control command.| | args | {[key: string]: any} | Yes | Parameters in key-value pair format carried in the custom control command.| -| callback | AsyncCallback | Yes | Callback used to return the result. If the command is sent, **err** is **undefined**; otherwise, **err** is an error object. | +| callback | AsyncCallback\ | Yes | Callback used to return the result. If the command is sent, **err** is **undefined**; otherwise, **err** is an error object. | -**Error codes** +> **NOTE** +> +> The **args** parameter supports the following data types: string, number, Boolean, object, array, and file descriptor. For details, see [@ohos.app.ability.Want(Want)](./js-apis-app-ability-want.md). +**Error codes** For details about the error codes, see [AVSession Management Error Codes](../errorcodes/errorcode-avsession.md). | ID| Error Message| @@ -3698,7 +3904,7 @@ controller.on('playbackStateChange', playbackFilter, (playbackState) => { on(type: 'sessionEvent', callback: (sessionEvent: string, args: {[key:string]: Object}) => void): void -Subscribes to session event changes. +Subscribes to session event changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -3732,7 +3938,7 @@ controller.on('sessionEvent', (sessionEvent, args) => { on(type: 'queueItemsChange', callback: (items: Array<[AVQueueItem](#avqueueitem10)\>) => void): void -Subscribes to playlist item changes. +Subscribes to playlist item changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -3766,7 +3972,7 @@ controller.on('queueItemsChange', (items) => { on(type: 'queueTitleChange', callback: (title: string) => void): void -Subscribes to playlist name changes. +Subscribes to playlist name changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -3796,6 +4002,41 @@ controller.on('queueTitleChange', (title) => { }); ``` +### on('extrasChange')10+ + +on(type: 'extrasChange', callback: (extras: {[key:string]: Object}) => void): void + +Subscribes to custom media packet changes. This API is called by the controller. + +**System capability**: SystemCapability.Multimedia.AVSession.Core + +**System API**: This is a system API. + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ------------------------------------------------------------ | ---- | ------------------------------------------------------------ | +| type | string | Yes | Event type. The event **'extrasChange'** is reported when the provider sets a custom media packet.| +| callback | (extras: {[key:string]: object}) => void | Yes | Callback used for subscription. The **extras** parameter in the callback indicates the custom media packet set by the provider. This packet is the same as that set in **dispatchSessionEvent**. | + +**Error codes** + +For details about the error codes, see [AVSession Management Error Codes](../errorcodes/errorcode-avsession.md). + +| ID| Error Message| +| -------- | ------------------------------ | +| 6600101 | Session service exception. | +| 6600103 | The session controller does not exist. | +| 401 | Parameter check failed | + +**Example** + +```js +controller.on('extrasChange', (extras) => { + console.info(`Caught extrasChange event,the new extra is: ${JSON.stringify(extras)}`); +}); +``` + ### on('sessionDestroy') on(type: 'sessionDestroy', callback: () => void) @@ -3826,7 +4067,7 @@ For details about the error codes, see [AVSession Management Error Codes](../err ```js controller.on('sessionDestroy', () => { - console.info('on sessionDestroy : SUCCESS '); + console.info(`on sessionDestroy : SUCCESS `); }); ``` @@ -3937,7 +4178,7 @@ controller.on('outputDeviceChange', (device) => { off(type: 'metadataChange', callback?: (data: AVMetadata) => void) -Unsubscribes from metadata changes. +Unsubscribes from metadata changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -3968,7 +4209,7 @@ controller.off('metadataChange'); off(type: 'playbackStateChange', callback?: (state: AVPlaybackState) => void) -Unsubscribes from playback state changes. +Unsubscribes from playback state changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -3999,7 +4240,7 @@ controller.off('playbackStateChange'); off(type: 'sessionEvent', callback?: (sessionEvent: string, args: {[key:string]: Obejct}) => void): void -Unsubscribes from session event changes. +Unsubscribes from session event changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -4030,7 +4271,7 @@ controller.off('sessionEvent'); off(type: 'queueItemsChange', callback?: (items: Array<[AVQueueItem](#avqueueitem10)\>) => void): void -Unsubscribes from playback item changes. +Unsubscribes from playback item changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -4061,7 +4302,7 @@ controller.off('queueItemsChange'); off(type: 'queueTitleChange', callback?: (title: string) => void): void -Unsubscribes from playlist name changes. +Unsubscribes from playlist name changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -4088,11 +4329,44 @@ For details about the error codes, see [AVSession Management Error Codes](../err controller.off('queueTitleChange'); ``` +### off('extrasChange')10+ + +off(type: 'extrasChange', callback?: (extras: {[key:string]: Object}) => void): void + +Unsubscribes from custom media packet changes. This API is called by the controller. + +**System capability**: SystemCapability.Multimedia.AVSession.Core + +**System API**: This is a system API. + +**Parameters** + +| Name | Type | Mandatory| Description | +| -------- | ----------------------- | ---- | ------------------------------------------------------------------------------------------------------- | +| type | string | Yes | Event type. The value is fixed at **'extrasChange'**. | +| callback | ({[key:string]: Object}) => void | No | Callback used for unsubscription.
The **callback** parameter is optional. If it is not specified, all the subscriptions to the specified event are canceled for this session.| + +**Error codes** + +For details about the error codes, see [AVSession Management Error Codes](../errorcodes/errorcode-avsession.md). + +| ID| Error Message| +| -------- | ---------------- | +| 6600101 | Session service exception. | +| 6600103 | The session controller does not exist. | +| 401 | Parameter check failed | + +**Example** + +```js +controller.off('extrasChange'); +``` + ### off('sessionDestroy') off(type: 'sessionDestroy', callback?: () => void) -Unsubscribes from the session destruction event. +Unsubscribes from the session destruction event. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -4123,7 +4397,7 @@ controller.off('sessionDestroy'); off(type: 'activeStateChange', callback?: (isActive: boolean) => void) -Unsubscribes from session activation state changes. +Unsubscribes from session activation state changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -4154,7 +4428,7 @@ controller.off('activeStateChange'); off(type: 'validCommandChange', callback?: (commands: Array\) => void) -Unsubscribes from valid command changes. +Unsubscribes from valid command changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -4185,7 +4459,7 @@ controller.off('validCommandChange'); off(type: 'outputDeviceChange', callback?: (device: OutputDeviceInfo) => void): void -Unsubscribes from output device changes. +Unsubscribes from output device changes. This API is called by the controller. **System capability**: SystemCapability.Multimedia.AVSession.Core @@ -4363,6 +4637,8 @@ Describes the information related to the media playback state. | bufferedTime | number | No | Buffered time.| | loopMode | [LoopMode](#loopmode) | No | Loop mode.| | isFavorite | boolean | No | Whether the media asset is favorited.| +| activeItemId10+ | number | No | ID of the item that is being played.| +| extras10+ | {[key: string]: Object} | No | Custom media data.| ## PlaybackPosition @@ -4442,3 +4718,5 @@ Enumerates the error codes used in the media session. | ERR_CODE_COMMAND_INVALID | 6600105 | Invalid session command. | | ERR_CODE_SESSION_INACTIVE | 6600106 | The session is not activated. | | ERR_CODE_MESSAGE_OVERLOAD | 6600107 | Too many commands or events. | + + \ No newline at end of file