gui-audio-player.vue 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <view class="gui-player">
  3. <view class="gui-player-title"
  4. :style="{color:color}">{{list[index].title}}</view>
  5. <view class="gui-player-poster">
  6. <image
  7. class="gui-player-poster-img"
  8. :class="[playStatus == 1 ? 'gui-playing' : '']"
  9. :src="list[index].coverImgUrl"
  10. mode="aspectFill"></image>
  11. </view>
  12. <!-- 播放进度 -->
  13. <view style="padding:25rpx;">
  14. <gui-single-slider
  15. ref="graceSingleSlider"
  16. @change="progressChange"
  17. :barWidth="100"
  18. :barClass="['gui-bg-gray', 'gui-primary-text']"
  19. :bglineClass="['gui-bg-gray']"
  20. :bglineAClass="['gui-bg-green']"
  21. :barText="playTime"></gui-single-slider>
  22. </view>
  23. <!-- 播放控制 -->
  24. <view class="gui-player-console">
  25. <!-- 循环模式 -->
  26. <view class="gui-player-tool"
  27. @tap="changeType">
  28. <text class="gui-player-tool gui-icons"
  29. v-if="dotype == 1">&#xe677;</text>
  30. <text class="gui-player-tool gui-icons"
  31. v-if="dotype == 2" style="font-size:40rpx;">&#xe64a;</text>
  32. </view>
  33. <view class="gui-player-console-c">
  34. <text class="gui-player-tool gui-icons" @tap="prev">&#xe659;</text>
  35. <text class="gui-player-tool gui-icons" style="font-size:66rpx;"
  36. @tap="pause" v-if="playStatus == 1">&#xe64b;</text>
  37. <text class="gui-player-tool gui-icons" style="font-size:66rpx;"
  38. @tap="playi" v-if="playStatus == 2">&#xe649;</text>
  39. <text class="gui-player-tool gui-icons" @tap="next">&#xe65a;</text>
  40. </view>
  41. <text class="gui-player-tool gui-icons" @tap="openList">&#xe648;</text>
  42. </view>
  43. <!-- 歌曲列表 -->
  44. <view class="gui-shade" :style="{left:listShow?'0':'-2000px'}"
  45. @tap.stop.parent="hideList" @touchmove.stop.parent="">
  46. <scroll-view
  47. scroll-y="true"
  48. class="graceplayer-list"
  49. :style="{background:listBg, height:listHeight}">
  50. <view class="graceplayer-list-item">歌曲列表</view>
  51. <view class="graceplayer-list-item"
  52. :class="[index == idx ? 'graceplayer-list-item-this' : '']"
  53. v-for="(item, idx) in list"
  54. :key="idx"
  55. @tap="playList"
  56. :data-index="idx">{{item.title}}<text class="graceplayer-list-item-singer"> - {{item.singer}}</text></view>
  57. </scroll-view>
  58. </view>
  59. </view>
  60. </template>
  61. <script>
  62. export default{
  63. name : "gui-audio-player",
  64. props : {
  65. color : {type:String, default:'#FFFFFF'},
  66. list : {type:Array , default:function(){return [];}},
  67. listBg : {type:String, default:'#292E35'},
  68. listHeight : {type:String, default:'880rpx'},
  69. autoplay : {type:Boolean, default:true}
  70. },
  71. data(){
  72. return {
  73. playStatus : 1,
  74. player : null,
  75. playTime : '00:00',
  76. timer : null,
  77. dotype : 1,
  78. index : 0,
  79. listShow : false,
  80. audioLength : 1
  81. }
  82. },
  83. mounted:function(){
  84. if(this.autoplay){
  85. this.play();
  86. }
  87. },
  88. created:function(){
  89. // #ifdef H5
  90. return ;
  91. // #endif
  92. this.player = uni.getBackgroundAudioManager();
  93. this.player.onTimeUpdate(()=>{
  94. try{
  95. if(this.playStatus != 1){return ;}
  96. this.audioLength = this.player.duration;
  97. // 调整进度
  98. var progress = this.player.currentTime / this.audioLength;
  99. progress = Math.round(progress * 100);
  100. var ref = this.$refs.graceSingleSlider;
  101. if(ref){
  102. ref.setProgress(progress);
  103. }
  104. this.playTime = this.timeFormat(this.player.currentTime);
  105. }catch(e){};
  106. });
  107. this.player.onPlay(()=>{
  108. this.playStatus = 1;
  109. this.audioLength = this.player.duration;
  110. });
  111. this.player.onPause(()=>{
  112. this.playStatus = 2;
  113. });
  114. this.player.onEnded(()=>{
  115. switch(this.dotype){
  116. case 1 :
  117. this.index++;
  118. if(this.index + 1 > this.list.length){this.index = 0;}
  119. this.play();
  120. break;
  121. case 2 :
  122. this.player.seek(0);
  123. this.play();
  124. break;
  125. }
  126. });
  127. if(this.player.currentTime < 1){
  128. this.play();
  129. }
  130. },
  131. methods:{
  132. play:function () {
  133. var audio = this.list[this.index];
  134. this.player.title = audio.title;
  135. this.player.singer = audio.singer;
  136. this.player.coverImgUrl = audio.coverImgUrl;
  137. this.player.src = audio.src;
  138. this.player.play();
  139. },
  140. progressChange : function(e){
  141. if(this.timer != null){ clearTimeout(this.timer); }
  142. this.player.pause();
  143. var needTime = this.audioLength * e / 100;
  144. needTime = Math.round(needTime);
  145. this.playTime = this.timeFormat(needTime);
  146. this.timer = setTimeout(()=>{
  147. this.player.seek(needTime);
  148. this.player.play();
  149. }, 800);
  150. },
  151. timeFormat : function (s){
  152. s = Math.round(s);
  153. if(s < 60){
  154. if(s < 10){return '00:0'+s;}
  155. return '00:'+s;
  156. }else{
  157. var second = s % 60;
  158. s = s - second;
  159. var minute = s / 60;
  160. if(minute < 10){minute = '0'+minute;}
  161. if(second < 10){second = '0'+second;}
  162. return minute+':'+second;
  163. }
  164. },
  165. changeType : function () {
  166. switch(this.dotype){
  167. case 1 :
  168. this.dotype = 2;
  169. break;
  170. case 2 :
  171. this.dotype = 1;
  172. break;
  173. }
  174. },
  175. pause :function () {this.player.pause();},
  176. playi :function () {this.player.play();},
  177. next : function () {
  178. if(this.index + 1 >= this.list.length){uni.showToast({title:"已经到底了 (:", icon:"none"}); return ;}
  179. this.index++;
  180. this.play();
  181. },
  182. prev : function () {
  183. if(this.index -1 < 0){uni.showToast({title:"已经到头了 (:", icon:"none"}); return ;}
  184. this.index--;
  185. this.play();
  186. },
  187. openList : function () { this.listShow = true; },
  188. hideList : function () { this.listShow = false; },
  189. playList : function (e) {
  190. var idx = e.currentTarget.dataset.index;
  191. this.index = idx;
  192. this.play();
  193. },
  194. setIndex : function (idx) { this.index = idx; }
  195. }
  196. }
  197. </script>
  198. <style scoped>
  199. .gui-player{padding:30rpx;}
  200. .gui-player-title{text-align:center; line-height:50rpx; font-size:30rpx; font-weight:bold;}
  201. .gui-player-poster{padding:30px; line-height:0; text-align:center;}
  202. .gui-player-poster-img{width:380rpx; height:380rpx; border-radius:300rpx; box-shadow:0rpx 2rpx 2rpx #323232;}
  203. @keyframes gui-rotate360{0%{transform:rotate(0deg);} 50%{transform:rotate(180deg);} 100%{transform:rotate(360deg);}}
  204. .gui-playing{animation:gui-rotate360 6000ms infinite linear;}
  205. .gui-player-console{padding:20rpx 10rpx; display:flex; flex-direction:row; align-items:center; justify-content:space-between;}
  206. .gui-player-tool{width:100rpx; line-height:100rpx; text-align:center; font-size:50rpx; display:block; flex-shrink:0; color:#FFFFFF;}
  207. .gui-player-console-c{width:400rpx; display:flex; flex-direction:row; justify-content:space-between;}
  208. .graceplayer-list{width:100%; height:1000rpx; background-color:#FFFFFF; position:absolute; left:0; bottom:0; z-index:9999;}
  209. .gui-shade{position:fixed; width:100%; height:100%; left:0; top:0; background-color:rgba(0,0,0,0.5); bottom:0; overflow:hidden; z-index:9998; display:flex; justify-content:center; align-items:center;}
  210. .graceplayer-list-item{padding:25rpx 0rpx; margin:5rpx 30rpx; border-bottom:1px solid #373A3F; line-height:50rpx; font-size:30rpx; color:#FFFFFF;}
  211. .graceplayer-list-item-singer{color:#888888; font-size:26rpx; margin-left:50rpx;}
  212. .graceplayer-list-item-this{color:#64CDA5 !important; font-weight:bold;}
  213. </style>