Transmissão ao vivo de webcam em fluxo de webcam (usando getUserMedia) gravando pedaços com MediaRecorder sobre API WEB com WebSockets e MediaSource

Estou tentando transmitir o vídeo de uma webcam para outros clientes em tempo real, mas encontro alguns problemas quando o espectador começa a assistir no meio.

Para esse fim, recebo o fluxo da webcam usando getUserMedia (e todos os seus irmãos).

Em seguida, com um clique no botão, começo a gravar o fluxo e envio cada segmento / bloco / o que você chamar para o back-end do emissor da Web:

var mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start(1000);
mediaRecorder.ondataavailable = function (event) {
    uploadVideoSegment(event); //wrap with a blob and call socket.send(...)
}

No lado do servidor (Web API, usando Microsoft.Web.WebSockets), recebo o byte [] como está perfeitamente.

Em seguida, envio o byte [] para os visualizadores que estão atualmente conectados ao Broadcaster, leio-o no evento onmessage do soquete usando um FileReader e anexo o Uint8Array ao sourceBuffer do MediaSource, que é o src do elemento de vídeo HTML5.

Quando os visualizadores obtêm o byte [] desde o início, especificamente, os primeiros 126 bytes que começam com o EBMLHeader (0x1A45DFA3) e terminam com o início do cluster (0x1F43B675) e, em seguida, com toda a mídia - está sendo reproduzido corretamente.

O problema ocorre quando um novo visualizador se junta ao meio e busca o segundo pedaço e depois.

Eu tenho tentado pesquisar e sujar as mãos um pouco de várias maneiras. Entendo que o cabeçalho é essencial (http://www.slideshare.net/mganeko/media-recorder-and-webm), que existem algumas coisas relacionadas a quadros-chave e todas essas coisas, mas fiquei confuso muito rapidamente.

Até agora, tentei escrever meu próprio analisador de webm simples em c # (a partir de uma referência do projeto node.js no github -https://github.com/mganeko/wmls) Assim, dividi o cabeçalho do primeiro pedaço, o armazenei em cache e tentei enviá-lo com cada pedaço posteriormente. Claro que não funcionou.

Eu acho que talvez o MediaRecorder esteja dividindo o cluster no meio enquanto o evento ondataavailable é acionado (isso porque notei que o início do segundo bloco não começa com o cabeçalho do cluster).

Nesse ponto, fiquei preso sem saber como usar o analisador para fazê-lo funcionar.

Depois, li sobre o uso do ffmpeg para converter o fluxo de webm s.t cada quadro também é um quadro-chave -Codificação de FFMPEG para MPEG-DASH - ou WebM com clusters de quadro-chave - para API MediaSource (na resposta de Chris Nolet).

Tentei usar o FFMpegConverter (para .Net) usando:

var conv = new FFMpegConverter();
var outputStream = new MemoryStream();

var liveMedia = conv.ConvertLiveMedia("webm", outputStream, "webm", new ConvertSettings { VideoCodec = "vp8", CustomOutputArgs = "-g 1" });
liveMedia.Start();
liveMedia.Write(vs.RawByteArr, 0, vs.RawByteArr.Length); //vs.RawByteArr is the byte[] I got from the MediaRecorder
liveMedia.Stop();

byte[] buf = new byte[outputStream.Length];
outputStream.Position = 0;
outputStream.Read(buf, 0, (int)outputStream.Length);

Eu não estou familiarizado com o FFMPEG, então provavelmente não estou obtendo os parâmetros corretamente, embora na resposta tenha sido o que eu vi, mas eles escreveram muito em breve.

É claro que encontrei aqui muitos problemas: Ao usar os websockets, a execução do FFMpegConverter simplesmente forçou o fechamento do canal dos websockets. (Ficarei feliz se alguém puder explicar o porquê).

Eu não desisti, escrevi tudo sem websockets usando os métodos HttpGet (para buscar o segmento do servidor) e HttpPost (com blobs de várias partes e todo o pessoal subseqüente para postar os pedaços gravados) e tentei usar o FFMpegConverter como mencionado acima.

Para o primeiro segmento, ele funcionou, mas produziu um byte [] com metade do comprimento do original (ficarei feliz se alguém puder explicar isso também) e, para os outros blocos, houve uma exceção (todas as vezes que não apenas uma vez) dizendo que o tubo foi encerrado.

Eu estou me perdendo.

Por favor me ajude, qualquer um. As 4 perguntas principais são:

Como posso reproduzir os pedaços que seguem o primeiro pedaço do MediaRecorder? (Enquanto isso, acabo de disparar os eventos de fechamento / fim do sourcebuffer e o sourceBuffer é desanexado do objeto MediaSource pai (causando uma exceção como "o sourceBuffer foi removido do pai") devido ao fato de o byte [] ter passado para não é bom - talvez eu não esteja usando o analisador de webm que escrevi da maneira correta para detectar partes importantes no segundo pedaço (que por sinal não começa com um cluster) e por isso escrevi que parece que o MediaRecorder está cortando o cluster no meio))

Por que o FFMpeg faz com que os WebSockets sejam fechados?

Estou usando o FFMpegConverter.ConvertLiveMedia com os parâmetros corretos para obter um novo segmento de webm com todas as informações necessárias para obtê-lo como um pedaço autônomo, sem depender dos pedaços anteriores (como Chris Nolet disse em sua resposta em o link SO acima)?

Por que o FFMpegConverter lança a exceção "the pipe ended"?

Qualquer ajuda será extremamente apreciada.

questionAnswers(0)

yourAnswerToTheQuestion