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

媒体会话交互功能

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

此内容主要展示了媒体会话的相关功能,使用@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
相关问题
HarmonyOS 如何实现交互实现-吸顶
475浏览 • 1回复 待解决
什么是PolarDB的会话管理?
2534浏览 • 1回复 待解决
ArkTS中Web交互、网络请求如何实现
415浏览 • 1回复 待解决
会话的结束时间怎样记录?
3227浏览 • 1回复 待解决
定时提醒功能如何实现?
5021浏览 • 1回复 待解决
Grid如何实现拖拽功能
2659浏览 • 1回复 待解决
HarmonyOS 分享功能如何实现
219浏览 • 1回复 待解决
鸿蒙如何实现分享功能
17742浏览 • 2回复 待解决