需求: 先目前需要实现一个音频播放器
左右布局 按钮控制播放 暂停 进度条展示播放进度,放在页面最下方
实现步骤:
1.先实现基础样式结构 wxml + wxss
2.实现 找到API wx.createInnerAudioContext 创建实例实现需求
3.实现进度条和播放器时间进度联动 监听时间变化 并且给进度条value赋值
4.封装成组件,方便其他页面使用,title + voiceUrl 由父组件传递
1.在 wxml中 实现样式
<!--components/player/player.wxml-->
<!--底部播放器 -->
<view class="player">
<!-- 左边的播放器封面和控制按钮 -->
<view class="player-left" bind:tap="changePage">
<image class="player-cover" src="{{play.coverImgUrl}}" />
<view class="player-controls">
<image wx:if="{{state=='paused'}}" src="/image/player-p.png" />
<image wx:else src="/image/player-d.png" />
</view>
</view>
<!-- 中间的播放器信息和进度条 -->
<view class="player-center ">
<!-- 显示播放进度和时间 -->
<view class="content-play-progress">
<text>{{currentTime}}</text>
<view>
<slider bindchange="sliderChange" activeColor="#d33a31" block-size="12" backgroundColor="#dadada" value="{{percent}}" />
</view>
<text>{{duration}}</text>
</view>
<view class="player-info-title">{{playerTitle}}</view>
</view>
</view>
问题??
A : 为什么不直接使用 # audio 组件
Q : 官方说 从基础库 1.6.0 开始,本接口停止维护,请使用 wx.createInnerAudioContext 代替,也就是意味着这里需要自己手写,然后在js中自己调 wx.createInnerAudioContext() 这个API 接口
2.在wxss 中完善样式
因为是放在页面最下方,所以直接 fixed 定位 了
.player {
position: fixed;
bottom: 0;
left: 0;
background-color: #ffffff; /* 设置背景色 */
border-top: 1px solid rgb(218, 218, 218); /* 添加顶部边框 */
display: flex;
align-items: center;
color: #7a7a7a;
padding: 20rpx;
}
.player-left {
display: flex;
flex-direction: column;
align-items: center;
position: relative;
height: 100rpx;
margin-right: 20rpx;
}
.player-cover {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
.player-controls {
position: absolute; /* 添加绝对定位 */
top: 50%; /* 居中 */
left: 50%; /* 居中 */
transform: translate(-50%, -50%); /* 居中 */
}
.player-controls image{
width: 40rpx;
height: 40rpx;
}
.player-center {
display: flex;
flex-direction: column;
}
.content-play-progress{
display: flex;
align-items: center;
}
.content-play-progress view{
width: 400rpx;
}
.player-info-title{
margin-bottom: 20rpx;
margin-left: 20rpx;
}
.player-right {
position: relative; /* 设置相对定位,以便在其内部进行绝对定位 */
display: flex;
}
.button {
position: relative; /* 设置相对定位,以便在其内部进行绝对定位 */
display: inline-block;
cursor: pointer;
}
.content {
display: inline-block;
padding: 10rpx 25rpx;
border-radius: 15rpx;
border: 2rpx solid #7a7a7a;
color: #7a7a7a;
font-size: 28rpx;
}
.badge {
position: absolute; /* 设置绝对定位 */
top: -30rpx; /* 距离按钮顶部的距离 */
right: -10rpx; /* 距离按钮右侧的距离 */
background-color:#ffffff;
color: #7a7a7a;
padding: 4rpx 8rpx;
border-radius: 50%;
font-size: 24rpx;
}
3.在 js 中完善功能
// components/player/player.js
Component({
/**
* 组件的属性列表
*/
properties: {
playerTitle: String,
voiceUrl: String
},
/**
* 组件的初始数据
*/
data: {
play: {
coverImgUrl: "/image/1.jpg",
title: "三环钮铜盖鼎、四环钮",
},
state: 'paused', // 默认播放状态为暂停
multiple: 1,
currentTime: '00:00', // 当前播放时间
duration: '00:00', // 音频总时长
percent: 0,
},
/**
* 组件的方法列表
*/
methods: {
changePage() {
// 切换播放状态
const newState = this.data.state === 'paused' ? 'playing' : 'paused';
if (newState === 'playing') {
this.innerAudioContext.play(); // 播放音频
} else {
this.innerAudioContext.pause(); // 暂停音频
}
this.setData({
state: newState
});
// innerAudioContext.stop() // 停止
// innerAudioContext.destroy() // 释放音频资源
},
sliderChange(e) {
const value = e.detail.value;
// 计算音频播放的目标时间
const duration = this.innerAudioContext.duration;
const targetTime = duration * value / 100;
// 设置音频播放进度
this.innerAudioContext.seek(targetTime);
// 更新当前播放时间
this.setData({
currentTime: this.formatTime(targetTime)
});
},
// 格式化时间
formatTime(time) {
var minute = Math.floor(time / 60) % 60;
var second = Math.floor(time) % 60
return (minute < 10 ? '0' + minute : minute) + ':' + (second < 10 ? '0' + second : second)
},
},
ready() {
// 初始化音频实例
this.innerAudioContext = wx.createInnerAudioContext({
useWebAudioImplement: false
});
this.innerAudioContext.src = this.properties.voiceUrl;
// 监听音频时间更新事件
this.innerAudioContext.onTimeUpdate(() => {
// 更新当前播放时间和进度百分比
this.setData({
currentTime: this.formatTime(this.innerAudioContext.currentTime),
duration: this.formatTime(this.innerAudioContext.duration),
percent: this.innerAudioContext.currentTime / this.innerAudioContext.duration * 100
});
});
},
detached() {
// 在组件销毁时释放音频资源
this.innerAudioContext.destroy();
}
})
注意点
在页面初始化就实例化一个音频实例,并且因为有播放时间和进度 ,所以需要监听 onTimeUpdate 它们的变化
当滑动进度条的时候,对应的播放时间要变化,这里需要setData 一下,否则初始时间不变化
更新当前播放时间
this.setData({
currentTime: this.formatTime(targetTime)
});
ready() {
// 初始化音频实例
this.innerAudioContext = wx.createInnerAudioContext({
useWebAudioImplement: false
});
this.innerAudioContext.src = this.properties.voiceUrl;
// 监听音频时间更新事件
this.innerAudioContext.onTimeUpdate(() => {
// 更新当前播放时间和进度百分比
this.setData({
currentTime: this.formatTime(this.innerAudioContext.currentTime),
duration: this.formatTime(this.innerAudioContext.duration),
percent: this.innerAudioContext.currentTime / this.innerAudioContext.duration * 100
});
});
},
detached() {
// 在组件销毁时释放音频资源
this.innerAudioContext.destroy();
}
4.在json 中开启组件为true
{
"component": true,
"usingComponents": {}
}