8. Acceso al dispositivo

Versión para imprimir.

A. Introduccion

B. Geolocalización

Salida

Ábrelo en otra pestaña.

Revísalo en gilpgedit.

1
<!DOCTYPE html>
2
<html lang="es">
3

    
4
<head>
5

    
6
 <meta charset="UTF-8">
7
 <meta name="viewport"
8
   content="width=device-width">
9

    
10
 <title>GPS</title>
11

    
12
 <style>
13
  html {
14
   color-scheme: light dark;
15
  }
16
 </style>
17

    
18
</head>
19

    
20
<body>
21

    
22
 <h1>GPS</h1>
23

    
24
 <p>
25
  <label>
26
   Latitud
27
   <output id="latitud"></output>
28
  </label>
29
 </p>
30

    
31
 <p>
32
  <label>
33
   Longitud
34
   <output id="longitud"></output>
35
  </label>
36
 </p>
37

    
38
 <script>
39

    
40
  navigator.geolocation.
41
   watchPosition(p => {
42

    
43
    latitud.value =
44
     p.coords.latitude
45

    
46
    longitud.value =
47
     p.coords.longitude
48

    
49
   });
50

    
51
 </script>
52

    
53
</body>
54

    
55
</html>

C. Archivos y cámara

Salida

Ábrelo en otra pestaña.

Revísalo en gilpgedit.

Observa como funciona en Android.

Observa como funciona en iOS.

1
<!DOCTYPE html>
2
<html lang="es">
3

    
4
<head>
5

    
6
 <meta charset="UTF-8">
7
 <meta name="viewport"
8
   content="width=device-width">
9

    
10
 <title>Archivos y Cámara</title>
11

    
12
 <style>
13
  html {
14
   color-scheme: light dark;
15
  }
16
 </style>
17

    
18
</head>
19

    
20
<body>
21

    
22
 <h1>Archivos y Cámara</h1>
23

    
24
 <p>
25
  <label>
26
   Foto de Móvil
27
   <input type="file"
28
     accept="image/*"
29
     capture="camera">
30
  </label>
31
 </p>
32

    
33
 <p>
34
  <label>
35
   Video de Móvil
36
   <input type="file"
37
     accept="video/*"
38
     capture="">
39
  </label>
40
 </p>
41

    
42
 <p>
43
  <label>
44
   Archivo
45
   <input type="file">
46
  </label>
47
 </p>
48

    
49
</body>
50

    
51
</html>

D. Uso directo de la cámara

Salida

Ábrelo en otra pestaña.

Revísalo en gilpgedit.

1
<!DOCTYPE html>
2
<html>
3

    
4
<head>
5

    
6
 <meta charset="utf-8">
7
 <meta name="viewport"
8
   content="width=device-width">
9

    
10
 <title>Cámara</title>
11

    
12
 <style>
13
  html {
14
   color-scheme: light dark;
15
  }
16
 </style>
17

    
18
</head>
19

    
20
<body>
21

    
22
 <h1>Cámara</h1>
23

    
24
 <p>
25
  Para grabar o capturar imagen,
26
  cliquea
27
  <strong>Inicia</strong>.
28
 </p>
29

    
30
 <p>
31
  Para grabar por 5 segundos
32
  cliquea
33
  <strong>Graba</strong>
34
  y cliquea
35
  <strong>Para</strong> para
36
  detener.
37
 </p>
38

    
39
 <p>
40
  Para capturar una imagen de la
41
  cámara, cliquea
42
  <strong>Captura</strong>.
43
 </p>
44

    
45
 <menu style="display: flex;
46
   flex-wrap: wrap;
47
   list-style: none;">
48
  <li>
49
   <button type="button"
50
     onclick="inicia()">
51
    Inicia
52
   </button>
53
  </li>
54
  <li>
55
   <button type="button"
56
     onclick="graba()">
57
    Graba
58
   </button>
59
  </li>
60
  <li>
61
   <button type="button"
62
     onclick="para();">
63
    Para
64
   </button>
65
  </li>
66
  <li>
67
   <button type="button"
68
     onclick="captura()">
69
    Captura
70
   </button>
71
  </li>
72
 </menu>
73

    
74
 <section
75
   style="display: inline-block;
76
     vertical-align: top;">
77

    
78
  <h1>Preview</h1>
79

    
80
  <video id="preview" width="160"
81
    height="120" autoplay
82
    muted></video>
83

    
84
 </section>
85

    
86
 <section
87
   style="display: inline-block;
88
     vertical-align: top;">
89

    
90
  <h1>Recording</h1>
91

    
92
  <video id="recording" width="160"
93
    height="120" controls></video>
94

    
95
  <p>
96
   <a id="descarga">Descarga</a>
97
  </p>
98

    
99
  <div id="mensajes"></div>
100

    
101
 </section>
102

    
103
 <section
104
   style="display: inline-block;
105
     vertical-align: top;">
106

    
107
  <h1>Imagen</h1>
108

    
109
  <canvas id="canvas" width="160"
110
    height="120"></canvas>
111

    
112
  <p>
113
   <a id="descargaImagen">
114
    Descarga</a>
115
  </p>
116

    
117
 </section>
118

    
119
 <script>
120

    
121
  let stream = null
122

    
123
  let TIEMPO_DE_GRABACION = 5000
124

    
125
  var context =
126
   canvas.getContext('2d')
127

    
128
  async function inicia() {
129
   try {
130
    stream = await navigator
131
     .mediaDevices.getUserMedia({
132
      video: true,
133
      audio: true
134
     })
135
    preview.srcObject = stream
136
    descarga.href = stream
137
    preview.captureStream =
138
     preview.captureStream
139
     || preview.mozCaptureStream
140
    await new Promise(
141
     resolve =>
142
      preview.onplaying = resolve)
143
   } catch (e) {
144
    log(e.message)
145
   }
146
  }
147

    
148
  async function graba() {
149
   try {
150
    const recordedChunks =
151
     await grabaClip(stream,
152
      TIEMPO_DE_GRABACION)
153
    let recordedBlob = new Blob(
154
     recordedChunks,
155
     { type: "video/webm" })
156
    recording.src =
157
     URL.createObjectURL(
158
      recordedBlob)
159
    descarga.href = recording.src
160
    descarga.download =
161
     "RecordedVideo.webm"
162

    
163
    log("Exitosamente grabados "
164
     + recordedBlob.size
165
     + " bytes de "
166
     + recordedBlob.type
167
     + " media.")
168
   } catch (e) {
169
    log(e.message)
170
   }
171
  }
172

    
173
  function para() {
174
   detiene(preview.srcObject)
175
  }
176

    
177
  function captura() {
178
   context.drawImage(preview,
179
    0, 0, 160, 120)
180
   descargaImagen.href =
181
    canvas.toDataURL('image/jpeg')
182
   descargaImagen.download =
183
    "imagen.jpg"
184
  }
185

    
186
  function grabaClip(stream,
187
   milisegundos) {
188
   let recorder =
189
    new MediaRecorder(stream)
190
   let data = []
191
   recorder.ondataavailable =
192
    event => data.push(event.data)
193
   recorder.start()
194
   log(recorder.state
195
    + " durante "
196
    + (milisegundos / 1000)
197
    + " segundos…")
198
   let detenido = new Promise(
199
    (resolve, reject) => {
200
     recorder.onstop = resolve
201
     recorder.onerror =
202
      event => reject(event.name)
203
    })
204
   let grabado =
205
    espera(milisegundos)
206
     .then(() => recorder.state
207
      === "recording"
208
      && recorder.stop()
209
     )
210

    
211
   return Promise.all([
212
    detenido,
213
    grabado
214
   ])
215
    .then(() => data)
216
  }
217

    
218
  function detiene(stream) {
219
   stream.getTracks().forEach(
220
    track => track.stop())
221
  }
222

    
223
  function log(msg) {
224
   mensajes.innerHTML +=
225
    msg + "<br>"
226
  }
227

    
228
  function espera(milisegundos) {
229
   return new Promise(
230
    resolve => setTimeout(
231
     resolve, milisegundos))
232
  }
233

    
234
 </script>
235

    
236
</body>
237

    
238
</html>

E. Resumen