1. 程式人生 > >(13) Nuxt.js寫一個常規音訊的播放元件,動態注入微信,新浪微博的js-sdk

(13) Nuxt.js寫一個常規音訊的播放元件,動態注入微信,新浪微博的js-sdk

export default { props: { userName: { type: String, default: 'Super Hero' }, duration: { type: [String, Number], default: '' }, autoplay: { type: [Boolean, String], default: false }, sourceUrl: { type: String
, default: '' }, coverpic: { type: String, default: '' } }, data() { return { defaultAvatar: require('@/assets/share/[email protected]'), // 預設頭像 audioElm: '', // 音訊播放器 DOM soundCurrentStopTime: ''
, // 當前聲音暫停的時間戳 playState: false, // 播放狀態的圖示控制 timeStepState: '', // 時間迭代 voicePlayMessage: '', // 音訊資源的狀況 currentPlayTime: '00:00', // 當前播放的時間,預設為0 cacheCurrentTime: 0 // 快取播放時間 }; }, computed: { coverUrl() { if (!this.coverpic) { return
this.defaultAvatar; } return this.coverpic; }, voiceTime() { if (this.duration) { return this.second2time(Number(this.duration)); } } }, watch: { sourceUrl(newVal, oldVal) { if (newVal) { this.playAudio(); } } }, created() { this.$store.commit('OPEN_LOADING'); }, beforeMount() { // 初始化音訊播放器 this.initAudioElm(); }, mounted() { // 檢測微博微信平臺 this.checkWeiBo_WeiChat(); this.audioElm.addEventListener('stalled', this.stalled); this.audioElm.addEventListener('loadstart', this.loadstart); this.audioElm.addEventListener('loadeddata', this.loadeddata); this.audioElm.addEventListener('canplay', this.canplay); this.audioElm.addEventListener('ended', this.ended); this.audioElm.addEventListener('pause', this.pause); this.audioElm.addEventListener('timeupdate', this.timeupdate); this.audioElm.addEventListener('error', this.error); this.audioElm.addEventListener('abort', this.abort); }, beforeDestroy() { this.audioElm.removeEventListener('loadstart', this.loadstart); this.audioElm.removeEventListener('stalled', this.stalled); this.audioElm.removeEventListener('canplay', this.canplay); this.audioElm.removeEventListener('timeupdate', this.timeupdate); this.audioElm.removeEventListener('pause', this.pause); this.audioElm.removeEventListener('error', this.error); this.audioElm.removeEventListener('ended', this.ended); }, methods: { initAudioElm() { let audio = new Audio(); audio.autobuffer = true; // 自動快取 audio.preload = 'metadata'; audio.src = this.sourceUrl; audio.load(); this.audioElm = audio; }, checkWeiBo_WeiChat() { let ua = navigator.userAgent.toLowerCase(); // 獲取判斷用的物件 const script = document.createElement('script'); if (/micromessenger/.test(ua)) { // 返回一個獨立的promise script.src = 'https://res.wx.qq.com/open/js/jweixin-1.2.0.js'; new Promise((resolve, reject) => { let done = false; script.onload = script.onreadystatechange = () => { if ( !done && (!script.readyState || script.readyState === 'loaded' || script.readyState === 'complete') ) { done = true; // 避免記憶體洩漏 script.onload = script.onreadystatechange = null; resolve(script); } }; script.onerror = reject; document .getElementsByTagName('head')[0] .appendChild(script); }).then(res => { this.initWeixinSource(); }); } if (/WeiBo|weibo/i.test(ua)) { script.src = 'https://tjs.sjs.sinajs.cn/open/thirdpart/js/jsapi/mobile.js'; new Promise((resolve, reject) => { let done = false; script.onload = script.onreadystatechange = () => { if ( !done && (!script.readyState || script.readyState === 'loaded' || script.readyState === 'complete') ) { done = true; // 避免記憶體洩漏 script.onload = script.onreadystatechange = null; resolve(script); } }; script.onerror = reject; document .getElementsByTagName('head')[0] .appendChild(script); }).then(res => { this.initWeiboSource(); }); } }, canplay() { this.$store.commit('CLOSE_LOADING'); }, initWeixinSource() { wx.config({ // 配置資訊, 即使不正確也能使用 wx.ready debug: false, appId: '', timestamp: 1, nonceStr: '', signature: '', jsApiList: [] }); wx.ready(() => { let st = setTimeout(() => { clearTimeout(st); this.audioElm.load(); }, 50); }); }, initWeiboSource() { window.WeiboJS.init( { appkey: '3779229073', debug: false, timestamp: 1429258653, noncestr: '8505b6ef40', scope: [ 'getNetworkType', 'networkTypeChanged', 'getBrowserInfo', 'checkAvailability', 'setBrowserTitle', 'openMenu', 'setMenuItems', 'menuItemSelected', 'setSharingContent', 'openImage', 'scanQRCode', 'pickImage', 'getLocation', 'pickContact', 'apiFromTheFuture' ] }, ret => { this.audioElm.load(); } ); }, playAudio() { // 播放暫停音訊 if (this.audioElm.readyState > 2) { // 當資源可以播放的時候 if (this.audioElm.paused) { this.cacheCurrentTime === 0 ? (this.audioElm.currentTime = 0) : (this.audioElm.currentTime = this.cacheCurrentTime); this.playState = true; this.audioElm.play(); } else { this.audioElm.pause(); } } }, second2time(currentTime) { // 秒數化為分鐘 let min = Math.floor(currentTime / 60); // 向下取整分鐘 let second = Math.floor(currentTime % 60); // 取模得到剩餘秒數 if (min < 10) { min = '0' + min; } if (second < 10) { second = '0' + second; } return `${min}:${second}`; }, stalled() { // 資源需要快取的時候暫停 this.audioElm.pause(); // 快取載入待播的時候,若是當前播放時間已經走動則觸發播放 if (this.audioElm.currentTime !== 0) { // 判斷當前播放的時間是否到達結束,否則則繼續播放 if (this.audioElm.currentTime !== this.audioElm.duration) { this.playAudio(); } else { this.ended(); } } }, timeupdate() { if ( this.audioElm.readyState > 2 && this.audioElm.currentTime > 0.2 ) { this.cacheCurrentTime = this.audioElm.currentTime; this.currentPlayTime = this.second2time( Number(this.audioElm.currentTime) ); if ( this.audioElm.ended || this.audioElm.currentTime === this.audioElm.duration ) { this.ended(); } } }, ended() { this.audioElm.pause(); // 清除快取的時間 this.cacheCurrentTime = 0; this.voicePlayMessage = ''; }, pause() { // 當音訊/視訊已暫停時 this.playState = false; }, error(err) { // 當在音訊/視訊載入期間發生錯誤時 this.audioElm.pause(); this.voicePlayMessage = '音訊載入資源錯誤!'; console.log('我報錯了:' + err); }, abort() { this.audioElm.pause(); } } };