目录

Local Media Session FAQs

This document summarizes typical issues encountered by audio and video apps during local media session integration with AVSession Kit, along with their diagnosis and resolution methods. You can use AVSession management error codes and HiLog logs to further diagnose issues.

AVSession Creation Failure

Symptom

An exception is thrown when createAVSession is called, and the session is not created successfully.

Possible Causes

Solution

  1. Check whether a live AVSession already exists. If necessary, call destroy to release the old session before creating a new one. Before creation, you can also call getAVSession to check whether the current app has already created a session object, and then decide whether to destroy the old session or reuse the existing one.

  2. In scenarios involving frequent creation and destruction, listen for the on('sessionDestroy') event through the media session controller, and create a new AVSession object only after receiving the old session destruction callback.

    import { avSession } from '@kit.AVSessionKit';
    
    async destroyAndRecreateAVSession(context: Context) {
        let videoSession: avSession.AVSession;
        let avSessionController: avSession.AVSessionController;
        try {
            // Create an AVSession for the first time and obtain its controller.
            videoSession = await avSession.createAVSession(context, 'VIDEO_SESSION', 'video');
            avSessionController = await videoSession.getController();
    
            // Register a session destruction listener. The callback is triggered after the session is destroyed.
            avSessionController.on('sessionDestroy', async () => {
                // Create an AVSession for the second time. Re-create a session of the same type after destruction.
                videoSession = await avSession.createAVSession(context, 'VIDEO_SESSION', 'video');
                // Destroy the AVSession for the second time.
                await videoSession.destroy();
            });
    
            // Destroy the AVSession for the first time, which triggers the sessionDestroy callback above.
            await videoSession.destroy();
        } catch (err) {
            console.error(`AVSession create Error: Code: ${err.code}, message: ${err.message}`);
        }
    }
  3. It is recommended to obtain the context through this.getUIContext().getHostContext() as Context to avoid passing undefined or a context that does not belong to the current UIAbility.

  4. Ensure that type is a valid value defined in AVSessionType.

  5. Ensure that all required parameters are valid non-null values. For example, avoid passing invalid values such as an empty string for tag.

Audio and Video Forcibly Paused After App Is Relegated to Background

Symptom

After the app is switched to the background, audio and video playback is forcibly paused by the system, and the user cannot continue listening.

Possible Causes

Solution

  1. Refer to Accessing AVSession in Background Playback to complete AVSession integration.

  2. Apply for an AUDIO_PLAYBACK type continuous task (ArkTS).

  3. Use a class member variable to hold the session instance, and release it only when the app process ends or the playback service exits.

  4. Check the related causes in AVSession Creation Failure one by one to ensure that the app holds a valid session.

  5. Before the app is relegated to the background, call setBackgroundPlayMode to set the background playback mode (BackgroundPlayMode), which informs the system whether to continue playback when the app is relegated to the background:

    • ENABLE_BACKGROUND_PLAY (supports background playback): The app continues playback when relegated to the background.
    • DISABLE_BACKGROUND_PLAY (does not support background playback): The app stops playback when relegated to the background.

    For apps with AVSessionType set to audio, the default value is ENABLE_BACKGROUND_PLAY; for apps with the type set to video, the default value is DISABLE_BACKGROUND_PLAY. If a video app needs to support background audio playback, you must explicitly set it to ENABLE_BACKGROUND_PLAY. If the app provides a "whether background playback is supported" switch, the background playback mode set must be consistent with the switch state; otherwise, the app may be forcibly paused after being relegated to the background, or the system Live View may display incorrectly. The following is a setup example:

    import { avSession } from '@kit.AVSessionKit';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    // Assume that currentAVSession has been created and held.
    async setBackgroundPlayMode(currentAVSession: avSession.AVSession) {
      try {
        await currentAVSession.setBackgroundPlayMode(avSession.BackgroundPlayMode.ENABLE_BACKGROUND_PLAY);
        console.info(' Succeeded in setBackgroundPlayMode');
      } catch (err) {
        let error = err as BusinessError;
        console.error(`setBackgroundPlayMode BusinessError: code: ${error.code}, message: ${error.message}`);
      }
    }

For more details, see Setting the Background Playback Mode.

Media Control Center Not Displaying the App Session

Symptom

The app has created an AVSession, but the Media Control Center does not display the corresponding media information or control bar.

Possible Causes

Solution

  1. Set media information such as the title, subtitle/artist, and album art. For details, see Setting Metadata Information. Ensure that key metadata fields such as assetId use valid values, and avoid passing empty strings, which may cause the setting to fail.
  2. Register at least one control command. For details, see Control Command Processing.
  3. Ensure that fields such as mediaImage, avQueueName, and avQueueId use valid characters.
  4. Ensure that the lyric content does not exceed the length limit of 40960 bytes.
  5. When a call app integrates AVSession, the session type (AVSessionType) must be set to voice_call or video_call.

    In HarmonyOS 6.0.0 and later versions, when an app is released as a business or social app on AppGallery, the message "In a call..." can be displayed in the Media Controller, and the AVCastPicker component can be used to switch the call device. For details, see Switching Call Output Devices.

Control Command Unresponsive or Media Control Display Mismatch

Symptom

When control buttons (play, pause, previous, next, etc.) are tapped in the media control center, there is no response, and neither the app nor the media control interface is updated. Alternatively, the actual playback state of the app is out of sync with the state displayed in the media control center — for example, the app is playing but the media control still shows paused.

Possible Causes

Solution

  1. Activate the session through activate and confirm that the session has been activated.
  2. Register listeners for the corresponding control commands through the AVSession object's on('play'), on('pause'), on('playNext'), on('playPrevious'), and other APIs, and drive the player to perform the corresponding operations in the callbacks. Refer to Control Command Processing to complete the registration logic.
  3. Call setAVPlaybackState to update the playback state when the playback state changes. When the state is set to PLAYBACK_STATE_PAUSE, the system reclaims the media control card in the capsule area 5 seconds after the app is relegated to the background, and reclaims the media control cards in the Notification Bar and Lock Screen positions 10 minutes later.

Playback Progress Bar Rewind Flicker

Symptom

After tapping the play button in the media control center, the playback progress bar rewinds and flickers.

Possible Causes

The player startup delay causes progress inconsistency. After the play button is tapped, the playback progress bar in the media control center starts timing immediately, while the player in the app has not actually started playback yet, causing its progress to lag behind the media control center. When the app subsequently synchronizes the progress, the progress value is smaller than the elapsed time tracked by the media control center, resulting in the progress bar rewinding and flickering.

Solution

Before the player starts playback, call setAVPlaybackState to set the state to PLAYBACK_STATE_BUFFERING (buffering). After the player actually starts playback, synchronize the state and progress.

import { avSession } from '@kit.AVSessionKit';
import { media } from '@kit.MediaKit';

// avPlayer is the player instance created through media.createAVPlayer(), and currentAVSession is the created AVSession object.

async listenAVPlayer(avPlayer: media.AVPlayer, currentAVSession: avSession.AVSession) {
    // Listen for AVPlayer state machine transitions in advance. After actual playback starts (entering the playing state), synchronize the actual state and progress.
    avPlayer.on('stateChange', async (state: string) => {
        if (state === 'playing') {
        let playingState: avSession.AVPlaybackState = {
            state: avSession.PlaybackState.PLAYBACK_STATE_PLAY,
            speed: 1.0,
            // currentTime is the current actual playback progress of AVPlayer, in milliseconds (ms).
            position: { elapsedTime: avPlayer.currentTime, updateTime: (new Date()).getTime() }
        };
        await currentAVSession.setAVPlaybackState(playingState);
        }
    });

    // After receiving a playback command and before AVPlayer actually starts playback, set the media control state to buffering to prevent the media control progress bar from starting to count ahead of time.
    let bufferingState: avSession.AVPlaybackState = {
        state: avSession.PlaybackState.PLAYBACK_STATE_BUFFERING,
        speed: 0,
        position: { elapsedTime: 0, updateTime: (new Date()).getTime() }
    };
    await currentAVSession.setAVPlaybackState(bufferingState);
    await avPlayer.play();
}