微信小程序?qū)崿F(xiàn)音樂播放器實例完整流程
目的
- 掌握swiper組件、scroll-view組件的使用
- 掌握image組件的使用
- 掌握音頻API的使用
- 掌握slider組件的使用
內(nèi)容
音樂小程序項目的完整開發(fā)流程,其開發(fā)步驟包括頁面結(jié)構(gòu)的分析、樣式的設(shè)計、組件的運用等。通過本章的學(xué)習(xí),讀者能夠掌握小程序的基本交互邏輯的開發(fā),能夠運用API來實現(xiàn)項目中的特定功能,學(xué)會解決開發(fā)過程中常見的問題。
代碼架構(gòu)
index.wxml
<!-- 標簽頁標題 --> <view class="tab"> <view class="tab-item {{tab==0?'active':''}}" bindtap="changeItem" data-item="0">音樂推薦</view> <view class="tab-item {{tab==1?'active':''}}" bindtap="changeItem" data-item="1">播放器</view> <view class="tab-item {{tab==2?'active':''}}" bindtap="changeItem" data-item="2">播放列表</view> </view> <!-- 內(nèi)容區(qū)域 --> <view class="content"> <swiper current="{{item}}" bindchange="changeTab"> <swiper-item> <!-- 內(nèi)容滾動區(qū)域 --> <scroll-view class="content-info" scroll-y> <!-- 輪播圖 --> <swiper class="content-info-slide" indicator-color="rgba(255,255,255,.5)" indicator-active-color="#fff" indicator-dots circular autoplay> <swiper-item> <image src="/images/xingong.jpg" /> </swiper-item> <swiper-item> <image src="/images/banner.jpg" /> </swiper-item> <swiper-item> <image src="/images/banner.jpg" /> </swiper-item> </swiper> <!-- 功能按鈕 --> <view class="content-info-portal"> <view> <image src="/images/04.png" /> <text>私人FM</text> </view> <view> <image src="/images/05.png" /> <text>每日歌曲推薦</text> </view> <view> <image src="/images/06.png" /> <text>云音樂新歌榜</text> </view> </view> <!-- 熱門音樂 --> <view class="content-info-list"> <view class="list-title">推薦歌曲</view> <view class="list-inner"> <view class="list-item"> <image src="/images/圖片27.jpg" /> <view>紫羅蘭</view> </view> <view class="list-item"> <image src="/images/圖片28.jpg" /> <view>五月之歌</view> </view> <view class="list-item"> <image src="/images/圖片29.jpg" /> <view>菩提樹</view> </view> <view class="list-item"> <image src="/images/圖片31.jpg" /> <view>歡樂頌</view> </view> <view class="list-item"> <image src="/images/圖片33.jpg" /> <view>安魂曲</view> </view> <view class="list-item"> <image src="/images/圖片36.jpg" /> <view>搖籃曲</view> </view> </view> </view> </scroll-view> </swiper-item> <swiper-item> <!-- 播放器頁面 --> <include src="play.wxml" /> </swiper-item> <swiper-item> <include src="playlist.wxml" /> </swiper-item> </swiper> </view> <!-- 底部播放器 --> <view class="player"> <image class="player-cover" src="{{play.coverImgUrl}}" /> <view class="player-info"> <view class="player-info-title">{{play.title}}</view> <view class="player-info-singer">{{play.singer}}</view> </view> <view class="player-controls"> <!-- 切換到播放列表 --> <image src="/images/01.png" bindtap="changeItem" data-item="2" /> <!-- 播放或暫停 --> <image wx:if="{{state=='paused'}}" src="/images/02.png" bindtap="play" /> <image wx:else src="/images/02stop.png" bindtap="pause" /> <!-- 下一曲 --> <image src="/images/03.png" bindtap="next" /> </view> </view>
info.wxml
<!-- 內(nèi)容滾動區(qū)域 --> <scroll-view class="content-info" scroll-y> <!-- 輪播圖 --> <swiper class="content-info-slide" indicator-color="rgba(255,255,255,.5)" indicator-active-color="#fff" indicator-dots circular autoplay> <swiper-item> <image src="/images/xingong.jpg" /> </swiper-item> <swiper-item> <image src="/images/xingong.jpg" /> </swiper-item> <swiper-item> <image src="/images/banner.jpg" /> </swiper-item> </swiper> <!-- 功能按鈕 --> <view class="content-info-portal"> <view> <image src="/images/04.png" /> <text>私人FM</text> </view> <view> <image src="/images/05.png" /> <text>每日歌曲推薦</text> </view> <view> <image src="/images/06.png" /> <text>云音樂新歌榜</text> </view> </view> <!-- 熱門音樂 --> <view class="content-info-list"> <view class="list-title">推薦歌曲</view> <view class="list-inner"> <view class="list-item"> <image src="/images/cover.jpg" /> <view>紫羅蘭</view> </view> <view class="list-item"> <image src="/images/cover.jpg" /> <view>五月之歌</view> </view> <view class="list-item"> <image src="/images/cover.jpg" /> <view>菩提樹</view> </view> <view class="list-item"> <image src="/images/cover.jpg" /> <view>歡樂頌</view> </view> <view class="list-item"> <image src="/images/cover.jpg" /> <view>安魂曲</view> </view> <view class="list-item"> <image src="/images/cover.jpg" /> <view>搖籃曲</view> </view> </view> </view> </scroll-view>
play.wxml
<!-- 播放器 --> <view class="content-play"> <!-- 顯示音樂信息 --> <view class="content-play-info"> <text>{{play.title}}</text> <view>—— {{play.singer}} ——</view> </view> <!-- 顯示專輯封面 --> <view class="content-play-cover"> <image src="{{play.coverImgUrl}}" style="animation-play-state:{{state}}" /> </view> <!-- 顯示播放進度和時間 --> <view class="content-play-progress"> <text>{{play.currentTime}}</text> <view> <slider bindchange="sliderChange" activeColor="#d33a31" block-size="12" backgroundColor="#dadada" value="{{play.percent}}" /> </view> <text>{{play.duration}}</text> </view> </view>
playlist.wxml
<scroll-view class="content-playlist" scroll-y> <view class="playlist-item" wx:for="{{playlist}}" wx:key="id" bindtap="change" data-index="{{index}}"> <image class="playlist-cover" src="{{item.coverImgUrl}}" /> <view class="playlist-info"> <view class="playlist-info-title">{{item.title}}</view> <view class="playlist-info-singer">{{item.singer}}</view> </view> <view class="playlist-controls"> <text wx:if="{{index==playIndex}}">正在播放</text> </view> </view> </scroll-view>
index.js
// pages/index/index.js Page({ /** * 頁面的初始數(shù)據(jù) */ data: { item: 0, tab: 0, // 播放列表數(shù)據(jù) playlist: [{ id: 1, title: '鋼琴協(xié)奏曲', singer: '肖邦', src: 'http://localhost:3000/1.mp3', coverImgUrl: '/images/cover.jpg' }, { id: 2, title: '奏鳴曲', singer: '莫扎特', src: 'http://localhost:3000/2.mp3', coverImgUrl: '/images/cover.jpg' }, { id: 3, title: '歡樂頌', singer: '貝多芬', src: 'http://localhost:3000/1.mp3', coverImgUrl: '/images/cover.jpg' }, { id: 4, title: '愛之夢', singer: '李斯特', src: 'http://localhost:3000/2.mp3', coverImgUrl: '/images/cover.jpg' }], state: 'paused', playIndex: 0, play: { currentTime: '00:00', duration: '00:00', percent: 0, title: '', singer: '', coverImgUrl: '/images/圖片47.jpg', } }, // 頁面切換 changeItem: function(e) { this.setData({ item: e.target.dataset.item, }) }, // tab切換 changeTab: function(e) { this.setData({ tab: e.detail.current }) }, // 實現(xiàn)播放器播放功能 audioCtx: null, onReady: function() { this.audioCtx = wx.createInnerAudioContext() // 默認選擇第1曲 this.setMusic(0) var that = this // 播放進度檢測 this.audioCtx.onError(function() { console.log('播放失?。? + that.audioCtx.src) }) // 播放完成自動換下一曲 this.audioCtx.onEnded(function() { that.next() }) // 自動更新播放進度 this.audioCtx.onPlay(function() {}) // onWaiting觸發(fā)的暫停 var waitFlag = false // 音頻由于網(wǎng)絡(luò)等原因等待中的回調(diào) this.audioCtx.onWaiting(function() { waitFlag = true }) // 音頻準備就緒的回調(diào) this.audioCtx.onCanplay(function() { if (waitFlag) { that.audioCtx.pause() that.audioCtx.play() waitFlag = false } }) this.audioCtx.onTimeUpdate(function() { that.setData({ 'play.duration': formatTime(that.audioCtx.duration), 'play.currentTime': formatTime(that.audioCtx.currentTime), 'play.percent': that.audioCtx.currentTime / that.audioCtx.duration * 100 }) }) // 格式化時間 function 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) } }, // 音樂播放 setMusic: function(index) { var music = this.data.playlist[index] this.audioCtx.src = music.src this.setData({ playIndex: index, 'play.title': music.title, 'play.singer': music.singer, 'play.coverImgUrl': music.coverImgUrl, 'play.currentTime': '00:00', 'play.duration': '00:00', 'play.percent': 0 }) }, // 播放按鈕 play: function() { this.audioCtx.play() this.setData({ state: 'running' }) }, // 暫停按鈕 pause: function() { this.audioCtx.pause() this.setData({ state: 'paused' }) }, // 下一曲按鈕 next: function() { var index = this.data.playIndex >= this.data.playlist.length - 1 ? 0 : this.data.playIndex + 1 this.setMusic(index) if (this.data.state === 'running') { this.play() } }, // 滾動條調(diào)節(jié)歌曲進度 sliderChange: function(e) { var second = e.detail.value * this.audioCtx.duration / 100 this.audioCtx.seek(second) }, // 播放列表換曲功能 change: function(e) { this.setMusic(e.currentTarget.dataset.index) this.play() } })
index.json
{ "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "音樂", "navigationBarTextStyle": "black" }
index.wxss
page { display: flex; flex-direction: column; background: #17181a; color: #ccc; height: 100%; } .tab { display: flex; } .tab-item { flex: 1; font-size: 10pt; text-align: center; line-height: 72rpx; border-bottom: 6rpx solid #eee; } .content { flex: 1; } .content > swiper { height: 100%; } .player { background: #222; border-top: 1px solid #252525; height: 112rpx; } .tab-item.active { color: #c25b5b; border-bottom-color: #c25b5b; } .content-info { height: 100%; } ::-webkit-scrollbar { width: 0; height: 0; color: transparent; } /* 輪播圖 */ .content-info-slide { height: 302rpx; margin-bottom: 20px; } .content-info-slide image { width: 100%; height: 100%; } /* 功能按鈕 */ .content-info-portal { display: flex; margin-bottom: 15px; } .content-info-portal > view { flex: 1; font-size: 11pt; text-align: center; } .content-info-portal image { width: 120rpx; height: 120rpx; display: block; margin: 20rpx auto; } /* 熱門音樂 */ .content-info-list { font-size: 11pt; margin-bottom: 20rpx; } .content-info-list > .list-title { margin: 20rpx 35rpx; } .content-info-list > .list-inner { display: flex; flex-wrap: wrap; margin: 0 20rpx; } .content-info-list > .list-inner > .list-item { flex: 1; } .content-info-list > .list-inner > .list-item > image { display: block; width: 200rpx; height: 200rpx; margin: 0 auto; border-radius: 10rpx; border: 1rpx solid #555; } .content-info-list > .list-inner > .list-item > view { width: 200rpx; margin: 10rpx auto; font-size: 10pt; } /* 播放器 */ .content-play { display: flex; justify-content: space-around; flex-direction: column; height: 100%; text-align: center; } .content-play-info > view { color: #888; font-size: 11pt; } /* 底部播放器 */ .player { display: flex; align-items: center; background: #222; border-top: 1px solid #252525; height: 112rpx; } .player-cover { width: 80rpx; height: 80rpx; margin-left: 15rpx; border-radius: 8rpx; border: 1px solid #333; } .player-info { flex: 1; font-size: 10pt; line-height: 38rpx; margin-left: 20rpx; padding-bottom: 8rpx; } .player-info-singer { color: #888; } .player-controls image { width: 80rpx; height: 80rpx; margin-right: 15rpx; } /* 顯示專輯頁面樣式 */ .content-play-cover image { animation: rotateImage 10s linear infinite; width: 400rpx; height: 400rpx; border-radius: 50%; border: 1px solid #333; } @keyframes rotateImage { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } /* 播放進度和時間 */ .content-play-progress { display: flex; align-items: center; margin: 0 35rpx; font-size: 9pt; text-align: center; } .content-play-progress > view { flex: 1; } /* 播放列表 */ .playlist-item { display: flex; align-items: center; border-bottom: 1rpx solid #333; height: 112rpx; } .playlist-cover { width: 80rpx; height: 80rpx; margin-left: 15rpx; border-radius: 8rpx; border: 1px solid #333; } .playlist-info { flex: 1; font-size: 10pt; line-height: 38rpx; margin-left: 20rpx; padding-bottom: 8rpx; } .playlist-info-singer { color: #888; } .playlist-controls { font-size: 10pt; margin-right: 20rpx; color: #c25b5b; }
app.json
{ "pages": [ "pages/index/index", "pages/test/index", "pages/test/swiper", "pages/test/test" ], "sitemapLocation": "sitemap.json" }
配置文件
project.config.json
{ "description": "項目配置文件", "packOptions": { "ignore": [], "include": [] }, "setting": { "urlCheck": true, "es6": true, "enhance": true, "postcss": true, "preloadBackgroundData": false, "minified": true, "newFeature": true, "coverView": true, "nodeModules": false, "autoAudits": false, "showShadowRootInWxmlPanel": true, "scopeDataCheck": false, "uglifyFileName": false, "checkInvalidKey": true, "checkSiteMap": true, "uploadWithSourceMap": true, "compileHotReLoad": false, "lazyloadPlaceholderEnable": false, "useMultiFrameRuntime": true, "useApiHook": true, "useApiHostProcess": true, "babelSetting": { "ignore": [], "disablePlugins": [], "outputPath": "" }, "useIsolateContext": true, "userConfirmedBundleSwitch": false, "packNpmManually": false, "packNpmRelationList": [], "minifyWXSS": true, "disableUseStrict": false, "minifyWXML": true, "showES6CompileOption": false, "useCompilerPlugins": false, "ignoreUploadUnusedFiles": true }, "compileType": "miniprogram", "libVersion": "2.23.1", "appid": "wx0298165ccea56bb4", "projectname": "music", "condition": {}, "editorSetting": { "tabIndent": "insertSpaces", "tabSize": 2 } }
到此這篇關(guān)于微信小程序?qū)崿F(xiàn)音樂播放器實例詳解的文章就介紹到這了,更多相關(guān)小程序?qū)崿F(xiàn)音樂播放器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于IE瀏覽器以及Firefox下的javascript冒泡事件的響應(yīng)層級
原來是由于IE瀏覽器以及Firefox對于冒泡型事件的支持層次不同造成的。(如對冒泡事件不是很了解可先查詢相關(guān)資料)2010-10-10javascript中toFixed()四舍五入使用方法詳解
最近做的項目涉及到金額的計算,有一種方式就是進行四舍五入的規(guī)則進行小數(shù)點后面的尾數(shù)處理,以前一直以為toFixed方法就是四舍五入的,這里為大家分享一下2018-09-09bootstrap模態(tài)框嵌套、tabindex屬性、去除陰影的示例代碼
這篇文章主要介紹了bootstrap模態(tài)框嵌套、tabindex屬性、去除陰影,需要的朋友可以參考下2017-10-10uniapp開發(fā)H5打包微信小程序樣式失效的完美解決方法
本文主要介紹了在使用uniapp開發(fā)H5頁面并打包成微信小程序時,可能會出現(xiàn)樣式失效的問題,并提供了解決方法,通過本文的學(xué)習(xí),讀者可以了解uniapp開發(fā)H5頁面打包成微信小程序的注意事項,避免出現(xiàn)樣式失效等問題2023-03-03