1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
---
title: MediaStream Recording API
slug: Web/API/MediaStream_Recording_API
tags:
- API
- Audio
- Media
- Media Capture and Streams
- MediaStream Recording
- MediaStream Recording API
- NeedsTranslation
- Overview
- Reference
- TopicStub
- Video
translation_of: Web/API/MediaStream_Recording_API
---
<div>{{DefaultAPISidebar("MediaStream Recording")}}</div>
<div><span class="seoSummary"><strong>MediaStream Recording API </strong>有时简称为<em>Media Recording API</em> 或者 <em>MediaRecorder API</em>, 与 <a href="/en-US/docs/Web/API/Media_Streams_API">Media Capture and Streams API</a> 和 <a href="/en-US/docs/Web/API/WebRTC_API">WebRTC API</a> 密切相关. MediaStream Recording API 使得捕获通过 {{domxref("MediaStream")}} 或者{{domxref("HTMLMediaElement")}} 对象产生的用于分析、加工或者保存到硬盘的数据成为可能. 它也非常容易让人们使用.</span></div>
<h2 id="基本概念">基本概念</h2>
<p>MediaStream Recording API 由一个主接口{{domxref("MediaRecorder")}}组成,这个接口负责的所有工作是从{{domxref("MediaStream")}}获取数据并将其传递给你进行处理。数据通过一系列{{event("dataavailable")}}事件传递,这些数据已经成为你创建 <code>MediaRecorder</code> 时所声明的格式。然后,您可以进一步处理数据,或者根据需要将其写入文件。</p>
<h3 id="录制过程概述">录制过程概述</h3>
<p>记录一个流的过程是非常容易的:</p>
<ol>
<li>建立一个 {{domxref("MediaStream")}}或者{{domxref("HTMLMediaElement")}} (以 {{HTMLElement("audio")}} 或 {{HTMLElement("video")}} 元素的形式) 来充当媒体数据的源.</li>
<li>创建一个 {{domxref("MediaRecorder")}} 对象, 指定源以及任何有需求的的选项 (比如容器的 MIME 类型或它轨道所需的比特率).</li>
<li>给 {{event("dataavailable")}} 事件设置{{domxref("MediaRecorder.ondataavailable")}} 事件处理函数; 会在数据可利用时候调用.</li>
<li>一旦媒体源播放,你已经准备好录制,使用 {{domxref("MediaRecorder.start()")}} 开始录制.</li>
<li>{{event("dataavailable")}} 事件处理函数正如你所愿的在每次数据准备好时调用; 这个事件有一个值为包含媒体数据的{{domxref("Blob")}} 类型的 <code>data</code> 属性. 你可以强制 <code>dataavailable</code> 事件发生, 因此会给你传递最新的声音以至于可以让你过滤、保存或者做一些其他的事情。</li>
<li>当源媒体停止播放时候,录制自动结束.</li>
<li>你可以随时结束录制通过使用 {{domxref("MediaRecorder.stop()")}}.</li>
</ol>
<div class="note">
<p><strong>注意:</strong> 单单使用包含已经录制好媒体切片的{{domxref("Blob")}}s 将大可不能单独播放. 媒体在重放之前需要重新组装 .</p>
</div>
<p>如果在录制过程中出错, {{event("error")}} 事件将会传给<code>MediaRecorder</code>. 你可以设置{{domxref("MediaRecorder.onerror", "onerror")}}去监听 <code>error</code> 事件.</p>
<p>例子中,我们使用Canvas 作为{{domxref("MediaStream")}}的源,在9秒后停止录音.</p>
<pre class="brush: js notranslate">var canvas = document.querySelector("canvas");
// Optional frames per second argument.
var stream = canvas.captureStream(25);
var recordedChunks = [];
console.log(stream);
var options = { mimeType: "video/webm; codecs=vp9" };
mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start();
function handleDataAvailable(event) {
console.log("data-available");
if (event.data.size > 0) {
recordedChunks.push(event.data);
console.log(recordedChunks);
download();
} else {
// ...
}
}
function download() {
var blob = new Blob(recordedChunks, {
type: "video/webm"
});
var url = URL.createObjectURL(blob);
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = "test.webm";
a.click();
window.URL.revokeObjectURL(url);
}
// demo: to download after 9sec
setTimeout(event => {
console.log("stopping");
mediaRecorder.stop();
}, 9000);</pre>
<h3 id="检查_and_控制记录器的状态">检查 and 控制记录器的状态</h3>
<p>你也可以使用 <code>MediaRecorder</code> 对象的属性去决定录制过程的状态, 用 {{domxref("MediaRecorder.pause", "pause()")}} 和 {{domxref("MediaRecorder.resume", "resume()")}} 方法暂停或者继续媒体源的录制.</p>
<p>如果你需要检查一个特殊的MIME类型是否被支持,使用{{domxref("MediaRecorder.isTypeSupported()")}}.</p>
<h3 id="检查潜在的输入源">检查潜在的输入源</h3>
<p>如果你的目标是记录摄像头或麦克风输入,您可能希望在构建 <code>MediaRecorder</code> 之前检查可用的输入设备. 这时,你需要调用 {{domxref("MediaDevices.enumerateDevices", "navigator.mediaDevices.enumerateDevices()")}} 来得到可使用的媒体设备. 你可以检查此列表,发现潜在的设备,甚至在有需要的时候过滤掉设备.</p>
<p>在这块代码中, <code>enumerateDevices()</code> 被用来检查可利用的设备,找到那些音频输入设备, 创建{{HTMLElement("option")}} 元素,之后添加到{{HTMLElement("select")}}元素,代表输入源选择器 .</p>
<pre class="brush: js notranslate">navigator.mediaDevices.enumerateDevices()
.then(function(devices) {
devices.forEach(function(device) {
let menu = document.getElementById("inputdevices");
if (device.kind == "audioinput") {
let item = document.createElement("option");
item.innerHTML = device.label;
item.value = device.deviceId;
menu.appendChild(item);
}
});
});</pre>
<p>类似的代码可以用来让用户限制他们希望使用的设备。</p>
<h3 id="更多信息">更多信息</h3>
<p>更多关于MediaStream Recording API 的使用, 查看 <a href="/en-US/docs/Web/API/MediaStream_Recording_API/Using_the_MediaStream_Recording_API">Using the MediaStream Recording API</a>, 这个显示了如何使用API来记录音频剪辑. 另一篇文章, <a href="/en-US/docs/Web/API/MediaStream_Recording_API/Recording_a_media_element">Recording a media element</a>, 介绍了如何从 {{HTMLElement("audio")}} 或{{HTMLElement("video")}} 元素 接收信息流和如何使用接收到的信息流(这个案例中,接收、存到硬盘)。 </p>
<h2 id="参考">参考</h2>
<dl>
<dt>{{domxref("BlobEvent")}}</dt>
<dd>Each time a chunk of media data is finished being recorded, it's delivered to consumers in {{domxref("Blob")}} form using a {{domxref("BlobEvent")}} of type <code>dataavailable</code>.</dd>
<dt>{{domxref("MediaRecorder")}}</dt>
<dd>The primary interface that implements the MediaStream Recording API.</dd>
<dt>{{domxref("MediaRecorderErrorEvent")}}</dt>
<dd>The interface that represents errors thrown by the MediaStream Recording API. Its {{domxref("MediaRecorderErrorEvent.error", "error")}} property is a {{domxref("DOMException")}} that specifies that error occurred.</dd>
</dl>
<h2 id="说明">说明</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td>{{SpecName("MediaStream Recording", "#MediaRecorderAPI")}}</td>
<td>{{Spec2("MediaStream Recording")}}</td>
<td>Initial definition</td>
</tr>
</tbody>
</table>
<h2 id="浏览器支持情况">浏览器支持情况</h2>
{{Compat("api.MediaRecorder")}}
<h2 id="参阅">参阅</h2>
<ul>
<li><a href="/en-US/docs/Web/API/MediaStream_Recording_API/Using_the_MediaStream_Recording_API">Using the MediaStream Recording API</a></li>
<li><a href="/en-US/docs/Web/API/MediaStream_Recording_API/Recording_a_media_element">Recording a media element</a></li>
<li><a href="https://simpl.info/mediarecorder/">simpl.info MediaStream Recording demo</a>, by <a href="https://twitter.com/sw12">Sam Dutton</a></li>
<li>{{domxref("navigator.mediaDevices.getUserMedia()")}}</li>
<li><a href="https://addpipe.com/blog/mediarecorder-api/">HTML5’s Media Recorder API in Action on Chrome and Firefox</a></li>
<li><a href="https://github.com/ai/audio-recorder-polyfill">MediaRecorder polyfill</a> for Safari and Edge</li>
<li><a href="https://github.com/chrisjohndigital/TutorRoom">TutorRoom</a>: HTML5 video capture/playback/download using getUserMedia and the MediaRecorder API (<a href="https://github.com/chrisjohndigital/TutorRoom">source on GitHub</a>)</li>
<li><a href="https://www.fingerspell.org/">FingerSpell</a>: Sign Language Fingerspelling practice using getUserMedia and the MediaRecorder API to create and download recordings, MediaRecorder API supported desktop browsers only <a href="https://github.com/chrisjohndigital/CameraCaptureJS">(source on GitHub</a>)</li>
<li><a href="http://codepen.io/anon/pen/gpmPzm">Simple video recording demo</a></li>
<li><a href="https://quickblox.github.io/javascript-media-recorder/sample/">Advanced media stream recorder sample</a></li>
<li><a href="https://github.com/chrisjohndigital/OpenLang">OpenLang</a>: HTML5 video language lab web application using MediaDevices and the MediaStream Recording API for video recording (<a href="https://github.com/chrisjohndigital/OpenLang">source on GitHub</a>)</li>
</ul>
|