if (navigator.mediaDevices.getUserMedia) {
const constraints = {
audio: true
};
let chunks = [];
navigator.mediaDevices.getUserMedia(constraints)
.then((stream) => {
this.recorder = new MediaRecorder(stream);
this.recorder.onstop = () => {
const blob = new Blob(chunks, {
type: 'audio/ogg; codecs=opus'
});
chunks = [];
const audioURL = URL.createObjectURL(blob);
this.audio.src = audioURL;
this.audio.oncanplay = function(e) {
console.error(this.duration, e);
this.play();
};
this.submitRecord(blob);
};
this.recorder.ondataavailable = function(e) {
chunks.push(e.data);
};
})
.catch((err) => {
this.cantRecord = false;
console.error('您的設備不能錄音', err);
});
} else {
this.cantRecord = false;
console.error('您的設備不能錄音');
}
複製代碼
可是這樣寫會遇到問題,咱們在獲取獲取audio的duration時候會發現 duration 是Infinity? 這是若是咱們動態的展現錄音時間時候就會有問題。首先明確一下這是chrome瀏覽器本身的存在的一個bug,由於咱們拿到的錄音數據流沒有定義長度,因此瀏覽器沒法解析出當前音頻的時長。html
formatePlayerDuration() {
this.player.onloadedmetadata = e => {
const audio = e.target;
const audioDuration = audio.duration;
if (audioDuration === Infinity) {
audio.currentTime = 1e101;
audio.ontimeupdate = function () {
this.ontimeupdate = () => {
return;
};
// 不從新設置currtTime,會直接觸發audio的ended事件,由於以前將currentTime設置成了一個比音頻時長還大的值。因此要將currentTime重置爲初始狀態。
// 注: 這裏有一個問題,直接設置爲0 是不起做用的。須要從新設置一下audio.currentTime = 1e101;而後再設置爲0
audio.currentTime = 1e101;
audio.currentTime = 0;
};
}
};
}
複製代碼
const recorder = {
init() {
this.initRecordPlayer();
this.initRecorder();
this.formatePlayerDuration();
},
initRecordPlayer() {
this.player = document.createElement('audio');
},
formatePlayerDuration() {
this.player.onloadedmetadata = e => {
const audio = e.target;
const audioDuration = audio.duration;
if (audioDuration === Infinity) {
audio.currentTime = 1e101;
audio.ontimeupdate = function () {
this.ontimeupdate = () => {
return;
};
// 不從新設置currtTime,會直接觸發audio的ended事件,由於以前將currentTime設置成了一個比音頻時長還大的值。
// 注: 這裏有一個問題,直接設置爲0 是不起做用的。須要從新設置一下audio.currentTime = 1e101;而後再設置爲0
audio.currentTime = 1e101;
audio.currentTime = 0;
};
}
};
},
initRecorder() {
if (navigator.mediaDevices.getUserMedia) {
const constraints = {
audio: true
};
let chunks = [];
navigator.mediaDevices.getUserMedia(constraints)
.then((stream) => {
this.recorder = new MediaRecorder(stream);
this.recorder.onstop = () => {
const blob = new Blob(chunks, {
type: 'audio/ogg; codecs=opus'
});
chunks = [];
const audioURL = URL.createObjectURL(blob);
this.audio.src = audioURL;
// 錄完自動播放
this.audio.oncanplay = function (e) {
this.play();
};
};
this.recorder.ondataavailable = function (e) {
chunks.push(e.data);
};
})
.catch((err) => {
console.error('您的設備不能錄音', err);
});
} else {
console.error('您的設備不能錄音');
}
}
}
複製代碼
這就是相關的簡單例子,實現方案大致就是這樣,(代碼我沒跑啊,直接是從業務中粘貼粘貼攢的),可是思路就是這樣,自測業務沒有問題,你們有問題能夠留言,一塊兒解決糾正html5