2017-05-29 1 views
0

J'ai créé plusieurs vidéos sur toile HTML5. Succès. J'ai fait node.js websocket et ses clients sur le navigateur. Succès. Maintenant, j'essaie de combiner ces projets. L'idée est d'envoyer la vidéo lue sur canvas (admin.html) via nodejs websocket (serveur) aux clients du navigateur (spectactor.html). J'ai échoué.Envoyer une vidéo diffusée sur une toile sur le WebSocket

Aidez-nous s'il vous plaît. Voici le script. runVid appelé lorsqu'un administrateur a cliqué sur une ligne dans la playlist après avoir établi la connexion ws. runVid a ensuite appelé draw() et sendImage. sendImage n'est pas du tout déclenché. Qu'est-ce qui ne va pas? J'ai également mis sendImage() dans la fonction draw(), mais cela a également échoué.

var port = 8080; 
var ws = new WebSocket('ws://127.0.0.1:' + port,['soap', 'xmpp']); 
ws.binaryType = 'arraybuffer'; 


    function runVid(){ 
    var video = document.getElementById('video'); 
    var canvas = document.getElementById('canvas'); 

    var context = canvas.getContext('2d'); 

    var cw = Math.floor(canvas.clientWidth); 
    var ch = Math.floor(canvas.clientHeight); 
    canvas.width = cw; 
    canvas.height = ch; 

    video.addEventListener('play', function(){ 
     draw(this, context, cw, ch); 
     sendImage(context, cw, ch); 
    }, false); 
    } 


    function draw(video,canvas,width,height) { 
    if(video.paused || video.ended) return false; 
    canvas.drawImage(video,0,0,width,height); 

    setTimeout(draw,20,video,canvas,width,height); 

    } 

    function sendImage(context, width,height){ 
    var imageData = context.getImageData(0, 0, width, height); 
    var canvasPixelArray = imageData.data; 
    var canvasPixelLen = canvasPixelArray.length; 

    for(var j = 0; j<canvasPixelLen;j++){ 
     byteArray[j] = canvasPixelArray[j]; 
    } 

    ws.send(byteArray.buffer); 
    console.log("byteArray sent"); 
    } 

Répondre

1

L'idée est d'envoyer la vidéo lue sur toile (admin.html) par nodejs websocket (serveur) aux clients du navigateur (spectactor.html).

Vous pouvez utiliser WebSocket, mais pourquoi voudriez-vous? Avec votre approche, vous devez récupérer toutes ces données dans le canevas, les mettre en mémoire tampon et, dans votre cas, les laisser crues (ce qui est énormément difficile à transmettre sur Internet), puis demander au serveur de copier toutes ces données. à tous ses clients d'écoute dans votre JS, puis annulez le processus à la réception. Le surcoût est énorme, et n'est approprié que si vous avez d'excellentes connexions internet, vous avez besoin d'une vidéo sans perte, et vous vous attendez à des taux d'images et/ou des tailles d'images faibles.

Ce que vous devez faire à la place est de commencer par CanvasCaptureMediaStream. Une fois que vous avez capturé un Canvas en tant que MediaStream, vous pouvez utiliser MediaRecorder pour obtenir une version encodée de cette vidéo, l'envoyer à votre serveur via WebSocket, puis laisser le serveur l'envoyer à tous les autres clients avec un HTTP normal!

Encore mieux ... utilisez WebRTC. Par défaut, vous perdrez de la qualité pour une latence plus faible, mais cela prendra votre nouveau MediaStream et l'enverra directement aux clients sans impliquer votre serveur. (À moins que vous ne souhaitiez bien sûr en diffuser un à plusieurs ... et finalement vous aurez besoin de serveurs impliqués pour gérer la charge.)

L'une ou l'autre de ces solutions est meilleure que ce que vous essayez de faire maintenant.

+0

C'est exactement ce que je fais, j'envoie des blobs via socketIO à mon serveur, mais comment envoyer la vidéo de mon serveur et la lire correctement sur le client? Merci – Antoine

+1

@Antoine J'utilise WebM sur HTTP pour cela, mais vous pouvez utiliser ce que vous voulez. Vous trouverez peut-être plus facile d'utiliser FFmpeg pour prendre en charge tout transcodage nécessaire et l'envoyer à un serveur de streaming vidéo existant. – Brad

+0

Pouvez-vous développer un peu là-dessus? Fondamentalement, je peux envoyer les fichiers WebM au client, mais comment les charger sur la source vide? J'essaie d'utiliser Media Extension API mais c'est incroyablement difficile pour moi, merci pour votre aide – Antoine