MediaSource API: 视频未播放

MediaSource API: Video not playing

我正在为 Magic Mirror 制作一个在 RPi 上运行的模块。该模块应该允许用户 select 在他们的手机上播放视频文件,开始读取文件并将流发送回魔镜上的 html 视频标签。这更像是 mirroring/casting 从移动设备到魔镜 (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;
        }
    }   
});

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

谢谢。

好的。所以在没有Whosebug帮助的情况下,我不断的尝试,终于解决了这个问题。发在这里只是为了帮助别人。

我对代码做了一些小的调整,并将文件更改为符合破折号的文件。现在需要关注如何将视频缓冲区动态转换为兼容 dash。不管怎样,这是代码。

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 视频缓冲区转换的帮助。