(13) Nuxt.js寫一個常規音訊的播放元件,動態注入微信,新浪微博的js-sdk
阿新 • • 發佈:2019-01-06
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();
}
}
};