06. 音频
Posted Composition55555
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了06. 音频相关的知识,希望对你有一定的参考价值。
文章目录
写在前面
- 本文写了很多官网的API的相关知识点,可略过直接到官网查看
记第一个小程序DEMO
- 名称:仿网易云音乐小程序
- 接口:网易云音乐NodeJS版 API
- 内容:主要实现轮播图、歌单推荐、排行榜、歌单显示、歌曲播放、歌词显示这几部分功能,其它暂未作考虑
- 本文主要内容:实现歌曲播放、歌词显示
歌曲播放设计到音频,所以我们先来看看如何实现小程序的音频
01. Audio
-
可以使用
Audio
组件进行音频的播放一开始走远了,只在组件中找到这个,然后就开始做,后来才发现已废弃,😢
02. innerAudioContext
对象
详见官网音频
// 创建实例
const innerAudioContext = wx.createInnerAudioContext()
(1)属性
-
src
:设置音频资源地址 -
startTime
:设置开始播放的时间,单位为s
-
autoplay
:设置是否自动播放 -
loop
:设置是否循环播放 -
obeyMuteSwitch
:设置是否遵循系统静音开关 -
volume
:设置音量 -
playbackRate
:设置播放速度
-
duration
:获取当前音频长度 -
currentTime
:获取当前音频播放位置,单位为s
-
paused
:获取当前是否是暂停状态 -
buffered
:获取当前音频缓冲时间点
(2)方法
-
play()
:播放 -
paused()
:暂停 -
stop()
:停止,停止后再播放会从头开始 -
seek(number)
:跳转歌曲播放位置,单位为s
-
destory()
:销毁当前实例 -
onCanplay()
、offCanplay()
:监听音频进入可以播放状态的事件、取消监听 -
onPlay()
、offPlay()
:监听音频播放事件、取消监听 -
onPause()
、offPause()
:监听音频暂停事件、取消监听 -
onStop()
、offStop()
:监听音频停止事件、取消监听 -
onEnded()
、offEnded()
:监听音频自然播放结束事件、取消监听 -
onTimeUpdate()
、offTimeUpdate()
:监听音频播放进度更新事件、取消监听 -
onError()
、offError()
:监听音频播放错误事件 -
onWaiting()
、offWaiting()
:监听音频加载中事件 -
onSeeking()
、offSeeking()
:监听音频进行跳转操作事件 -
onSeeked()
、offSeeked()
:监听音频完成跳转操作事件
03. backgroundAudioManager
对象
详见官网背景音频
// 创建实例
const backgroundAudioManager = wx.getBackgroundAudioManager()
(1)属性
- 大部分同
innerAudioContext
src
:backgroundAudioManager
设置了新的音频资源地址时,会自动开始播放音频
-
title
:设置音频标题,必填项 -
epnaem
:专辑名 -
singer
:歌手名 -
coverImgUrl
:封面图 -
webUrl
:分享功能背景音频播放时,会在状态栏显示一个原生音频播放器
以上内容都是为播放器设置的
protocol
:音频协议
(2)方法
- 只有监听事件,没有取消监听事件,方法同
innerAudioContext
onNext()
:下一曲,限iosonPrev()
:上衣区,限IOS
04. 实现歌曲播放
这里为了方便查看,统一将代码放在一起
变量说明:
musicUrl
:歌曲播放地址
playState
:播放状态标识
playStatus
:控制图片选择.可选值paused | running
/* 以backgroundAudioManager为例 */
// 1.创建实例
const backgroundAudioManager = wx.getBackgroundAudioManager()
// 2. 设置资源地址(背景音频会自动播放)
backgroundAudioManager.src = this.data.musicUrl
// 设置标题和图片——原生播放器,与页面不相关
backgroundAudioManager.title = this.data.musicName
backgroundAudioManager.coverImgUrl = this.data.musicPic
// 3.播放事件
handleMusicPlay()
// 歌曲播放
if (this.data.playState)
backgroundAudioManager.play()
else
backgroundAudioManager.pause()
// 4.监听歌曲播放状态
handleMusicWatch()
// 4.1 监听歌曲播放状态
backgroundAudioManager.onPlay(() =>
this.handlePlay(false)
)
// 4.2 监听歌曲暂停状态
backgroundAudioManager.onPause(() =>
this.handlePlay(true)
)
// 4.3 监听歌曲自然播放结束事件
backgroundAudioManager.onEnded(() =>
this.handlePlay(true)
setTimeout(() =>
backgroundAudioManager.play() // 再次播放
, 2000)
)
,
// 5. 播放状态改变事件
handlePlay(flag)
// 播放图标状态切换
this.setData(
playState: flag,
)
// 图片旋转状态
this.setData(
playStatus: flag ? 'paused' : 'running',
)
,
播放图标?
- 页面添加了一个播放图标,用于显示当前歌曲的播放状态
控制图片旋转?
- CSS的动画属性
animation-play-state: paused | running;
- 用来控制动画的暂停与播放
<!-- 播放图标 --> <view class="play-icon" bindtap="handleMusic"> <text wx:if=" playState " class="iconfont icon-play"></text> <text wx:if=" !playState " class="iconfont icon-paused"></text> </view> <!-- 音乐图片 --> <view class="music-pic" style="animation-play-state: playStatus "> <image src=" musicPic " mode="scaleToFill" lazy-load="false"></image> </view>
- 效果图:
05. 实现歌词滚动
(1)处理歌词数据
请求到的歌词数据格式为:
"[00:00.000] 这是一句歌词\\n[00:01.000] 这是一句歌词\\n..."
所以先要将其通过
\\n
分割为数组形式:["[00:00.000] 这是一句歌词","[00:00.000] 这是一句歌词",...]
然后要将每一个数组项分割为【时间与歌词】两部分:
- 可以通过
]
符号对每一项数组元素进行分割,然后通过subString
方法截取- 结果应该为:
'00:00.000'
、'这是一句歌词'
- 最后处理时间,将其通过
:
分割为分钟数和秒数,算出总时间(s)
- 最后的结果应该得到:时间数组、歌词数组,两者长度一致
/* 代码实现 */
// 1. 分割歌词为数组
let lyric = this.data.musicLyric.lyric.split('\\n')
let lyricTime = [] // 时间数组
let lyricText = [] // 歌词数组
// 2. 遍历:分别取出时间、歌词
lyric.forEach(item =>
// item格式: [00:00.00] 歌词
// 通过 ‘]’ 符号取出:先找到 ‘]’ 所在索引
let index = item.indexOf(']')
// 对数组项进行遍历:当遍历项的歌词 不为空时 才取出
if (item && item.substring(index + 1) != '')
// 取出歌词:substring(index + 1):表示取后面所有字符串
lyricText.push(item.substring(index + 1))
// 处理时间:先去除前后 [] 符号,item.substring(1, index)
// 再根据 : 分割为数组:分钟数、秒数
let time = item.substring(1, index).split(':')
// 然后将 分钟数转换为秒数 最后再相加 保留三位小数 并转换为数字类型
lyricTime.push((time[0] * 60 + time[1] * 1).toFixed(3) - 0)
)
this.setData(
lyricTime,
lyricText,
)
(2)歌词匹配显示
使用
backgroundAudioManager.onTimeUpdate()
实时监听歌曲进度然后根据请求返回的——时间数据,与当前播放进度时间比较,来确定显示哪一行歌词
变量说明:
lyricTime
:歌词时间数组
current
:当前歌词、时间 对应的数组下标,初始值为0
handleMusicWatch()
// 实时监听歌曲进度
backgroundAudioManager.onTimeUpdate(() =>
// 获取当前歌曲进度
let currentTime = backgroundAudioManager.currentTime
// 获取歌词对应的 时间进度
let time = this.data.lyricTime[this.data.current + 1]
// 如果 当前的歌曲进度 大于 歌词的进度
// 则让歌词显示下一行,即让数组序号 current +1
// PS:这里只能尽量让歌词跟着滚动,不是完全匹配,
if (currentTime > time)
this.setData(
current: this.data.current + 1,
)
)
<!-- 歌词显示 -->
<view class="lyric">
<!-- 内容 -->
<view class="content" style="transform:translateY( -current * 60 rpx);">
<!-- 展示所有歌词,然后利用 CSS3 属性——滚动歌词、更改当前播放歌词的颜色 -->
<!-- 注意:style属性内的语句 不能换行!!! -->
<text
wx:for=" lyricText "
wx:key="index"
class=" index == current ? 'current' : '' "
> item </text>
</view>
</view>
/* 当前播放歌词样式 */
.current
color: blue!important;
background: -webkit-linear-gradient(left, transparent, #ffffff1f, transparent);
/* 歌词 */
.lyric
width: 100%;
margin-top: 12rpx;
height: 180rpx;
overflow: hidden;
text-align: center;
.content
position: relative;
margin: auto;
padding-top: 60rpx;
width: 100%;
height: 100%;
font-size: 30rpx;
transition: transform 0.3s linear;
text
display: block;
height: 60rpx;
line-height: 60rpx;
font-weight: bold;
color: #ccc;
// background: -webkit-linear-gradient(left, transparent, #ffffff1f, transparent);
// 控制两个属性的过渡,需要用 , 分隔
transition: color 0.3s linear, background 0.3s linear;
.bg
width: 100%;
height: 60rpx;
position: absolute;
top: 48rpx;
// background-color: #ffffff1f;
background-image: -webkit-linear-gradient(left, transparent, #ffffff1f, transparent);
border-radius: 50rpx;
transition: transform 1s linear;
- 实现效果
(PS:以上内容可能描述不够清晰,请谅解)
(另外,暂时停止了)
以上是关于06. 音频的主要内容,如果未能解决你的问题,请参考以下文章
Java 实现音频添加自定义时长静音(附代码) | Java工具类