鸿蒙开发融云demo播放语音消息

101 阅读2分钟
鸿蒙开发融云demo播放语音消息

融云鸿蒙版是不带UI的,得自己一步步搭建。 这次讲如何播放语音消息。播放的示例代码,融云平台上有提供参考的。 难处理的是播放时,播放的动画,以及录音消息根据时间长度显示的长度不一。

一、思路:

播放:AudioPlayer.playByPlayer 播放的动画:用帧动画 长度不一的消息:自己算

二、效果图:

在这里插入图片描述这是图,可能看不到动效,你看17s的只有两个小括号,证明它是正在动的。

三、关键代码:

播放代码:

  public static startPlayHQVoiceMessage(
    messageId:number,
    backAvPlayerCallback?:(avPlayer:media.AVPlayer) => void,
    stateAvPlayerCallback?:(avPlayerState:string) => void
    ){
    IMEngine.getInstance().downloadMediaMessage(messageId).then(result => {
      if (EngineError.Success === result.code) {
        logContent("downloadMediaMessage",result.data as string)
        // 本地路径
        AudioPlayer.playByPlayer(result.data as string,backAvPlayerCallback,stateAvPlayerCallback)
      }
    });
  }
/**
   * 使用 AVPlayer 播放高清语音消息
   * @param localPath 高清语音消息下载后的本地沙箱路径
   */
  public static async playByPlayer(localPath: string,
    backAvPlayerCallback?:(avPlayer:media.AVPlayer) => void,
    stateAvPlayerCallback?:(avPlayerState:string) => void
  ) {
    let avPlayer = await media.createAVPlayer();
    let fdPath = "fd://"
    let file = await fs.open(localPath);
    fdPath = fdPath + file.fd;
    avPlayer.url = fdPath;
    backAvPlayerCallback?.(avPlayer)
    avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
      stateAvPlayerCallback?.(state)
      switch (state) {
        case 'idle': // 成功调用reset接口后触发该状态机上报
          console.info('AVPlayer state idle called.');
          //avPlayer?.release(); // 调用release接口销毁实例对象
          break;
        case 'initialized': // avplayer 设置播放源后触发该状态上报
          console.info('AVPlayer state initialized called.');
          avPlayer?.prepare();
          break;
        case 'prepared': // prepare调用成功后上报该状态机
          console.info('AVPlayer state prepared called.');
          avPlayer?.play(); // 调用播放接口开始播放
          break;
        case 'playing': // play成功调用后触发该状态机上报
          console.info('AVPlayer state playing called.');
          break;
        case 'paused': // pause成功调用后触发该状态机上报
          console.info('AVPlayer state paused called.');
          avPlayer?.play(); // 再次播放接口开始播放
          break;
        case 'completed': // 播放结束后触发该状态机上报
          console.info('AVPlayer state completed called.');
          avPlayer?.stop(); //调用播放结束接口
          break;
        case 'stopped': // stop接口成功调用后触发该状态机上报
          console.info('AVPlayer state stopped called.');
          avPlayer?.reset(); // 调用reset接口初始化avplayer状态
          break;
        case 'released':
          console.info('AVPlayer state released called.');
          break;
        default:
          console.info('AVPlayer state unknown called.');
          break;
      }
    })
  }

播放动画代码:

if (this.msg.objectName === HQVoiceMessageObjectName){
                Row({space:2}){
                  Text(`${(this.msg.content as HQVoiceMessage).duration}"`)
                    .width(this.dealVoiceWidth((this.msg.content as HQVoiceMessage).duration))
                    .constraintSize({ maxWidth: '60%' })
                    .textAlign(TextAlign.End)
                    .lineHeight($r('app.integer.search_text_height'))
                    .fontSize($r('app.integer.search_font_size'))
                    .fontColor($r('app.color.color_182431'))

                  // 用帧动画
                  ImageAnimator()
                    .images([
                      {
                        src: $r('app.media.rc_voice_send_play3'),
                        duration: 300,
                        width: 20,
                        height: 20,
                        top: 0,
                        left: 0
                      },
                      {
                        src: $r('app.media.rc_voice_send_play2'),
                        duration: 300,
                        width: 20,
                        height: 20,
                        top: 0,
                        left: 0
                      },
                      {
                        src: $r('app.media.rc_voice_send_play1'),
                        duration: 300,
                        width: 20,
                        height: 20,
                        top: 0,
                        left: 0
                      }
                    ])
                    .state(this.voicePlayMessageId === this.msg.messageId?this.voicePlayState:AnimationStatus.Initial)
                    .fixedSize(false)
                    .fillMode(FillMode.None)
                    .iterations(-1)
                }
                  .constraintSize({ minHeight: $r('app.integer.opt_layout_chat_view_profile_picture_height') })
                  .backgroundColor($r('app.color.color_D0E9F3'))
                  .padding({
                    top: $r('app.integer.layout_8'),
                    left: $r('app.integer.text_font_13'),
                    bottom: $r('app.integer.layout_8'),
                    right: $r('app.integer.text_font_13')
                  })
                  .borderRadius({
                    topLeft: $r('app.integer.opt_layout_chat_view_item_padding_right'),
                    topRight: $r('app.integer.layout_4'),
                    bottomLeft: $r('app.integer.opt_layout_chat_view_item_padding_right'),
                    bottomRight: $r('app.integer.opt_layout_chat_view_item_padding_right')
                  })
                  .onClick(async ()=>{
                    // 返回给界面上处理,退出界面就关闭声音
                    this.playVoiceCallback?.(this.msg.messageId)
                  })
              }
四、鸿蒙融云Demo源码结构图:

在这里插入图片描述在这里插入图片描述

有问题或者需要完整源码demo的可以看简介联系我,也可以私信我,我每天都看私信的