| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- <template>
- <!--
- 引用方式
- onLoad() {
- var audioPlayer = this.$refs.audioPlayer;
- audioPlayer.setSrc(
- "https://vkceyugu.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3");
- // audioPlayer.setPoster(
- // "https://vkceyugu.cdn.bspapp.com/VKCEYUGU-uni-app-doc/7fbf26a0-4f4a-11eb-b680-7980c8a877b8.png"); //海报图片
- audioPlayer.setSinger("贝多芬"); //设置歌手
- audioPlayer.setName("致爱丽丝"); //设置作品名字
- //
- },
- -->
- <view class="imt-audio">
- <view class="audio-top">
- <view class="audio-left">
- <view class="audio-control-wrapper">
- <image :src="poster" mode="aspectFill" class="cover"></image>
- <!-- loading存在逻辑问题,注释掉不用了 -->
- <!-- <image :src="require('./static/loading.png')" v-if="playState=='loading'" class="play loading"></image> -->
- <!-- <template v-else> -->
- <image :src="require('./static/playbtn.png')" alt="play" @click="play" class="play" v-if="playState=='pause'">
- </image>
- <image :src="require('./static/pausebtn.png')" alt="pause" @click="pause" class="play" v-else></image>
- <!-- </template> -->
- </view>
- </view>
- <view class="audio-right">
- <view class="audio-wrapper">
- <view class="titlebox">
- <view class="title">{{name}}</view>
- <view v-if="singer" class="singer">{{singer}}</view>
- </view>
- </view>
- <slider class="audio-slider" block-size="12" block-color="#49679c" activeColor="#49679c"
- backgroundColor="#dddddd" :max="duration" :value="currentTime" @change="sliderChange"
- @changing="sliderChanging"></slider>
- <view class="slidebox">
- <view>{{formatSeconds(currentTime)}}</view>
- <view>{{formatSeconds(duration)}}</view>
- </view>
- </view>
- </view>
- <view v-if="playState=='playing'" class="play-btns">
- <view @click.stop="sliderTo(-15)">
- <u-icon name="rewind-left" color="#898989" size="22"></u-icon>
- </view>
- <view class="play-speed" @click.stop="changePlaySpeed">
- {{currentSpeed==1?'倍数': currentSpeed + ' 倍'}}
- </view>
- <view @click.stop="sliderTo(15)">
- <u-icon name="rewind-right" color="#898989" size="22"></u-icon>
- </view>
- </view>
- </view>
- </template>
- <script>
- /*
- createInnerAudioContext()是audio组件的内部实现,不能熄屏播放、不能后台播放、不能倍速播放。
- getBackgroundAudioManager() 可以熄屏播放、后台播放,不能倍速播放。缺点是响应速度很慢,无法实现精细、及时的进度控制,而且可能被别的程序占用。
-
- 因此这里只能用video来实现,video能倍速播放,不能熄屏播放、不能后台播放。而且避免了用createInnerAudioContext()实现的跳转到别的页面,还在播放的问题
- 因此应用程序可以在需要后台播放的时候(需要用户操作触发),再暂停这个控件的播放,然后自己用getBackgroundAudioManager实现后台播放
- */
- import Vue from 'vue';
- export default {
- props: {},
- data() {
- return {
- bgAudio: null,
- //
- src: "",
- poster: "",
- name: "...",
- singer: "...",
- duration: 0,
- currentTime: 0,
- nextTime: null,
- playState: "pause", //"loading"/"playing"/"pause"
- isSliderChanging: false,
- currentSpeed: 1
- };
- },
- created: function() {
- },
- methods: {
- // 后台播放相关
- operateBgAudio(opearteType) {
- const that = this;
- let bgAudio = this.bgAudio;
- if (!bgAudio) {
- // 进度条恢复可动
- this.isSliderChanging = false;
- //
- bgAudio = uni.getBackgroundAudioManager();
- bgAudio.paused = true;
- bgAudio.currentTime = this.currentTime || 0;
- bgAudio.title = "致爱丽丝"; //设置作品名字
- bgAudio.src = 'https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3';
- bgAudio.onPlay(e => {
- this.playState = "playing";
- })
- bgAudio.onPause(e => {
- this.isSliderChanging = false;
- this.playState = "pause";
- })
- bgAudio.onStop(e => {
- // 清空
- that.stop();
- })
- bgAudio.onEnded(e => {
- // 清空
- that.bgAudio = '';
- this.isSliderChanging = false;
- that.stop();
- })
- bgAudio.onTimeUpdate(e => {
- if (that.nextTime === 0 || that.nextTime > 0) {
- that.currentTime = that.nextTime;
- setTimeout(function() {
- that.nextTime = null;
- that.isSliderChanging = false;
- })
- } else {
- if (that.isSliderChanging == false) {
- that.currentTime = that.bgAudio.currentTime || 0;
- that.duration = that.bgAudio.duration || 0;
- }
- }
- })
- this.bgAudio = bgAudio;
- }
- switch (opearteType) {
- case 'play':
- bgAudio.play();
- break;
- case 'pause':
- bgAudio.pause();
- break;
- case 'sliderChange':
- bgAudio.seek(this.nextTime)
- this.isSliderChanging = false;
- break;
- case 'changePlaySpeed':
- bgAudio.playbackRate = this.currentSpeed;
- break;
- }
- },
- // 切换播放速度
- changePlaySpeed() {
- if (this.currentSpeed < 2) {
- this.currentSpeed += 0.25;
- } else {
- this.currentSpeed = 1;
- }
- //
- this.operateBgAudio('changePlaySpeed');
- },
- setSrc: function(value) {
- this.src = value;
- },
- setPoster: function(value) {
- this.poster = value;
- },
- setName: function(value) {
- this.name = value;
- },
- setSinger: function(value) {
- this.singer = value;
- },
- formatSeconds: function(seconds) {
- var result = typeof seconds === "string" ? parseFloat(seconds) : seconds;
- if (isNaN(result))
- return "";
- let h = Math.floor(result / 3600) < 10 ?
- "0" + Math.floor(result / 3600) :
- Math.floor(result / 3600);
- let m = Math.floor((result / 60) % 60) < 10 ?
- "0" + Math.floor((result / 60) % 60) :
- Math.floor((result / 60) % 60) + h * 60;
- let s = Math.floor(result % 60) < 10 ?
- "0" + Math.floor(result % 60) :
- Math.floor(result % 60);
- return `${m}:${s}`;
- },
- play: function() {
- this.playState = "playing";
- //
- this.operateBgAudio("play");
- },
- pause: function() {
- this.playState = "pause";
- this.operateBgAudio("pause");
- },
- sliderTo(time) {
- this.isSliderChanging = true;
- this.currentTime += time;
- this.nextTime = this.currentTime;
- this.operateBgAudio("sliderChange");
- },
- sliderChange: function(e) {
- this.isSliderChanging = true;
- // 进度条下次变化时间
- this.nextTime = e.detail.value;
- this.operateBgAudio("sliderChange");
- },
- sliderChanging: function() {
- this.isSliderChanging = true;
- },
- stop: function() {
- this.isSliderChanging = true;
- this.currentTime = 0;
- this.playState = "pause";
- },
- },
- }
- </script>
- <style lang="scss">
- @import './index.scss';
- </style>
|