鸿蒙开发融云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的可以看简介联系我,也可以私信我,我每天都看私信的