Molti browser ora hanno la possibilità di accedere all'input video e audio dell'utente. Tuttavia, a seconda del browser, potrebbe trattarsi di un'esperienza dinamica e in linea completa o potrebbe essere delegata a un'altra app sul dispositivo dell'utente.
Inizia in modo semplice e graduale
Il modo più semplice è chiedere all'utente un file preregistrato. A tal fine, crea un semplice elemento di input file e aggiungi un filtro accept
che indichi che puoi accettare solo file video e un attributo capture
che indichi che vuoi recuperarli direttamente dalla videocamera.
<input type="file" accept="video/*" capture />
Questo metodo funziona su tutte le piattaforme. Sul computer, all'utente verrà chiesto di caricare un file dal
file system (ignorando l'attributo capture
). In Safari su iOS si aprirà l'app Fotocamera, che ti consentirà di registrare il video e poi di inviarlo di nuovo alla pagina web. Su Android, l'utente potrà scegliere l'app con cui registrare il video prima di inviarlo di nuovo alla pagina web.
Molti dispositivi mobili hanno più di una fotocamera. Se hai una preferenza, puoi impostare l'attributo capture
su user
se vuoi che la fotocamera sia rivolta verso l'utente o su environment
se vuoi che sia rivolta verso l'esterno.
<input type="file" accept="video/*" capture="user" />
<input type="file" accept="video/*" capture="environment" />
Tieni presente che si tratta solo di un suggerimento: se il browser non supporta l'opzione o il tipo di videocamera richiesto non è disponibile, il browser potrebbe scegliere un'altra videocamera.
Una volta che l'utente ha completato la registrazione ed è tornato sul sito web, devi recuperare in qualche modo i dati del file. Puoi accedere rapidamente collegando un evento onchange
all'elemento di input e leggendo la proprietà files
dell'oggetto evento.
<input type="file" accept="video/*" capture="camera" id="recorder" />
<video id="player" controls></video>
<script>
var recorder = document.getElementById('recorder');
var player = document.getElementById('player');
recorder.addEventListener('change', function (e) {
var file = e.target.files[0];
// Do something with the video file.
player.src = URL.createObjectURL(file);
});
</script>
Una volta ottenuto l'accesso al file, puoi utilizzarlo come preferisci. Ad esempio, puoi:
- Collegalo direttamente a un elemento
<video>
per poterlo riprodurre - Scaricalo sul dispositivo dell'utente
- Caricalo su un server collegandoti a un
XMLHttpRequest
- Disegna i frame in una tela e applica filtri
Sebbene l'utilizzo del metodo dell'elemento input per accedere ai dati dei video sia molto diffuso, è l'opzione meno interessante. Vogliamo davvero accedere alla fotocamera e offrire un'esperienza piacevole direttamente nella pagina.
Accedere alla fotocamera in modo interattivo
I browser moderni possono avere un canale diretto con la fotocamera, il che ci consente di creare esperienze completamente integrate con la pagina web e l'utente non dovrà mai uscire dal browser.
Ottenere l'accesso alla fotocamera
Possiamo accedere direttamente alla videocamera utilizzando un'API nella specifica WebRTC chiamata getUserMedia()
. getUserMedia()
chiederà all'utente di accedere ai microfoni e alle videocamere collegati.
In caso di esito positivo, l'API restituirà un Stream
contenente i dati della videocamera o del microfono, che potremo poi collegare a un elemento <video>
, a uno stream WebRTC o salvarlo utilizzando l'API MediaRecorder
.
Per ottenere i dati dalla videocamera, è sufficiente impostare video: true
nell'oggetto vincoli passato all'API getUserMedia()
<video id="player" controls></video>
<script>
var player = document.getElementById('player');
var handleSuccess = function (stream) {
player.srcObject = stream;
};
navigator.mediaDevices
.getUserMedia({audio: true, video: true})
.then(handleSuccess);
</script>
Se vuoi scegliere una videocamera specifica, puoi prima elencare le videocamere disponibili.
navigator.mediaDevices.enumerateDevices().then((devices) => {
devices = devices.filter((d) => d.kind === 'videoinput');
});
Puoi quindi passare il deviceId che vuoi utilizzare quando chiami getUserMedia
.
navigator.mediaDevices.getUserMedia({
audio: true,
video: {
deviceId: devices[0].deviceId,
},
});
Da solo, non è molto utile. Tutto ciò che possiamo fare è acquisire i dati video e riprodurli.
Accedere ai dati non elaborati della videocamera
Per accedere ai dati video non elaborati della videocamera, puoi disegnare ogni fotogramma in un <canvas>
e manipulare direttamente i pixel.
Per una tela 2D, puoi utilizzare il metodo drawImage
del contesto per disegnare il frame corrente di un elemento <video>
nella tela.
context.drawImage(myVideoElement, 0, 0);
Con una tela WebGL puoi utilizzare un elemento <video>
come origine per una texture.
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
gl.RGBA,
gl.UNSIGNED_BYTE,
myVideoElement,
);
Tieni presente che in entrambi i casi verrà utilizzato il fotogramma corrente di un video in riproduzione. Per elaborare più fotogrammi, devi ridisegnare ogni volta il video sulla tela.
Scopri di più in questo articolo sull'applicazione di effetti in tempo reale a immagini e video.
Salvare i dati della videocamera
Il modo più semplice per salvare i dati della videocamera è utilizzare l'API
MediaRecorder
.
L'API MediaRecorder
acquisirà lo stream creato da getUserMedia
e poi salverà progressivamente i dati dello stream nella destinazione che preferisci.
<a id="download">Download</a>
<button id="stop">Stop</button>
<script>
let shouldStop = false;
let stopped = false;
const downloadLink = document.getElementById('download');
const stopButton = document.getElementById('stop');
stopButton.addEventListener('click', function() {
shouldStop = true;
})
var handleSuccess = function(stream) {
const options = {mimeType: 'video/webm'};
const recordedChunks = [];
const mediaRecorder = new MediaRecorder(stream, options);
mediaRecorder.addEventListener('dataavailable', function(e) {
if (e.data.size > 0) {
recordedChunks.push(e.data);
}
if(shouldStop === true && stopped === false) {
mediaRecorder.stop();
stopped = true;
}
});
mediaRecorder.addEventListener('stop', function() {
downloadLink.href = URL.createObjectURL(new Blob(recordedChunks));
downloadLink.download = 'acetest.webm';
});
mediaRecorder.start();
};
navigator.mediaDevices.getUserMedia({ audio: true, video: true })
.then(handleSuccess);
</script>
Nel nostro caso, salviamo i dati direttamente in un array che in un secondo momento possiamo trasformare in un Blob
, che può essere utilizzato per salvare i dati sul nostro server web o direttamente nello spazio di archiviazione del dispositivo dell'utente.
Chiedere l'autorizzazione per utilizzare la videocamera in modo responsabile
Se l'utente non ha mai concesso al tuo sito l'accesso alla videocamera,
nel momento in cui chiami getUserMedia
il browser chiederà all'utente di
concedere al tuo sito l'autorizzazione per la videocamera.
Gli utenti detestano che venga chiesto loro di accedere a dispositivi potenti sulla propria macchina e spesso bloccano la richiesta o la ignorano se non comprendono il contesto in cui è stata creata. È buona prassi chiedere di accedere alla videocamera solo quando è necessario. Una volta che l'utente ha concesso l'accesso, non gli verrà chiesto di nuovo, ma se rifiuta l'accesso, non potrai più accedere per chiedere all'utente l'autorizzazione.
Utilizza l'API Permissions per verificare se disponi già dell'accesso
L'API getUserMedia
non ti fornisce alcuna informazione su se hai già accesso alla videocamera. Questo presenta un problema: per fornire un'interfaccia utente piacevole e convincere l'utente a concederti l'accesso alla fotocamera, devi chiedere l'accesso alla fotocamera.
Questo problema può essere risolto in alcuni browser utilizzando l'API Permission. L'API
navigator.permission
consente di eseguire query sullo stato della possibilità di
accedere ad API specifiche senza dover richiedere nuovamente l'autorizzazione.
Per verificare se hai accesso alla videocamera dell'utente, puoi passare {name: 'camera'}
al metodo di query, che restituirà:
granted
: l'utente ti ha già concesso l'accesso alla fotocamera.prompt
: l'utente non ti ha concesso l'accesso e gli verrà chiesto di farlo quando chiameraigetUserMedia
.denied
: il sistema o l'utente ha bloccato esplicitamente l'accesso alla videocamera e non potrai accedervi.
Ora puoi verificare rapidamente se devi modificare l'interfaccia utente per adattarla alle azioni che l'utente deve intraprendere.
navigator.permissions.query({name: 'camera'}).then(function (result) {
if (result.state == 'granted') {
} else if (result.state == 'prompt') {
} else if (result.state == 'denied') {
}
result.onchange = function () {};
});