使用AVPlayer开发音乐播放器
·
目录
任务1:准备播放的音乐素材
步骤1:准备mp3歌曲资源
将准备好的歌曲资源放入 rawfile 目录下,示意图如下
步骤2:定义歌曲信息模型
定义每首歌的信息如下所示。
export default interface Song {
id: number; // 索引
title: string; // 标题
author: string // 作者
path: string; // 文件路径
}
步骤3:准备歌曲数据
//歌曲数据
const SONGS: Song[] = [
{
id: 1,
title: "如风",
author: "王菲",
path: "如风.mp3"
},
{
id: 2,
title: "容易受伤的女人",
author: "王菲",
path: "容易受伤的女人.mp3"
},
{
id: 3,
title: "执迷不悔",
author: "王菲",
path: "执迷不悔.mp3"
}
]
任务2:构建播放器UI界面
示意图如下
播放器UI界面分为3个部分:
- 标题
- 歌曲列表。单击歌曲,开始播放歌曲。
- 控制器。显示歌曲名称、可以播放/暂停。没有播放歌曲的时候显示“点击歌曲开发播放”
页面框架结构如下:
build() {
Column() {
this.Header() //标题
this.SongList() //歌曲列表
this.SongShow() //歌曲控制器
}.height('100%')
.width('100%')
}
步骤1:标题
@Builder Header(){
Row() {
Row() {
Text('音乐播放器')
.fontColor(Color.White).fontSize(32)
}.margin({ left: 20 })
}.backgroundColor(Color.Green).height('8%').width('100%')
}
步骤2:歌曲列表
@Builder SongList(){
Column() {
List() {
ForEach(SONGS, (song: Song) => {
ListItem() {
Row() {
Button({ type: ButtonType.Normal }) {
Row() {
Text(song.id + '')
.fontSize(32)
Column() {
Text(song.title).fontSize(20).fontWeight(700)
Text(song.author).fontSize(14)
}.alignItems(HorizontalAlign.Start)
.margin({ left: 20 })
}.justifyContent(FlexAlign.Start)
.width('90%')
}
.backgroundColor(Color.White)
.width("100%")
.height(50)
.margin({ top: 10 })
.onClick(() => {
this.playerState = '暂停';
this.isPlaying = true;
this.onPageShow();
this.changeSong(song);
this.selectedSong = song;
})
}
}
})
}.width('100%')
}.height('84%')
}
步骤3:歌曲控制器
@Builder SongShow(){
Row() {
Row() {
if (this.selectedSong.id == -1) {
Text('点击歌曲开始播放')
.fontSize(20).fontColor(Color.White)
} else {
//左侧 70% ,显示歌曲名称
Column() {
Text(this.selectedSong.title)
.fontSize(20).fontColor(Color.White)
}.width('70%').alignItems(HorizontalAlign.Start)
//右侧20%,显示播放、暂停控制
Column() {
Button({ type: ButtonType.Normal, stateEffect: true }) {
Text(this.playerState)
.fontSize(20).fontColor(Color.White)
}
.borderRadius(8)
.height(26)
.width(70)
.backgroundColor(Color.Orange)
.onClick(() => {
this.playPause()
})
}.width('20%')
}
}.width('99%').margin({ left: 15 })
}.backgroundColor(Color.Green).height('8%').width('100%')
}
任务3:实现音乐播放器
步骤1:定义变量
//播放器
private avPlayer: media.AVPlayer | null = null;
//是否正在播放
private isPlaying: boolean = false;
//播放/暂停 按钮的文字
@State playerState: string = '暂停'
//当前正在播放的歌曲
@State selectedSong: Song = {
id: -1,
title: '',
author: '',
path: ''
};
步骤2:点击歌曲列表开始播放歌曲
找到列表Item,设置点击事件
.onClick(() => {
this.playerState = '暂停';
this.isPlaying = true;
this.onPageShow();
this.changeSong(song);
this.selectedSong = song;
})
调用内部函数:onPageShow()开始初始化播放器,并设置监听
async onPageShow() {
// 创建avPlayer实例对象
this.avPlayer = await media.createAVPlayer();
// 创建状态机变化回调函数
this.setAVPlayerCallback();
console.info('播放器准备完成')
}
setAVPlayerCallback() {
if (this.avPlayer !== null) {
this.avPlayer.on('error', (err) => {
console.error(TAG, `播放器发生错误,错误码:${err.code}, 错误信息:${err.message}`);
this.avPlayer?.reset();
});
this.avPlayer.on('stateChange', async (state, reason) => {
console.info(TAG, "reason=" + JSON.stringify(reason))
switch (state) {
case 'initialized':
console.info(TAG, '资源初始化完成');
this.avPlayer?.prepare();
break;
case 'prepared':
console.info(TAG, '资源准备完成');
this.avPlayer?.play();
break;
case 'completed':
console.info(TAG, '播放完成');
this.avPlayer?.stop();
break;
}
});
}
}
然后调用changeSong()开始播放歌曲
// 以下为使用资源管理接口获取打包在HAP内的媒体资源文件并通过fdSrc属性进行播放
async changeSong(song: Song) {
if (this.avPlayer !== null) {
this.avPlayer?.reset()
// 创建状态机变化回调函数
this.setAVPlayerCallback();
// 通过UIAbilityContext的resourceManager成员的getRawFd接口获取媒体资源播放地址
// 返回类型为{fd,offset,length},fd为HAP包fd地址,offset为媒体资源偏移量,length为播放长度
let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
let fileDescriptor = await context.resourceManager.getRawFd(song.path);
// 为fdSrc赋值触发initialized状态机上报
this.avPlayer.fdSrc = fileDescriptor;
}
}
步骤3:播放、暂停控制
示意图如下,在底部控制器栏有一个按钮,可以控制播放、暂停。
实现代码如下
//播放/暂停
playPause(){
if (this.avPlayer !== null && this.isPlaying == true) {
/**
* 如果正在播放,点击按钮
* - 暂停播放
* - 播放状态为false
* - 按钮文字改为继续
*/
this.avPlayer.pause()
this.playerState = '继续'
this.isPlaying = false
} else {
/**
* 如果不在播放,也就是暂停、或者未开始,点击按钮
* -开始播放
* -按钮位置改为暂停
* -播放状态改为true
*/
this.avPlayer?.play()
this.playerState = '暂停'
this.isPlaying = true
}
}
效果
启动app的效果
播放歌曲的效果
更多推荐

所有评论(0)