BackgroundAudioController.ets 7.77 KB
import { Context, WantAgent, wantAgent } from '@kit.AbilityKit'
import { avSession as AVSessionManager } from '@kit.AVSessionKit'
import { backgroundTaskManager } from '@kit.BackgroundTasksKit'
import { BusinessError } from '@kit.BasicServicesKit'
import { Logger } from 'wdKit/Index'
import { PlayerConstants } from '../constants/PlayerConstants'
import { WDPlayerController } from './WDPlayerController'

const TAG = "BackgroundAudioController"

export class BackgroundAudioController {

  private static bgAudioController: BackgroundAudioController
  private constructor() {
  }
  public static sharedController() {
    if (!BackgroundAudioController.bgAudioController) {
      BackgroundAudioController.bgAudioController = new BackgroundAudioController()
    }
    return BackgroundAudioController.bgAudioController
  }

  public gotContextFunc?: () => Context
  public avplayerController?: WDPlayerController
  private lastSession?: AVSessionManager.AVSession

  // 开始创建并激活媒体会话
  // 创建session
  async createSession() {
    if (!this.gotContextFunc) { return }
    this.destorySession()
    let type: AVSessionManager.AVSessionType = 'audio';
    let session = await AVSessionManager.createAVSession(this.gotContextFunc(),'SESSION_NAME', type);

    // 激活接口要在元数据、控制命令注册完成之后再执行
    await session.activate();
    Logger.debug(TAG, `session create done : sessionId : ${session.sessionId}`);

    this.lastSession = session
  }

  destorySession() {
    if (this.lastSession) {
      this.lastSession.deactivate();
      this.lastSession.destroy();
    }
  }

  //设置播放元数据
  setSessionMetaData(assetId: string, title: string, mediaImage: string, artist?: string) {
    let metadata: AVSessionManager.AVMetadata = {
      assetId: assetId,
      title: title,
      mediaImage: mediaImage,
      artist: artist ?? "",
      // duration: "",
    };
    this.lastSession?.setAVMetadata(metadata).then(() => {
      Logger.debug(TAG, `SetAVMetadata successfully`);
    }).catch((err: BusinessError) => {
      Logger.error(TAG, `Failed to set AVMetadata. Code: ${err.code}, message: ${err.message}`);
    });
  }

  //设置播放状态
  setSessionPlayStatus(playStatus: number) {
    let pauseed = playStatus == PlayerConstants.STATUS_PAUSE
    let playbackState: AVSessionManager.AVPlaybackState = {
      state:pauseed ? AVSessionManager.PlaybackState.PLAYBACK_STATE_PAUSE : AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY,
      isFavorite:false
    };
    this.lastSession?.setAVPlaybackState(playbackState, (err: BusinessError) => {
      if (err) {
        Logger.error(TAG, `Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`);
      } else {
        Logger.debug(TAG, `SetAVPlaybackState 设置播放状态成功` + playStatus);
      }
    });
  }

  //设置进度,单位秒
  setSessionPlayProgress(progressDuration: number, totalDuration: number) {
    Logger.debug(TAG, `set progress: ` + progressDuration + " duration: " + totalDuration);
    if (totalDuration <= 0) {
      return
    }
    // 设置状态: 播放状态,进度位置,播放倍速,缓存的时间
    let playbackState: AVSessionManager.AVPlaybackState = {
      state: AVSessionManager.PlaybackState.PLAYBACK_STATE_PLAY, // 播放状态
      position: {
        elapsedTime: progressDuration * 1000, // 已经播放的位置,以ms为单位
        updateTime: new Date().getTime(), // 应用更新当前位置时的时间戳,以ms为单位
      },
      duration: totalDuration * 1000,
      // speed: 1.0, // 可选,默认是1.0,播放的倍速,按照应用内支持的speed进行设置,系统不做校验
      // bufferedTime: 14000, // 可选,资源缓存的时间,以ms为单位
    };
    this.lastSession?.setAVPlaybackState(playbackState, (err) => {
      if (err) {
        Logger.error(TAG, `Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`);
      } else {
        // Logger.debug(TAG, `SetAVPlaybackState successfully`);
      }
    });
  }

  // 置灰或禁用不支持的按钮
  stopUseFeatures() {
    // 取消指定session下的相关监听
    this.lastSession?.off('playFromAssetId');
    this.lastSession?.off('setSpeed');
    this.lastSession?.off('setLoopMode');
    this.lastSession?.off('toggleFavorite');
    this.lastSession?.off('skipToQueueItem');
    this.lastSession?.off('handleKeyEvent');
    this.lastSession?.off('commonCommand');
    this.lastSession?.off('rewind');
    this.lastSession?.off('fastForward');
  }

  listenPlayEvents() {
    this.lastSession?.on('play', () => {
      Logger.debug(TAG, `on play `);
    });
    this.lastSession?.on('pause', () => {
      Logger.debug(TAG, `on pause `);
    });
    this.lastSession?.on('stop', () => {
      Logger.debug(TAG, `on stop `);
    });
    this.lastSession?.on('playNext', () => {
      Logger.debug(TAG, `on playNext `);
    });
    this.lastSession?.on('playPrevious', () => {
      Logger.debug(TAG, `on playPrevious `);
    });

    this.lastSession?.on('seek', (position: number) => {
      Logger.debug(TAG, `on seek , the time is ${JSON.stringify(position)}`);

      // 由于应用内seek可能会触发较长的缓冲等待,可以先把状态设置为 Buffering
      let playbackState: AVSessionManager.AVPlaybackState = {
        state: AVSessionManager.PlaybackState.PLAYBACK_STATE_BUFFERING, // 缓冲状态
      };
      this.lastSession?.setAVPlaybackState(playbackState, (err) => {
        if (err) {
          Logger.debug(TAG, `Failed to set AVPlaybackState. Code: ${err.code}, message: ${err.message}`);
        } else {
          Logger.debug(TAG, `SetAVPlaybackState seek buffering`);
        }
      });

      // 应用响应seek命令,使用应用内播放器完成seek实现


    });
  }

  // 开启后台长时任务
  startContinuousTask() {
    let params: Record<string, string> = {
      "title": "开始后台任务",
      "content": "内容?",
      // "pushLink": pushLink,
      // "taskid": message.taskId,
      // "messageId": message.messageId,
      // "gtTransmitMsgLocalNotify": "1",
    }

    let wantAgentInfo: wantAgent.WantAgentInfo = {
      // 点击通知后,将要执行的动作列表
      // 添加需要被拉起应用的bundleName和abilityName
      wants: [
        {
          deviceId: '',
          bundleName: "com.peopledailychina.hosactivity",
          abilityName: "EntryAbility",
          action: 'com.test.pushaction',
          entities: [],
          parameters:params,
        }
      ],
      // 指定点击通知栏消息后的动作是拉起ability
      actionType: wantAgent.OperationType.START_ABILITY,
      // 使用者自定义的一个私有值
      requestCode: 0,
      // 点击通知后,动作执行属性
      wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG],
    };

    // 通过wantAgent模块下getWantAgent方法获取WantAgent对象
    wantAgent.getWantAgent(wantAgentInfo).then((wantAgentObj: WantAgent) => {
      if (!this.gotContextFunc) { return }
      backgroundTaskManager.startBackgroundRunning(this.gotContextFunc(),
        backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK,
        wantAgentObj).then(() => {
        Logger.debug(TAG, `Succeeded in operationing startBackgroundRunning.`);
      }).catch((err: BusinessError) => {
        Logger.error(TAG, `Failed to operation startBackgroundRunning. Code is ${err.code}, message is ${err.message}`);
      });
    });
  }

  stopContinuousTask() {
    if (!this.gotContextFunc) { return }
    backgroundTaskManager.stopBackgroundRunning(this.gotContextFunc()).then(() => {
      Logger.debug(TAG, `Succeeded in operationing stopBackgroundRunning.`);
    }).catch((err: BusinessError) => {
      Logger.error(TAG, `Failed to operation stopBackgroundRunning. Code is ${err.code}, message is ${err.message}`);
    });
  }

}