MediaSource API:视频无法播放

时间:2018-05-10 11:08:21

标签: javascript node.js socket.io video-streaming media-source

我正在为Magic Mirror制作一个在RPi上运行的模块。该模块应允许用户在其移动设备上选择视频文件,开始读取文件并将流发送回魔镜上的html视频标签。这更像是将视频从移动设备镜像/转换为魔镜(rpi)。该框架基于Nodejs。

目前我正在尝试读取本地文件并将流发送到客户端。

我正在为服务器使用以下代码:

module.exports = NodeHelper.create({
    socketNotificationReceived: function(notification, payload) {
        var self = this;
        switch(notification) {
            case "INITIATEDEVICES":
                var readStream = fs.createReadStream("./modules/MMM-MP4Player/video.mp4");
                readStream.addListener('data', function(data){
                    self.sendSocketNotification('Video_File',data);
                });
                break;
        }
    }
});

以下代码适用于客户端:

Module.register("MMM-MP4Player",{
    start: function(){
        window.URL = window.URL || window.webkitURL;
        window.MediaSource = window.MediaSource || window.WebKitMediaSource;
        if(!!! window.MediaSource){
            console.log('MediaSource API is not available!');
        }
    },
    getDom: function() {
        var self = this;
        wrapper = document.createElement("div");
        videoElement = document.createElement("video");
        videoElement.width = 1280;
        videoElement.height = 720;
        videoElement.controls = true;
        videoElement.autoplay = true;
        videoElement.id = self.identifier+"_player";
        wrapper.appendChild(videoElement);

        setTimeout(function(){ 
            self.mediaSource = new MediaSource();
            self.queue = [];
            videoElement.src = window.URL.createObjectURL(self.mediaSource);
            self.mediaSource.addEventListener('sourceopen', function(e){
                self.sourceBuffer = self.mediaSource.addSourceBuffer('video/mp4; codecs="avc1.42E01E,mp4a.40.2"'); // video/webm; codecs="vorbis,vp9"
                videoElement.play();
                self.sourceBuffer.addEventListener('update', function() {
                    if (self.queue.length > 0 && !self.sourceBuffer.updating) {
                        self.sourceBuffer.appendBuffer(self.queue.shift());
                    }
                });
            }, false);

            self.sendSocketNotification("INITIATEDEVICES");
        }, 2000);
        return wrapper;
    },

    socketNotificationReceived: function(notification, payload){
        var self = this;
        switch(notification){
            case "Error": // Universal error handler
                break;
            case "Video_File":
                if (self.sourceBuffer.updating || self.queue.length > 0) {
                    self.queue.push(new Uint8Array(payload.data));
                } else {
                    self.sourceBuffer.appendBuffer(new Uint8Array(payload.data));
                }
                break;
        }
    }   
});

视频块从服务器完美发送并由客户端接收。只是视频播放器仍然是空的。欢迎提出所有建议。

感谢。

1 个答案:

答案 0 :(得分:1)

好的。所以在没有stackoverflow的帮助后,我继续进行实验并最终纠正了问题。在这里张贴只是为了帮助别人。

我对代码进行了一些小调整,并将文件更改为符合破折号的文件。现在需要关注如何将视频缓冲区转换为符合虚线的版本。无论如何这里是代码。

Module.register("MMM-MP4Player",{
    getDom: function() {
        var self = this;
        wrapper = document.createElement("div");
        videoElement = document.createElement("video");
        videoElement.width = 300;
        videoElement.height = 200;
        videoElement.controls = true;
        videoElement.autoplay = true;
        videoElement.id = self.identifier+"_player";
        wrapper.appendChild(videoElement);

        window.URL = window.URL || window.webkitURL;
        window.MediaSource = window.MediaSource || window.WebKitMediaSource;
        self.mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
        self.queue = [];
        if(window.MediaSource && window.MediaSource.isTypeSupported(self.mimeCodec)){
            setTimeout(function(){ 
                self.mediaSource = new MediaSource();
                videoElement.src = window.URL.createObjectURL(self.mediaSource);
                videoElement.play();
                self.mediaSource.addEventListener('sourceopen', function(e){
                    self.sourceBuffer = self.mediaSource.addSourceBuffer(self.mimeCodec);
                    self.sourceBuffer.addEventListener('updateend', function() {
                        if (self.queue.length > 0 && !self.sourceBuffer.updating) {
                            self.sourceBuffer.appendBuffer(self.queue.shift());
                        }
                    }, false);                  
                }, false);
                self.sendSocketNotification("INITIATEDEVICES");
            }, 2000);
        }
        return wrapper;
    },

    socketNotificationReceived: function(notification, payload){
        var self = this;
        switch(notification){
            case "Video_File":
                if (self.sourceBuffer.updating || self.queue.length > 0) {
                    self.queue.push(new Uint8Array(payload));
                } else {
                    self.sourceBuffer.appendBuffer(new Uint8Array(payload));
                }
                break;
        }
    }
});

欢迎任何有关Nodejs中视频缓冲区转换的帮助。