Registrazione video dell'utente

Bilance per tappeti

Molti browser ora hanno la possibilità di accedere all'input video e audio dell'utente. Tuttavia, a seconda del browser, potrebbe essere un'esperienza completamente dinamica e in linea oppure potrebbe essere delegata a un'altra app sul dispositivo dell'utente.

Inizia in modo semplice e progressivo

La cosa più semplice da fare è semplicemente chiedere all'utente un file preregistrato. Per farlo, crea un semplice elemento di input del file e aggiungi un filtro accept che indichi che possiamo accettare solo file video e un attributo capture che indichi che possiamo riceverli direttamente dalla videocamera.

<input type="file" accept="video/*" capture />

Questo metodo funziona su tutte le piattaforme. Su computer, all'utente verrà chiesto di caricare un file dal file system (senza l'attributo capture). In Safari su iOS si apre l'app Fotocamera, che permette di registrare il video e di inviarlo alla pagina web; su Android l'utente può scegliere l'app in cui registrare il video prima di inviarlo alla pagina web.

Molti dispositivi mobili sono dotati di più fotocamere. Se hai una preferenza, puoi impostare l'attributo capture su user se vuoi che la videocamera sia rivolta verso l'utente o su environment se vuoi che la videocamera sia rivolta verso l'esterno.

<input type="file" accept="video/*" capture="user" />
<input type="file" accept="video/*" capture="environment" />

Tieni presente che questo è solo un suggerimento: se il browser non supporta l'opzione o se il tipo di videocamera richiesto non è disponibile, il browser potrebbe scegliere un'altra videocamera.

Quando l'utente ha finito di registrare e torna sul sito web, devi recuperare in qualche modo i dati del file. Puoi accedere rapidamente associando un evento onchange all'elemento di input e poi 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 fare tutto ciò che vuoi. Ad esempio, puoi:

  • Collegalo direttamente a un elemento <video> per riprodurlo
  • Scaricalo sul dispositivo dell'utente
  • Caricalo su un server collegandolo a un XMLHttpRequest
  • Disegna i frame e applica i filtri

Sebbene il metodo basato sugli elementi di input per accedere ai dati video sia onnipresente, è l'opzione meno accattivante. Vogliamo avere accesso alla fotocamera e offrire un'esperienza positiva direttamente dalla pagina.

Accedi alla videocamera in modo interattivo

I browser moderni possono avere una linea diretta con la fotocamera consentendoci di creare esperienze completamente integrate con la pagina web e l'utente non lascerà mai il browser.

Ottenere l'accesso alla fotocamera

Possiamo accedere direttamente alla videocamera utilizzando un'API nella specifica WebRTC denominata getUserMedia(). getUserMedia() chiederà all'utente di accedere ai microfoni e alle videocamere connessi.

Se l'operazione ha esito positivo, l'API restituisce un Stream che contiene i dati della videocamera o del microfono. In seguito, possiamo associarlo a un elemento <video>, collegarlo a uno stream WebRTC o salvarlo utilizzando l'API MediaRecorder.

Per ottenere i dati dalla fotocamera, è sufficiente impostare video: true nell'oggetto di vincoli che viene 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, prima puoi enumerare le videocamere disponibili.

navigator.mediaDevices.enumerateDevices().then((devices) => {
  devices = devices.filter((d) => d.kind === 'videoinput');
});

Puoi quindi passare l'ID dispositivo che vuoi utilizzare quando chiami getUserMedia.

navigator.mediaDevices.getUserMedia({
  audio: true,
  video: {
    deviceId: devices[0].deviceId,
  },
});

Di per sé, questo non è molto utile. Tutto ciò che possiamo fare è recuperare i dati del video.

Accesso ai dati non elaborati dalla fotocamera

Per accedere ai dati video non elaborati dalla fotocamera, puoi disegnare ogni fotogramma in una <canvas> e manipolare direttamente i pixel.

Per un canvas 2D, puoi utilizzare il metodo drawImage del contesto per disegnare il frame corrente di un elemento <video> nel canvas.

context.drawImage(myVideoElement, 0, 0);

Con una tela WebGL puoi utilizzare un elemento <video> come origine di 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ù frame, devi disegnare ogni volta il video nella tela.

Per saperne di più, consulta il nostro articolo sull'applicazione di effetti in tempo reale a immagini e video.

Salvare i dati dalla fotocamera

Il modo più semplice per salvare i dati della videocamera è utilizzare l'API MediaRecorder.

L'API MediaRecorder acquisirà il flusso creato da getUserMedia e salverà progressivamente i dati del flusso 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, i dati vengono salvati direttamente in un array che possiamo poi convertire in un Blob, che può essere utilizzato per salvare i dati sul nostro server web o direttamente nello spazio di archiviazione sul dispositivo dell'utente.

Chiedi l'autorizzazione per usare la fotocamera in modo responsabile

Se l'utente non ha precedentemente concesso al tuo sito l'accesso alla fotocamera, nell'istante in cui chiami getUserMedia, il browser gli chiederà di concedere alla fotocamera l'autorizzazione di accesso al tuo sito.

Gli utenti detestano la richiesta di accedere a dispositivi potenti sul proprio computer e spesso la bloccheranno oppure la ignorano se non comprendono il contesto in cui è stata creata. È buona norma chiedere l'accesso alla videocamera solo se necessario. Una volta che l'utente concede l'accesso, non gli verrà più chiesto di farlo. Tuttavia, se l'utente rifiuta l'accesso, non potrai ottenere di nuovo l'accesso per chiedere l'autorizzazione all'utente.

Utilizza l'API Permissions per verificare se hai già l'accesso

L'API getUserMedia ti consente di sapere se hai già accesso alla fotocamera. Questo presenta un problema: per fornire all'utente una bella interfaccia utente e convincerlo a concederti l'accesso alla fotocamera, devi richiederne l'accesso.

Questo problema può essere risolto in alcuni browser utilizzando l'API Permission. L'API navigator.permission ti consente di eseguire query sullo stato della possibilità di accedere ad API specifiche senza dover ripetere la richiesta.

Per eseguire una query se hai accesso alla fotocamera dell'utente, puoi passare {name: 'camera'} al metodo di query, che restituirà:

  • granted: l'utente ti ha precedentemente concesso l'accesso alla fotocamera;
  • prompt: l'utente non ti ha concesso l'accesso e verrà visualizzato un messaggio quando chiamerai il numero getUserMedia.
  • denied: il sistema o l'utente ha bloccato esplicitamente l'accesso alla videocamera e non potrai accedervi.

Inoltre, ora puoi controllare rapidamente se devi modificare l'interfaccia utente per adattarla alle azioni che deve eseguire.

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 () {};
});

Feedback