const mediaRecorder = new MediaRecorder(stream[, options]);
参数: stream,MediaStrem 对象,录制源; options,类型为 MediaRecorderOptions 的可选参数
MediaRecorderOptions 属性说明 | |
属性 | 说明 |
mimeType |
指定录制流的编码格式 调用 MediaRecorder.isTypeSupported()方法检查当前浏览器是否支持指定的编码格式。如果当前浏览器不支持指定的编码格式,则该构造函数抛出异常 NotSupportedError |
audioBitsPerSecond | 指定录制流的音频码率 |
videoBitsPerSecond | 指定录制流的视频码率 |
bitsPerSecond | 指定录制流中音视频的码率,用于替代 audioBitsPerSecond 和 videoBitsPerSecond 属性,如果这两个属性只指定了一个,则 bitsPerSecond 将替代另外一个 |
audioBitrateMode | 指定音频码率模式,取值为 cbr 或 vbr。cbr 指以固定码率进行编码,vbr 指以可变码率进行编码 |
如果没有指定录制流的码率,则默认视频码率为 2.5Mbps,音频码率取决于采样率和通道数。
如下面代码清单所示,创建录制流,指定的视频编码格式是 mp4,如果创建成功则返回 MediaRecorder 对象,创建失败则打印错误信息并返回 null。
function getRecorder(stream) {
const options = {
audioBitsPerSecond : 128000,
videoBitsPerSecond : 2500000,
mimeType : 'video/mp4'
}
let mediaRecorder = null;
try {
mediaRecorder = new MediaRecorder(stream,options);
} catch(e) {
console.error('Exception while creating MediaRecorder: ' + e);
}
return mediaRecorder;
}
返回构造 MediaRecorder 对象时指定的 MIME 编码格式,如果在构造时未指定,则返回浏览器默认使用的编码格式,类型为字符串。
下面代码清单调用 getUserMedia 方法获取音视频流,并指定 mp4 编码格式进行录制。
if (navigator.mediaDevices) {
console.log('getUserMedia supported.');
const constraints = { audio: true, video: true };
const chunks = [];
navigator.mediaDevices.getUserMedia(constraints)
.then(stream => {
const options = {
audioBitsPerSecond: 128000,
videoBitsPerSecond: 2500000,
mimeType:'video/mp4'
}
const mediaRecorder = new MediaRecorder(stream,options);
console.log(mediaRecorder.mimeType);
}).catch(error => {
console.log(error.message);
});
}
返回 MediaRecorder 对象的当前状态,类型为 RecordingState。
RecordingState 属性说明 | |
属性 | 说明 |
inactive | 没有进行录制,原因可能是录制没有开始或者已经停止 |
recording | 录制正在进行 |
paused | 录制已开始,当前处于暂停状态 |
下面的代码清单在 onclick 事件的处理函数中启动录制并打印录制的状态
record.onclick = () => {
mediaRecorder.start();
console.log(mediaRecorder.state);
}
返回构造 MediaRecorder 对象时指定的媒体流对象,类型为 MediaStream。
返回当前的视频码率,可能与构造时指定的码率不同,类型为数值。
返回当前的音频码率,可能与构造时指定的码率不同,类型为数值。
返回音频轨道的码率模式,类型为 BitrateMode。
BitrateMode 的枚举值 | |
枚举值 | 说明 |
cbr | cbr指以固定码率进行编码。 |
vbr | vbr指以可变码率进行编码。 |
检查当前浏览器是否支持指定的 MIME 格式。
const canRecord = MediaRecorder.isTypeSupported(mimeType)
参数: mimeType,MIME 媒体格式。
返回值: 类型为 Boolean,如果支持该 mimeType 则返回 true,否则返回 false。
下面的代码清单检测 types 数组中的 mimeType,如果当前浏览器支持此 mimeType,则打印 YES,如果不支持则打印 NO。
const types = [ "video/webm",
"audio/webm",
"video/webm\;codecs=vp8",
"video/webm\;codecs=daala",
"video/webm\;codecs=h264",
"audio/webm\;codecs=opus",
"video/mpeg"];
for (let i in types) {
console.log("Is "+ types[i] + " supported? "+(MediaRecorder.isTypeSupported(types[i]) ? "YES” : "NO"));
}
该方法触发 dataavailable 事件,事件包含 Blob 格式的录制数据。该方法通常需要周期性调用。
mediaRecorder.requestData()
参数: 无。
返回值: 无。如果 MediaRecorder.state 不是 recording,将抛出异常 InvalidState。
如下代码清单所示,每秒调用一次 requestData() 方法,并在 dataavailable 事件处理函数中获取录制数据。
this.mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
this.recordedChunks .push(event.data);
}
};
this.recorderIntervalHandler = setInterval(() => {
this.mediaRecorder.requestData();
}, 1000);
启动录制,将录制数据写入 Blob 对象。
mediaRecorder.start(timeslice)
参数: timeslice,可选参数,用于设置录制缓存区时长,单位为毫秒(ms)。如果指定了 timeslice,当 Blob 缓存区写满后,触发 dataavailable 事件,并重新创建一个 Blob 对象。如果未指定 timeslice,则录制数据会始终写人同一个 Blob 对象,直到调用 requestData()方法才会重新创建新的 Blob 对象。
返回值:无。如果调用出错,会抛出异常。
start 异常说明 | |
异常 | 说明 |
InvalidModificationError | 录制源的媒体轨道发生了变化,录制时不能添加或删除媒体轨道 |
InvalidStateError | MediaRecorder 当前状态不是 inactive |
NotSupportedError | 媒体源处于 inactive 状态,或者媒体轨道不可录制 |
SecurityError | 媒体流不允许录制 |
UnknownError | 其他未知错误 |
下面的代码清单启动录制,并将 Blob 缓存区设置为 100ms,缓存区满后触发 dataavailable 事件。
recorder.ondataavailable = (event) => {
console.log(' Recorded chunk of size ' + event.data.size +"B");
recordedChunks.push(event.data);
};
recorder.start(100);
暂停录制。当调用该方法时,浏览器将产生如下行为。
恢复录制。当调用该方法时,浏览器会产生如下行为。
下面的代码清单展示了暂停/恢复状态的切换。
pause.onclick = () =< {
if(MediaRecorder.state === "recording") {
//暂停录制。
mediaRecorder.pause();
} else if (MediaRecorder.state === "paused") {
//恢复录制
mediaRecorder.resume();
}
}
当调用 MediaRecorder.start() 方法时触发该事件。此时启动录制,录制数据开始写人 Blob,对应事件句柄 onstart。
以下两种语法都可以为 start 事件设置处理函数。
MediaRecorder.onstart = (event) => { ... }
MediaRecorder.addEventListener('start', (event) => { ... })
下面的代码清单启动录制,并在 onstart 事件句柄中处理录制数据。
record.onclick = () => {
mediaRecorder.start();
console.log("recorder started");
}
mediaRecorder.onstart = () => {
//start事件处理流程
}
当调用 MediaRecorder.pause() 方法时触发该事件。此时暂停录制数据,对应事件句柄 onpause。
以下两种语法都可以为 pause 事件设置处理函数。
MediaRecorder.onpause = (event) => { ... }
MediaRecorder.addEventListener('pause', (event) => { ... })
下面的代码清单在 onclick 事件中切换录制状态并在相应的事件句柄中输出日志。
pause.onclick = () => {
if (mediaRecorder.state === "recording") {
mediaRecorder.pause();
} else if (mediaRecorder.state === "paused") {
mediaRecorder.resume();
}
}
mediaRecorder.onpause = () => {
console.log("mediaRecorder paused!");
}
mediaRecorder.onresume = () => {
console.log("mediaRecorder resumed!");
}
当调用 MediaRecorderresume() 方法时触发该事件。此时由暂停恢复录制,对应事件句柄 onresume。
以下两种语法都可以为 resume 事件设置处理函数。
MediaRecorder.onresume = (event) => { ... }
MediaRecorder.addEventListener('resume', (event) => { ... })
当调用 MediaRecorder.stop() 方法或媒体流中止时触发该事件。此时停止录制数据,对 应事件句柄 onstop。
以下两种语法都可以为 stop 事件设置处理函数。
MediaRecorder.onstop = (event) => { ... }
MediaRecorder.addEventListener('stop', (event) => { ... })
下面的代码清单在 ondataavailable 事件句柄中将录制的数据保存到 chunks 数组,当录制 停止时,使用 chunks 生成音频地址,回放录制的数据。
mediaRecorder.onstop = (e) => {
console.log("data available after MediaRecorder.stop() called.");
let audio = document.createElement ('audio');
audio.controls = true;
const blob = new Blob(chunks, { 'type' : 'audio/ogg; codecs=opus' ));
const audioURL = window.URL.createObjectURL(blob);
audio.srcobject = audioURL;
console.log("recorder stopped");
}
mediaRecorder.ondataavailable = (e) => {
chunks.push(e.data);
}
该事件用于处理录制数据,对应事件句柄 ondataavailable,以下情况会触发该事件。
以下两种语法都可以为 dataavailable 事件设置处理函数。
MediaRecorder.ondataavailable = (event) => { ... }
MediaRecorder.addEventListener('dataavailable', (event) => { ... })
在创建录制对象或录制过程中出现错误时触发该事件,事件类型为 MediaRecorderErrorEvent,对应事件句柄 onerror。
以下两种语法都可以为 error 事件设置处理函数。
MediaRecorder.onerror = (event) => { ... }
MediaRecorder.addEventListener('error', (event) => { ... })
下表列出了该事件触发时的错误名,错误名可以通过 MediaRecorderErrorEvent.error.name 获取。
MediaRecorder 错误名 | |
错误名 | 说明 |
InvalidStateError | 在活跃状态调用了 start() 方法、resume() 方法以及在不活跃状态调用了 stop() 方法和 pause() 方法都会导致该错误 |
SecurityError | 因为安全问题,该媒体流不允许被录制。比如使用 getUserMedia() 获取媒体流时,用户未通过授权 |
NotSupportedError | 不支持传人 MIME 格式 |
UnknownError | 其他未知错误 |
下面的代码清单实现了录制流函数 recordStream,在该函数中启动录制,保存录制数据并在出错时打印错误信息。
function recordstream(stream) {
let bufferList = [];
let recorder = new MediaRecorder(stream);
recorder.ondataavailable = (event) => {
bufferList.push(event.data);
};
recorder.onerror = (event) => {
let error = event .error;
switch (error.name) {
case InvalidstateError:
console.log("You can't record the video right now. Try again later.");
break;
case SecurityError:
console.log("Recording the specified source is not allowed due to securityrestrictions.");
break;
default:
console.log("A problem occurred while trying to record the video.");
break;
}
};
recorder.start(100);
return recorder;
}