Executando verificação de segurança...
10

[PITCH] Um gravador de tela (mas no navegador)

Um gravador de tela e no navegador? Bom, a ideia foi explorar não só a API de Screen Capture como também uma API experimental para gerenciamento de arquivos, a API de File System, onde é possível ter um acesso bem mais "nativo" sobre arquivos, e sem a limitação de tamanho de arquivos, diferente de outras APIs. E com isso eu tive a ideia de criar um gravador de tela "aprimorado" mas simples para navegadores, onde também é possível gravar a tela inteira com o áudio.

Experimente: Screen Recorder

Carregando publicação patrocinada...
3

Valeu por compartilhar a ideia! Para mim funcionou bem! Logo após escolhermos o local onde o arquivo webm será salvo, a interface no navegador lembra bastante a carinha do Google Meet no instante em que fazemos a escolha do que será exibido durante a apresentação. No caso aqui, qual janela será gravada ou a tela toda (incluindo o áudio, se desejar).


Algo que notei aqui: O processo rodando no Google Chrome consume boa parte do processamento do PC. Saberia se existe alguma otimização que pode ser ativada no navegador ou no código que compartilhou de maneira que limite o número de frames capturados por segundo? Acho que com isso restrinjo um pouco do processamento :). No mais, muito boa ideia!!

Código original

    <script>
      async function record() {
        const handle = await window.showSaveFilePicker({ startIn: "videos", types: [{ accept: { "video/webm": ".webm" } }] })
        const writable = await handle.createWritable()
        const stream = await navigator.mediaDevices.getDisplayMedia({ audio: true, video: true })
        const recorder = new MediaRecorder(stream, { mimeType: "video/webm" })
        recorder.ondataavailable = async ({ data }) => await writable.write(data)
        recorder.onstop = async () => await writable.close()
        recorder.start()
      }
    </script>

Fonte: https://github.com/d3tu/reco/blob/main/index.html

Tentei futucar o código fonte que disponibilizou para alterar alguma propriedade framerate do objeto MediaRecorder. Até achei uma discussão aqui https://github.com/w3c/mediacapture-record/issues/177, recorri à documentação em https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/MediaRecorder e https://www.w3.org/TR/mediastream-recording, mas ainda não consegui mudar o intervalo de captura, só a qualidade do vídeo e áudio.

Código modificado

    <script>
      async function record() {
        const showSaveFilePickerOptions = {
          startIn: "videos",
          types: [{ accept: { "video/webm": ".webm" } }]
        };
        const getDisplayMediaOptions = {
           audio: true,
           video: true
        };
        const mediaRecorderOptions = {
          audioBitsPerSecond: 128000/8,
          videoBitsPerSecond: 2500000/8,
          mimeType: "video/webm"
        };
        const handle = await window.showSaveFilePicker(showSaveFilePickerOptions)
        const writable = await handle.createWritable()
        const stream = await navigator.mediaDevices.getDisplayMedia(getDisplayMediaOptions)
        const recorder = new MediaRecorder(stream, mediaRecorderOptions)
        recorder.ondataavailable = async ({ data }) => await writable.write(data)
        recorder.onstop = async () => await writable.close()
        recorder.start()
      }
    </script>

Adaptado de: https://github.com/d3tu/reco/blob/main/index.html

1

Valeu pela cooperação! Realmente ainda tem muita coisa pra se fazer, começei com uma base inicial, para se caso alguém tivesse idéias pudessem dar ideias, como a sua. Além do suporte a arquivos WEBMs seria legal implementar também um suporte para arquivos MP4, que até então não foi possível por causa da API Media Recorder não suportar.

Como você disse ter notado uma grande quantidade de processamento sendo gasta, isso também deve ter relação a grande quantidade de dados sendo processadas em recorder.ondataavailable = async ({ data }) => await writable.write(data), então talvez se usasse algo para reduzir esse processo, talvez aumentando o buffer, pudesse resolver.

Também seria interessante ter mais opções, como gravar a câmera, opções de salvamento, algo para pausar e continuar a gravação, bem como escolher a quantidade de frames, qualidade e outros. E claro, melhorar a interface. 😅

1

Mais um update! Refiz a interface e adicionei novas funções. Sobre o suporte ao MP4 (mas não adicionado, ainda?) eu fiz uma pesquisa e achei interessante o uso do ffmpeg.wasm, que é o FFmpeg portado para WebAssembly, onde poderia dar suporte a várias novas funcionalidades. Inclusive me inspirei um pouco no programa OBS Studio. ;)

2

deto, agradeço seus novos comentários e por tão breve atuar em seu código, dando a ele novas funcionalidades. Logo que vi na documentação da API a possibilidade de salvar em MP4, alterei seu código para ver se talvez ganhasse um pouco mais de desempenho na questão uso de recursos. Não funcionou, apesar de estar na documentação da API. Devo ter feito alguma coisa errada e foi bom ler seu comentário a respeito do ffmpeg.wasm.

É bem provável que sua ideia de utilizar o módulo em WASM para fazer o trabalho mais pesado proporcione mais eficiência. Não testei e fiquei curioso para saber se o desempenho será melhor que o proporcionado pela API nativa do navegador.

Aproveito para comentar algo a respeito do que deixou no comentário anterior. Em uma das discussões que encontrei em fórums, antigos, havia o pedido de incorporarem à API opções de pausa/continuar e você já conseguiu explorá-los na sua nova UI. Ficou jóia!

No que se refere ao ondataavailable foi algo que também notei que poderia agir, pois no comentário que li também em fórums, isso gera bastante dado para o processamento lidar. Como a publicação também era antiga, comentavam inclusive da perda de alguns frames.

Ah, agradeço por citar o OBS Studio! Eu lia comentários, ouvia falarem a respeito, mas nunca dei atenção à essa ferramenta que também é opensource!