aboutsummaryrefslogtreecommitdiff
path: root/files/es/web/api/mediadevices/getusermedia/index.html
blob: 1466aecd3651a57c699d38c4b1e5151d9253a7f2 (plain)
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
---
title: MediaDevices.getUserMedia()
slug: Web/API/MediaDevices/getUserMedia
translation_of: Web/API/MediaDevices/getUserMedia
---
<div>{{APIRef("WebRTC")}}{{SeeCompatTable}}</div>

<p>El método <code><strong>MediaDevices.getUserMedia()</strong></code> solicita al usuario permisos para usar un dispositivo de entrada de vídeo y/o uno de audio como una cámara o compartir la pantalla y/o micrófono. Si el usuario proporciona los permisos, entonces le retornará un {{domxref("Promise")}} que es resuelto por el resultado del objeto <code><a href="/en-US/docs/WebRTC/MediaStream_API#LocalMediaStream">MediaStream</a></code>. Si el usuario niega el permiso, o si el recurso multimedia no es válido, entonces el promise es rechazado con <code>PermissionDeniedError</code> o <code>NotFoundError</code> respectivamente. Nótese que es posible que el promise retornado no sea ni resuelto ni rechazado, ya que no se requiere que el usuario tome una decisión.</p>

<h2 id="Sintaxis">Sintaxis</h2>

<pre class="syntaxbox">var <em>gumPromise</em> = <em>MediaDevices</em>.getUserMedia(<em>constraints</em>);</pre>

<p>Generalmente, accederás al objeto singleton {{domxref("MediaDevices")}} usando {{domxref("navigator.mediaDevices")}}, de esta forma:</p>

<pre><code>navigator.mediaDevices.getUserMedia(myConstraints).then(function(mediaStream) {
  /* usar el flujo de datos */
}).catch(function(err) {
  /* manejar el error */
});</code></pre>

<h3 id="Parámetros">Parámetros</h3>

<dl>
 <dt><code>constraints</code></dt>
 <dd>
 <p>Es un objeto {{domxref("MediaStreamConstraints")}} que especifica los tipos de recursos a solicitar, junto con cualquier requerimiento para cada tipo.</p>

 <p>El parámetro constraints es un objeto <code>MediaStreamConstaints</code> con dos miembros: <code>video</code> y <code>audio</code>, que describen los tipos de recurso solicitados. Debe especificarse uno o ambos. Si el navegador no puede encontrar todas las pistas de recursos con los tipos especificados que reúnan las restricciones dadas, entonces el promise retornado es rechazado con <code>NotFoundError</code>.</p>

 <p>Lo siguiente realiza la petición de tanto audio como vídeo sin requerimientos específicos:</p>

 <pre class="brush: js">{ audio: true, video: true }</pre>

 <p>Mientras que la información acerca de las cámaras y micrófonos de los usuarios se encuentran inaccesibles por razones de privacidad, una aplicación puede solicitar la cámara y las capacidades del micrófono que este requiera, usando restricciones adicionales. El siguiente código es para mosrtar una resolución de una cámara de 1280x720.</p>

 <pre class="brush: js">{
  audio: true,
  video: { width: 1280, height: 720 }
}</pre>

 <p>El navegador tratará de respetar esto, pero puede devolver otras resoluciones si una coincidencia exacta no está disponible o si el usuario la reemplaza.</p>

 <p>Para <em>conseguir </em>otras resoluciones, puede utilizar las propiedaes <code>min</code>, <code>max</code>, or <code>exact</code> (también conocido como min == max). El siguiente ejemplo le muestra cómo solicitar una resolución mínima de 1280x720.</p>

 <pre class="brush: js">{
  audio: true,
  video: {
    width: { min: 1280 },
    height: { min: 720 }
  }
}</pre>

 <p>Si no existe una cámara con una resolución mínima para trabajar, entonces la promesa devuelta será rechazada con NotFoundError, y no se le pedirá al usuario.</p>

 <p>La razón de esto es debido a que las propiedades <code>min</code>, <code>max</code>, y <code>exact </code>son inherentemente obligatorias, mientras que los valores planos y una propiedad llamada <em>ideal </em>no lo son. He aquí un ejemplo más completo:</p>

 <pre class="brush: js">{
  audio: true,
  video: {
    width: { min: 1024, ideal: 1280, max: 1920 },
    height: { min: 776, ideal: 720, max: 1080 }
  }
}</pre>

 <p>Un valor perteneciente a la propiedad <code>ideal, </code>cuando es usada, tiene gravedad, lo que significa que el navegador tratará de encontrar la configuración (una cámara, si tienes más de una), con la distancia de aptitud más pequeña (<a href="http://w3c.github.io/mediacapture-main/#methods-5">fitness distance</a>) de los valores ideales dados.</p>

 <p>Los valores planos son inherentemente ideales, lo que significa que de los ejemplos mostrados anteriormente, podrían haberse escrito de la siguiente manera:</p>

 <pre class="brush: js">{
  audio: true,
  video: {
    width: { ideal: 1280 },
    height: { ideal: 720 }
  }
}</pre>

 <p>No todas las restricciones son números. Por ejemplo, en dispositivos móviles, los siguientes preferirán la cámara frontal (si está disponible) sobre la posterior:</p>

 <pre class="brush: js">{ audio: true, video: { facingMode: "user" } }</pre>

 <p>Para <em>solicitar </em>la cámara frontal, use:</p>

 <pre class="brush: js">{ audio: true, video: { facingMode: { exact: "environment" } } }</pre>
 </dd>
</dl>

<h3 id="Valor_de_retorno">Valor de retorno</h3>

<p>Un {{jsxref("Promise")}} que resuelve a un objeto {{domxref("MediaStream")}}.</p>

<h3 id="Errores">Errores</h3>

<p>Los rechazos de la promesa devuelta se realizan con un objeto {{domxref ("MediaStreamError")}} que está modelado en {{domxref ("DOMException")}}. Los errores más relevantes son:</p>

<dl>
 <dt><code>SecurityError</code></dt>
 <dd>Permiso para usar un dispositivo fue denegado por el usuario o por el sistema.</dd>
 <dt><code>NotFoundError</code></dt>
 <dd>No se encontraron pistas multimedia del tipo especificado que satisfagan las restricciones especificadas.</dd>
</dl>

<h2 id="Ejemplos"><strong>Ejemplos</strong></h2>

<h3 id="Usando_la_Promesa_(Promise)">Usando la Promesa (Promise)</h3>

<p>Este ejemplo asigna el objeto {{domxref("MediaStream")}} al elemento apropiado.</p>

<pre>var p = navigator.mediaDevices.getUserMedia({ audio: true, video: true });

p.then(function(mediaStream) {
  var video = document.querySelector('video');
  video.src = window.URL.createObjectURL(mediaStream);
  video.onloadedmetadata = function(e) {
    // Do something with the video here.
  };
});

p.catch(function(err) { console.log(err.name); }); // always check for errors at the end.</pre>

<h3 id="Ancho_y_alto">Ancho y alto</h3>

<p>He aquí un ejemplo del uso de <code>mediaDevices.getUserMedia(), </code>incluyendo un polyfill para hacer frente a los navegadores más antiguos.</p>

<pre class="brush: js">var promisifiedOldGUM = function(constraints, successCallback, errorCallback) {

  // First get ahold of getUserMedia, if present
  var getUserMedia = (navigator.getUserMedia ||
      navigator.webkitGetUserMedia ||
      navigator.mozGetUserMedia);

  // Some browsers just don't implement it - return a rejected promise with an error
  // to keep a consistent interface
  if(!getUserMedia) {
    return Promise.reject(new Error('getUserMedia is not implemented in this browser'));
  }

  // Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
  return new Promise(function(successCallback, errorCallback) {
    getUserMedia.call(navigator, constraints, successCallback, errorCallback);
  });

}

// Older browsers might not implement mediaDevices at all, so we set an empty object first
if(navigator.mediaDevices === undefined) {
  navigator.mediaDevices = {};
}

// Some browsers partially implement mediaDevices. We can't just assign an object
// with getUserMedia as it would overwrite existing properties.
// Here, we will just add the getUserMedia property if it's missing.
if(navigator.mediaDevices.getUserMedia === undefined) {
  navigator.mediaDevices.getUserMedia = promisifiedOldGUM;
}


// Prefer camera resolution nearest to 1280x720.
var constraints = { audio: true, video: { width: 1280, height: 720 } };

navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  var video = document.querySelector('video');
  video.src = window.URL.createObjectURL(stream);
  video.onloadedmetadata = function(e) {
    video.play();
  };
})
.catch(function(err) {
  console.log(err.name + ": " + err.message);
});
</pre>

<h3 id="Cuadros_por_segundo">Cuadros por segundo</h3>

<p>Pocos frame-rates ó cuadros por segundo pueden ser deseables  en algunos casos, como transmisiones  WebRTC con restricciones de ancho de banda.</p>

<pre class="brush: js">var constraints = { video: { frameRate: { ideal: 10, max: 15 } } };
</pre>

<h3 id="Camara_frontal_y_camara_trasera">Camara frontal y camara trasera</h3>

<p>En telefonos moviles.</p>

<pre class="brush: js">var front = false;
document.getElementById('flip-button').onclick = function() { front = !front; };

var constraints = { video: { facingMode: (front? "user" : "environment") } };
</pre>

<h2 id="Permisos">Permisos</h2>

<p>Para usar <code>getUserMedia()</code> en una app instalable (por ejemplo, una <a href="/en-US/Apps/Build/Building_apps_for_Firefox_OS/Firefox_OS_app_beginners_tutorial">Firefox OS app</a>), necesitas especificar uno o ambos de los siguientes campos dentro de tu archivo manifest:</p>

<pre class="brush: js">"permissions": {
  "audio-capture": {
    "description": "Required to capture audio using getUserMedia()"
  },
  "video-capture": {
    "description": "Required to capture video using getUserMedia()"
  }
}</pre>

<p>Ver <a href="/en-US/Apps/Developing/App_permissions#audio-capture">permission: audio-capture</a> y  <a href="/en-US/Apps/Developing/App_permissions#video-capture">permission: video-capture</a> para más información.</p>

<h2 id="Especificaciones">Especificaciones</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('Media Capture', '#dom-mediadevices-getusermedia', 'MediaDevices.getUserMedia()')}}</td>
   <td>{{Spec2('Media Capture')}}</td>
   <td>Initial definition</td>
  </tr>
 </tbody>
</table>

<h2 id="Compatibilidad_con_navegadores">Compatibilidad con navegadores</h2>

<div>{{CompatibilityTable}}</div>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Firefox (Gecko)</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari (WebKit)</th>
  </tr>
  <tr>
   <td>Stream API</td>
   <td>{{CompatVersionUnknown}}<sup>[1][3]</sup><br>
    47</td>
   <td>36<sup>[2]</sup></td>
   <td>{{CompatNo}}</td>
   <td>{{CompatVersionUnknown}}<sup>[1]</sup></td>
   <td>{{CompatNo}}</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Android Webview</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Phone</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
   <th>Chrome for Android </th>
  </tr>
  <tr>
   <td>Stream API</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>36<sup>[2]</sup></td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
 </tbody>
</table>
</div>

<p>[1] Viejas versiones de Chrome y Opera implementan <code>navigator.webkitGetUserMedia</code>, la versión prefijada {{domxref("navigator.getUserMedia")}} del metodo.</p>

<p>En Chrome, esta promise-based interfaz esta unicamente disponible mediante el <a href="https://github.com/webrtc/adapter">adapter.js</a> polyfill, o usando la bandera <a>chrome://flags/#enable-experimental-web-platform-features</a>.</p>

<p>Chrome usa una sintaxis de restricciones desactualizada, pero la sintaxis descrita aquí esta disponible mediante el  <a href="https://github.com/webrtc/adapter">adapter.js</a> polyfill.</p>

<p>[2] Viejas versiones de  Firefox implementan <code>navigator.mozGetUserMedia</code>, la versión prefijada  {{domxref("navigator.getUserMedia")}} del método.</p>

<p>Esta promise-based interfaz y  la sintaxis de restricciones descrita aquí esta disponible  en Firefox 38. Versiones anteriores (32-37) usaban una sitaxis de restriciones desactualizada, pero la sintaxis descrita aquí, tanto como la promise-based interfaz, esta disponible mediante <a href="https://github.com/webrtc/adapter">adapter.js</a> polyfill.</p>

<p>Opera usa una sintaxis de restricciones desactualizada, pero la sintaxis descrita aquí esta disponible mediante <a href="https://github.com/webrtc/adapter">adapter.js</a> polyfill.</p>

<p>[3] Chrome lanza un  error si la página que sirve el script es cargada desde un origen inseguro (i.e. HTTP).</p>

<h2 id="Ver_También">Ver También</h2>

<ul>
 <li>The older <a href="/en-US/docs/Web/API/Navigator/getUserMedia">navigator.getUserMedia</a> legacy API.</li>
 <li><a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices">navigator.enumerateDevices</a> - learn the types and number of devices the user has available.</li>
 <li><a href="/en-US/docs/WebRTC">WebRTC</a> - the introductory page to the API</li>
 <li><a href="/en-US/docs/WebRTC/MediaStream_API">MediaStream API</a> - the API for the media stream objects</li>
 <li><a href="/en-US/docs/WebRTC/taking_webcam_photos">Taking webcam photos</a> - a tutorial on using <code>getUserMedia() for taking photos rather than video.</code></li>
</ul>