如何实现媒体会话交互功能

媒体会话交互功能

HarmonyOS
2024-05-28 20:09:53
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
jennyhan

此内容主要展示了媒体会话的相关功能,使用@ohos.multimedia.avsession等接口实现媒体提供方与媒体控制方自定义信息的交互功能。可以用来制作媒体播放等内容

相关核心API

通过接口createAVSession()创建媒体会话;

通过接口activate()激活媒体会话;

通过接口setAVQueueItems()设置播放列表,设置后媒体控制方可以读取使用该信息;

通过接口setAVQueueTitle()设置播放列表标题,设置后媒体控制方可以读取使用该信息;

通过接口setAVMetadata()设置当前媒体的元数据,设置后媒体控制方可以读取使用此信息;

通过接口on()开启对媒体控制方控制命令的监听,对媒体控制方的命令进行处理;

核心代码介绍

打开应用的主界面设计

  build() { 
    Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { 
      Flex({ direction: FlexDirection.Row, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { 
        Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) { 
          Text(this.isPlaying ? $r('app.string.In_play') : $r('app.string.Not_in_play')) 
            .fontSize('20sp') 
            .fontColor('#182431') 
            .margin({ top: '55vp' }) 
            .width('80vp') 
            .height('26vp') 
            .id('PageTitle') 
  
          Image(this.currentImage ? this.currentImage : '') 
            .width('100%') 
            .margin({ top: '15vp' }) 
            .id('CurrentImage') 
  
          Text(this.currentAVMetadata.title ? this.currentAVMetadata.title : 'No title') 
            .width('100%') 
            .height('32vp') 
            .fontSize('24fp') 
            .fontColor('#556B89') 
            .id('Title') 
  
          Text(this.currentAVMetadata.artist ? this.currentAVMetadata.artist : 'No artist') 
            .width('100%') 
            .height('19vp') 
            .margin({ top: '12vp' }) 
            .fontSize('14fp') 
            .fontColor('#556B89') 
            .id('Artist') 
  
          Text(this.currentLyric ? this.currentLyric : '') 
            .width('100%') 
            .height('19vp') 
            .opacity(0.8) 
            .margin({ top: '8vp' }) 
            .fontSize('14fp') 
            .fontColor('#556B89') 
            .id('Lyric') 
  
          Flex({ 
            direction: FlexDirection.Row, 
            alignItems: ItemAlign.Center, 
            alignContent: FlexAlign.Center, 
            justifyContent: FlexAlign.Center 
          }) { 
            Button({ stateEffect: true }) { 
              Image($r('app.media.previous')) 
            } 
            .width('30vp') 
            .height('30vp') 
            .backgroundColor('#00000000') 
            .id('Previous') 
            .onClick(async () => { 
              this.providerFeature.previous(); 
            }) 
  
            Button({ stateEffect: true }) { 
              Image(this.isPlaying ? $r('app.media.pause') : $r('app.media.play')) 
            } 
            .width('64vp') 
            .height('64vp') 
            .margin({ left: '48vp' }) 
            .backgroundColor('#00000000') 
            .id('PlayOrPause') 
            .onClick(async () => { 
              if (!this.isPlaying) { 
                await this.providerFeature.play(); 
              } else { 
                await this.providerFeature.pause(); 
              } 
            }) 
  
            Button({ stateEffect: true }) { 
              Image($r('app.media.next')) 
            } 
            .width('30vp') 
            .height('30vp') 
            .margin({ left: '48vp' }) 
            .backgroundColor('#00000000') 
            .id('Next') 
            .onClick(async () => { 
              this.providerFeature.next(); 
            }) 
          } 
          .height('64vp') 
          .margin({ left: '36vp', right: '36vp' }) 
          .margin({ top: '80vp' }) 
        } 
        .height('100%') 
        .width('100%') 
      } 
      .margin({ left: '34vp', right: '34vp' }) 
    } 
    .width('100%') 
    .height('100%') 
    .backgroundImage($r('app.media.background1')) 
    .backgroundImageSize(ImageSize.Cover) 
  }

准备图像资源

async prepareImageResources(): Promise<void> { 
    let that = this; 
    that.queueItemPixelMapArray.push(await that.saveRawFileToPixelMap('first.png')); 
    that.queueItemPixelMapArray.push(await that.saveRawFileToPixelMap('second.png')); 
    that.queueItemPixelMapArray.push(await that.saveRawFileToPixelMap('third.png')); 
    that.MetadataPixelMapArray.push(await that.saveRawFileToPixelMap('first_with_background.png')); 
    that.MetadataPixelMapArray.push(await that.saveRawFileToPixelMap('second_with_background.png')); 
    that.MetadataPixelMapArray.push(await that.saveRawFileToPixelMap('third_with_background.png')); 
    for (let i = 0;i < that.queueItemPixelMapArray.length; i++) { 
      that.queueItems[i].description.mediaImage = that.queueItemPixelMapArray[i]; 
      that.avMetadataList[i].mediaImage = that.MetadataPixelMapArray[i]; 
    } 
    this.currentPlayItemLink.set(this.queueItems[0]); 
    that.currentImageLink.set(that.MetadataPixelMapArray[0]); 
    this.currentAVMetadataLink.set(this.avMetadataList[0]); 
  }

初始化第一音乐状态

 async InitFirstMusicState(): Promise<void> { 
    let that = this; 
    that.isPlayLink.set(false); 
    that.currentLyricLine = 0; 
    that.currentImageLink.set(that.MetadataPixelMapArray[0]); 
    that.currentState.state = avSession.PlaybackState.PLAYBACK_STATE_PAUSE; 
    await that.session.setAVPlaybackState(that.currentState); 
  
    await that.setAVMetadataToController(0); 
    that.currentPlayItemLink.set(that.queueItems[0]); 
    that.currentAVMetadataLink.set(that.avMetadataList[0]); 
  }

为控制器准备资源

async prepareResourcesForController(): Promise<void> { 
    let that = this; 
    that.constantsForControl.avMetadataList[0].mediaImage = await that.saveRawFileToPixelMap('first.png'); 
    that.constantsForControl.avMetadataList[1].mediaImage = await that.saveRawFileToPixelMap('second.png'); 
    that.constantsForControl.avMetadataList[2].mediaImage = await that.saveRawFileToPixelMap('third.png'); 
  }

其中所需要的资源mediaDate可参考如下;

export default class MediaData { 
  queueItemDescFirst: avSession.AVMediaDescription = { 
    assetId: '001', 
    title: 'First music', 
    subtitle: 'music_sub_name', 
    description: 'music_description', 
    mediaImage: 'http://www.xxx.com', 
    extras: { 
      'extras': 'any' 
    } 
  }; 
  queueItemFirst: avSession.AVQueueItem = { 
    itemId: 0, 
    description: this.queueItemDescFirst 
  }; 
  queueItemDescSecond: avSession.AVMediaDescription = { 
    assetId: '002', 
    title: 'Second music', 
    subtitle: 'music_sub_name', 
    description: 'music_description', 
    mediaImage: 'http://www.xxx.com', 
    extras: { 
      'extras': 'any' 
    } 
  }; 
  queueItemSecond: avSession.AVQueueItem = { 
    itemId: 1, 
    description: this.queueItemDescSecond 
  }; 
  queueItemDescThird: avSession.AVMediaDescription = { 
    assetId: '003', 
    title: 'Third music', 
    subtitle: 'music_sub_name', 
    description: 'music_description', 
    mediaImage: 'http://www.xxx.com', 
    extras: { 
      'extras': 'any' 
    } 
  }; 
  queueItemThird: avSession.AVQueueItem = { 
    itemId: 2, 
    description: this.queueItemDescThird 
  }; 
  lyricsForDemo: Array<string> = [ 
    'This is the first line of the lyrics', 
    'This is the second line of the lyrics', 
    'This is the third line of the lyrics', 
    'This is the fourth line of the lyrics', 
    'This is the fifth line of the lyrics', 
    'This is the sixth line of the lyrics', 
    'This is the seventh line of the lyrics', 
    'This is the eighth line of the lyrics', 
    'This is the ninth line of the lyrics', 
    'This is the tenth line of the lyrics', 
    'This is the eleventh line of the lyrics', 
    'This is the twelfth line of the lyrics', 
    'This is the thirteenth line of the lyrics', 
    'This is the fourteenth line of the lyrics', 
    'This is the fifteenth line of the lyrics', 
    'This is the sixteenth line of the lyrics', 
    'This is the seventeenth line of the lyrics', 
    'This is the eighteenth line of the lyrics', 
    'This is the nineteenth line of the lyrics', 
    'This is the twentieth line of the lyrics', 
    'This is the last line of the lyrics', 
  ] 
  avMetadataFirst: avSession.AVMetadata = { 
    assetId: '0', 
    title: this.queueItemDescFirst.title, 
    artist: 'First artist', 
    lyric: JSON.stringify(this.lyricsForDemo) 
  } 
  avMetadataSecond: avSession.AVMetadata = { 
    assetId: '1', 
    title: this.queueItemDescSecond.title, 
    artist: 'Second artist', 
    lyric: JSON.stringify(this.lyricsForDemo) 
  } 
  avMetadataThird: avSession.AVMetadata = { 
    assetId: '2', 
    title: this.queueItemDescThird.title, 
    artist: 'Third artist', 
    lyric: JSON.stringify(this.lyricsForDemo) 
  } 
  avMetadataList: Array<avSession.AVMetadata> = [this.avMetadataFirst, this.avMetadataSecond, this.avMetadataThird]; 
}

启动连续任务

async startContinuousTask(): Promise<void> { 
    let wantAgentInfo = { 
      wants: [ 
        { 
          bundleName: "com.samples.mediaprovider", 
          abilityName: "com.samples.mediaprovider.EntryAbility" 
        } 
      ], 
      operationType: WantAgent.OperationType.START_ABILITY, 
      requestCode: 0, 
      wantAgentFlags: [WantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] 
    }; 
    let want = await WantAgent.getWantAgent(wantAgentInfo); 
    await backgroundTaskManager.startBackgroundRunning(globalThis.context, backgroundTaskManager.BackgroundMode.AUDIO_PLAYBACK, want); 
  }

注册监听器

 async RegisterListener(): Promise<void> { 
    let that = this; 
    this.session.on('play', async () => { 
      console.info(`on play , do play task`); 
      let that = this; 
      that.isPlayLink.set(true); 
      that.currentState.state = avSession.PlaybackState.PLAYBACK_STATE_PLAY; 
      await that.session.setAVPlaybackState(that.currentState); 
    }); 
    this.session.on('pause', async () => { 
      console.info(`on pause , do pause task`); 
      that.isPlayLink.set(false); 
      that.currentState.state = avSession.PlaybackState.PLAYBACK_STATE_PAUSE; 
      await that.session.setAVPlaybackState(that.currentState); 
    }); 
    this.session.on('stop', async () => { 
      console.info(`on stop , do stop task`); 
      that.isPlayLink.set(false); 
      that.currentState.state = avSession.PlaybackState.PLAYBACK_STATE_PAUSE; 
      await that.session.setAVPlaybackState(that.currentState); 
    }); 
    this.session.on('playNext', async () => { 
      console.info(`on playNext , do playNext task`); 
      let nextId: number = that.currentPlayItemLink.get().itemId + 1; 
      nextId = that.queueItems.length > nextId ? nextId : nextId - that.queueItems.length; 
      await that.handleNewItem(nextId); 
    }); 
    this.session.on('playPrevious', async () => { 
      console.info(`on playPrevious , do playPrevious task`); 
      let previousId: number = that.currentPlayItemLink.get().itemId - 1; 
      previousId = previousId < 0 ? previousId + that.queueItems.length : previousId; 
      await that.handleNewItem(previousId); 
    }); 
    this.session.on('skipToQueueItem', async (itemId) => { 
      console.info(`on skipToQueueItem , do skip task`); 
      await that.handleNewItem(itemId); 
    }); 
    this.session.on('commonCommand', (commandString, args) => { 
      console.info(`on commonCommand , command is ${commandString}, args are ${JSON.stringify(args)}`); 
      that.handleCommonCommand(commandString, args); 
    }); 
  }

实现效果

适配版本信息

· IDE:DevEco Studio 4.0.1.501

· SDK:HarmoneyOS 4.0.0.38

分享
微博
QQ
微信
回复
2024-05-29 20:28:30
相关问题
什么是PolarDB的会话管理?
1224浏览 • 1回复 待解决
如何申请设备上的媒体读写权限
768浏览 • 1回复 待解决
Grid如何实现拖拽功能
870浏览 • 1回复 待解决
鸿蒙如何实现分享功能
16099浏览 • 2回复 待解决
定时提醒功能如何实现?
3407浏览 • 1回复 待解决
grid如何怎么实现拖拽功能
321浏览 • 1回复 待解决
webview如何实现网络请求拦截功能
614浏览 • 1回复 待解决
【JS】如何实现左滑删除功能
1978浏览 • 1回复 待解决
求大佬告知如何实现复制功能
553浏览 • 1回复 待解决
如何实现双路预览+录制功能
447浏览 • 1回复 待解决
如何实现Fraction懒加载功能
6043浏览 • 1回复 待解决
如何实现类似插槽的功能
559浏览 • 1回复 待解决
如何实现文本展开收起功能
159浏览 • 1回复 待解决
HarmonyOS中如何用Java实现配音功能
3263浏览 • 1回复 待解决
如何实现向用户申请授权的功能
531浏览 • 1回复 待解决
如何实现 app 内置全局悬浮球功能
547浏览 • 1回复 待解决
如何实现类似.9 图的功能
442浏览 • 1回复 待解决
JS如何实现手机扫码功能
1654浏览 • 1回复 待解决
camera_lite预览功能如何实现
1005浏览 • 0回复 待解决
在读取媒体文件open: permission denied
1433浏览 • 1回复 待解决