Как получить непрерывный фрагмент видео в виде массива BLOB-объектов и динамически установить тег видео в Websocket - PullRequest
0 голосов
/ 29 июня 2018

Я пытаюсь создать свою собственную архитектуру вещания. В этой системе я использую Websocket для передачи данных, так как я знаю, это подходит для непрерывной передачи данных.


В моей системе есть Хост , который запускает прямую трансляцию видео с веб-камеры. Я использую MediaStreamRecorder.js , который записывает каждые 5 секунд видео и отправляет на сервер через websocket как массив BLOB-объектов.

Сервер просто получает и отправляет всем клиентам, которые подключены в этом сеансе.

Когда клиент подключен, он получает непрерывный 5-секундный фрагмент видео в виде массива BLOB-объектов через Websocket.

Моя основная проблема на стороне клиента: как я могу установить для массива видеоблока значение html video источник динамически каждые 5 секунд, чтобы он мог воспроизводить каждые 5 секунд видеоданные.

Я использую Glassfish 4.0 в качестве сервера и Javscript на стороне хоста и клиента. Браузер: Chrome Исходный код:

ServerBroadCast.java

    package websocket1;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/liveStreamMulticast")
public class LiveStreamMultiCast {
    private static final Set<Session> sessions = Collections.synchronizedSet(new HashSet<Session>());

    @OnOpen
    public void whenOpening(Session session) {
        // session.setMaxBinaryMessageBufferSize(1024*512); // 512 KB
        sessions.add(session);
        System.out.println("You are Connected!");
        System.out.println("Total Connection are connected: " + sessions.size());

    }

    @OnMessage
    public void handleVideo(byte[] videoData, Session HostSession) {
        // System.out.println("Insite process video");

        try {
            if (videoData != null) {
                sendVideo(videoData, HostSession);
            }

        } catch (Throwable e) {
            System.out.println("Error sending message " + e.getMessage());
        }
    }


    @OnClose
    public void onClosing(Session session) {
        System.out.println("Goodbye!");
        sessions.remove(session);
    }

    private void sendVideo(byte[] videoData, Session hostSession) throws IOException {

        Iterator<Session> iterator = sessions.iterator();
        Session tempSession = null;

        while (iterator.hasNext()) {
            tempSession = iterator.next();

            // System.out.println("Sever send data to "+ tempSession);
            if (!tempSession.equals(hostSession))
                tempSession.getBasicRemote().sendBinary(ByteBuffer.wrap(videoData));

        }

    }
}

host.html

<html>
<head>
    <title>Demo</title>
    <script type="text/javascript" src="js/required/mediastream.js"></script>
</head>
<body>

<video id="video" autoplay=""></video>

<button id="stopButton" onclick="stop()">Stop</button>
<script type="text/javascript">

var url = "ws://localhost:8080/LiveTraining3Demo/liveStreamMulticast"; // 8080/application_name/value_given_in_annotation

var socket = new WebSocket(url);
    var video = document.querySelector('video');

socket.onopen = function(){

    console.log("Connected to Server!!");

}
socket.onmessage = function(msg){
    console.log("Message come from server");

}
/////////////////////////////////
var wholeVideo =[];
var chunks = [];
var mediaRecorder;
//////////////////////////////////////

  function gotMedia(stream) {
    video.srcObject = stream;
    mediaRecorder = new MediaStreamRecorder(stream);
    console.log("mediaRecorderCalled");
    mediaRecorder.mimeType = 'video/webm';
    mediaRecorder.start(5000);//
    console.log("recorder started");

    mediaRecorder.ondataavailable = (event) =>{
        chunks.push(event.data);
        console.log("push  B");
        wholeVideo.push(event.data);
        console.log("WholeVideo Size:");
        setTimeout(sendData(),5010);
    }



  }


  function sendData(){ 
    //var byteArray = new Uint8Array(recordedTemp);
    const superBuffer =  new Blob(chunks, {
        type: 'video/webm'
        });

     socket.send(superBuffer);
     console.log("Send Data");
      console.table(superBuffer);
      chunks = [];

  }


  navigator.getUserMedia  = navigator.getUserMedia || 
                                     navigator.webkitGetUserMedia ||
                                      navigator.mozGetUserMedia || 
                                       navigator.msGetUserMedia;

  navigator.mediaDevices.getUserMedia({video: true , audio: true})
      .then(gotMedia)
      .catch(e => { console.error('getUserMedia() failed: ' + e); });
    </script>

</body>
</html>

client.html

<html>
<head>

<title>Recieve Video</title>

</head>
<body>
<video id="video" autoplay controls loop
    style="width: 700; height: 500; margin: auto">
    <source src="" type="video/webm">
</video>
<script>
    var url = "ws://localhost:8080/LiveTraining3Demo/liveStreamMulticast"; // 8080/application_name/value_given_in_annotation
    var check = true;
    var socket = new WebSocket(url);
    var videoData = [];
    var superBuffer = null;
    //var videoUrl;

    //socket.binaryType = 'arraybuffer';
    socket.onopen = function() {
        console.log("Connected!!");

    }

    var check = true;
    socket.onmessage = function(videoStream) {

        var video = document.querySelector('video');
        var videoUrl = window.URL.createObjectURL(videoStream.data);
        video.src = videoUrl;
        video.load();
        video.onloadeddata = function() {
            URL.revokeObjectURL(video.src);
            video.play();
        }
        //video.srcObject

        //video.play();

        console.table(videoStream);

    }
    socket.onerror = function(err) {
        console.log("Error: " + err);
    }
</script>
</body>
</html>


Когда я пытаюсь запустить все остальные, все выглядит нормально, но в client.html отображается только источник видео тега без воспроизведения видео.

Я работаю над этим с недели. Возможно, моя реализация не работает, я также знаю WebRTC , Mauz Webrtc Broadcast , но я не хотел бы проходить через этот комплекс, если есть другой простой способ сделать это. Я не люблю использовать node.js сервер, так как я должен сделать это веб-приложение с весны. Любая идея может быть оценена. Заранее спасибо !!.

1 Ответ

0 голосов
/ 01 июля 2019

На стороне клиента получит буфер массива. Поэтому вам нужно преобразовать буфер массива в массив BLOB-объектов.

 let video = document.querySelector('video'); 
  let blobArray = [];
 socket.on('message',data=>{
  blobArray.push(new Blob([new Uint8Array(data)],{'type':'video/mp4'}));
  let currentTime = video.currentTime;
  let blob = new Blob(blobArray,{'type':'video/mp4'});
  video.src = window.URL.createObjectURL(blob);
  video.currentTime = currentTime;
  video.play();
 });
...