Skip to content

Commit b6bffb3

Browse files
committed
v0.1.2
1、播放模式(默认、随机、单曲循环、列表循环)
1 parent 664d681 commit b6bffb3

File tree

8 files changed

+334
-144
lines changed

8 files changed

+334
-144
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-echo",
3-
"version": "0.1.1",
3+
"version": "0.1.2",
44
"private": true,
55
"scripts": {
66
"dev": "node scripts/start.js",
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import React from 'react'
2+
import ReactDOM from "react-dom"
3+
import { connect } from 'react-redux'
4+
import { setAudioData, setAudioEle, setAudioPlay, setAudioProgress } from '@/store/actions'
5+
6+
// 音乐条
7+
class AudioContainer extends React.Component {
8+
render() {
9+
console.log('AudioContainer render')
10+
return (
11+
<audio id='audio' ref="audio" />
12+
)
13+
}
14+
componentDidMount() {
15+
this.audioInit()
16+
}
17+
shouldComponentUpdate(newProps) {
18+
if (!this.props.audio_data || newProps.audio_data.sound.id !== this.props.audio_data.sound.id) {
19+
return true
20+
}
21+
return false
22+
}
23+
componentWillReceiveProps(newProps) {
24+
if (!this.props.audio_data || newProps.audio_data.sound.id !== this.props.audio_data.sound.id) {
25+
this.audioDOM.src = newProps.audio_data.sound.source
26+
this.audioDOM.play()
27+
}
28+
}
29+
// audio元素初始化
30+
audioInit = () => {
31+
let _audio = ReactDOM.findDOMNode(this.refs.audio)
32+
if (_audio) {
33+
this.audioDOM = _audio
34+
this.props.setAudioEle(_audio)
35+
_audio.oncanplay = () => {
36+
_audio.play()
37+
}
38+
_audio.onplay = () => {
39+
console.log('播放')
40+
this.props.setAudioPlay(true)
41+
}
42+
_audio.onpause = () => {
43+
console.log('暂停')
44+
this.props.setAudioPlay(false)
45+
}
46+
_audio.ontimeupdate = () => {
47+
if (!this.audioDOM.paused) {
48+
const progress = (_audio.currentTime / _audio.duration * 100).toFixed(2) + '%'
49+
this.props.setAudioProgress(progress)
50+
}
51+
}
52+
_audio.onended = () => {
53+
this.props.setAudioPlay(false)
54+
// 加载播放模式逻辑
55+
console.log('加载播放模式逻辑')
56+
this.handlePlayMode()
57+
}
58+
}
59+
}
60+
// 处理播放模式
61+
handlePlayMode = () => {
62+
switch (this.props.playMode) {
63+
case 'random': this.randomPlay()
64+
break
65+
case 'singleRepeat': this.singleRepeat()
66+
break
67+
case 'listRepeat': this.listRepeat()
68+
break
69+
default:
70+
console.log('默认播放模式')
71+
}
72+
}
73+
// 随机播放
74+
randomPlay = () => {
75+
// 0 ~ 播放列表的长度,随机得到一个数
76+
// 如果随机数对应的音乐和当前播放的音乐相同的话,采取listRepeat方法的逻辑,否则播放
77+
let index = ~~(Math.random() * this.props.playList.length)
78+
if (this.props.playList[index].sound.id === this.props.audio_data.sound.id) {
79+
this.listRepeat()
80+
} else {
81+
this.props.setAudioData(this.props.playList[index])
82+
}
83+
}
84+
// 单曲循环
85+
singleRepeat = () => {
86+
this.audioDOM.load()
87+
this.audioDOM.play()
88+
}
89+
// 列表循环
90+
listRepeat = () => {
91+
// 获取当前音乐位置currentIndex
92+
// currentIndex是结尾的话,nextIndex就等于0,否则 +1
93+
// 只有一首音乐,播放模式是列表循环或者用户点击下一首的情况:重新加载并播放当前的音乐
94+
let currentIndex = this.props.playList.findIndex(n => n.sound.id === this.props.audio_data.sound.id)
95+
if (currentIndex > -1) {
96+
let nextIndex
97+
currentIndex === this.props.playList.length - 1 ? nextIndex = 0 : nextIndex = currentIndex + 1
98+
if (this.props.playList[nextIndex].sound.id === this.props.audio_data.sound.id) {
99+
this.singleRepeat()
100+
} else {
101+
this.props.setAudioData(this.props.playList[nextIndex])
102+
}
103+
} else {
104+
console.warn('正常逻辑不会到这里啊')
105+
}
106+
}
107+
}
108+
109+
const mapStateToProps = (state) => {
110+
return {
111+
audio_data: state.audio_data,
112+
playList: state.playList,
113+
playMode: state.playMode
114+
}
115+
}
116+
const mapDispatchToProps = (dispatch, ownProps) => {
117+
return {
118+
setAudioData: (audio) => {
119+
dispatch(setAudioData(audio))
120+
},
121+
setAudioEle: (data) => {
122+
dispatch(setAudioEle(data))
123+
},
124+
setAudioPlay: (status) => {
125+
dispatch(setAudioPlay(status))
126+
},
127+
setAudioProgress: (audio) => {
128+
dispatch(setAudioProgress(audio))
129+
}
130+
}
131+
}
132+
133+
export default connect(mapStateToProps, mapDispatchToProps)(AudioContainer)

src/components/MusicBar/Bar/index.js

Lines changed: 17 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Control from '../Control'
55
import Progress from '../Progress'
66
import PlayList from '../PlayList'
77
import { Modal } from 'antd-mobile'
8+
import { connect } from 'react-redux'
89
import { withRouter } from 'react-router-dom'
910

1011
class barContainer extends React.PureComponent {
@@ -13,16 +14,18 @@ class barContainer extends React.PureComponent {
1314
let { audio_data } = this.props
1415
return (
1516
<React.Fragment>
16-
<div className="bar-container">
17-
<div className="bar-info">
18-
<Cover audio_data={audio_data} />
19-
<Control handlePlay={this.audioPlayOrPause} handlePlayList={this.handlePlayListOpen} />
17+
{audio_data &&
18+
<div className="bar-container">
19+
<div className="bar-info">
20+
<Cover audio_data={audio_data} />
21+
<Control handlePlayList={this.handlePlayListOpen} />
22+
</div>
23+
<Progress />
24+
<Modal popup animationType="slide-up" visible={this.state.playListVisible} onClose={this.handlePlayListOpen}>
25+
<PlayList handlePlayListOpen={this.handlePlayListOpen} playListVisible={this.state.playListVisible} />
26+
</Modal >
2027
</div>
21-
<Progress />
22-
<Modal popup animationType="slide-up" visible={this.state.playListVisible} onClose={this.handlePlayListOpen}>
23-
<PlayList handlePlayListOpen={this.handlePlayListOpen}/>
24-
</Modal >
25-
</div>
28+
}
2629
</React.Fragment>
2730
)
2831
}
@@ -33,13 +36,6 @@ class barContainer extends React.PureComponent {
3336
unlisten: ''
3437
}
3538
}
36-
audioPlayOrPause = () => {
37-
if (this.props.audioDOM.paused) {
38-
this.props.audioDOM.play()
39-
} else {
40-
this.props.audioDOM.pause()
41-
}
42-
}
4339
handlePlayListOpen = () => {
4440
this.setState(prevState => {
4541
let unlisten = ''
@@ -61,51 +57,11 @@ class barContainer extends React.PureComponent {
6157
}
6258
})
6359
}
64-
// 添加播放列表
65-
AddToPlayList = (item) => {
66-
// let ishas = false
67-
// if (this.playList.find((n) => n.sound.id === item.sound.id)) {
68-
// ishas = true
69-
// }
70-
// if (!ishas) {
71-
// this.playList.unshift(item)
72-
// this.set_playList(this.playList)
73-
// }
74-
}
75-
// 随机播放
76-
randomPlay = () => {
77-
// 0 ~ 播放列表的长度,随机得到一个数
78-
// 如果随机数对应的音乐和当前播放的音乐相同的话,采取listRepeat方法的逻辑,否则播放
79-
// let index = ~~(Math.random() * this.playList.length)
80-
// if (this.playList[index].sound.id === this.audio_data.sound.id) {
81-
// this.listRepeat()
82-
// } else {
83-
// this.set_audio_data(this.playList[index])
84-
// }
85-
}
86-
// 单曲循环
87-
singleRepeat = () => {
88-
// this.audio.ele.load()
89-
// this.audio.ele.play()
90-
}
91-
// 列表循环
92-
listRepeat = () => {
93-
// 获取当前音乐位置currentIndex
94-
// currentIndex是结尾的话,nextIndex就等于0,否则 +1
95-
// 只有一首音乐,播放模式是列表循环或者用户点击下一首的情况:重新加载并播放当前的音乐
96-
// let currentIndex = this.playList.findIndex(n => n.sound.id === this.audio_data.sound.id)
97-
// if (currentIndex > -1) {
98-
// let nextIndex
99-
// currentIndex === this.playList.length - 1 ? nextIndex = 0 : nextIndex = currentIndex + 1
100-
// if (this.playList[nextIndex].sound.id === this.audio_data.sound.id) {
101-
// this.singleRepeat()
102-
// } else {
103-
// this.set_audio_data(this.playList[nextIndex])
104-
// }
105-
// } else {
106-
// console.warn('正常逻辑不会到这里啊')
107-
// }
60+
}
61+
const mapStateToProps = (state) => {
62+
return {
63+
audio_data: state.audio_data
10864
}
10965
}
11066

111-
export default withRouter(barContainer)
67+
export default withRouter(connect(mapStateToProps, {})(barContainer))

src/components/MusicBar/Control/index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,24 @@ class Control extends React.Component {
1212
{/* 播放列表 */}
1313
<div className="control-icon my-icon-menu" onClick={this.props.handlePlayList}></div>
1414
{/* 播放/暂停 */}
15-
<div className={`control-icon control-icon-mid ${audio_play ? "my-icon-pause" : "my-icon-arrow"}`} onClick={this.props.handlePlay} ></div>
15+
<div className={`control-icon control-icon-mid ${audio_play ? "my-icon-pause" : "my-icon-arrow"}`} onClick={this.handlePlayOrPause} ></div>
1616
{/* 下一首 */}
1717
<div className="control-icon my-icon-next" onClick={this.listRepeat} ></div>
1818
</div>
1919
)
2020
}
21+
handlePlayOrPause = () => {
22+
if (this.props.audio_ele.paused) {
23+
this.props.audio_ele.play()
24+
} else {
25+
this.props.audio_ele.pause()
26+
}
27+
}
2128
}
2229

2330
const mapStateToProps = (state) => {
2431
return {
32+
audio_ele: state.audio_ele,
2533
audio_play: state.audio_play
2634
}
2735
}

0 commit comments

Comments
 (0)