简体   繁体   中英

MediaSource API: Video not playing

I am making a module for Magic Mirror which runs on a RPi. The module is supposed to allow the user select a video file on their mobile, start reading the file and send the stream back to html video tag on the magic mirror. This is more like mirroring/casting a video from mobile device to magic mirror (rpi). The framework is based on Nodejs.

Currently I am trying to read a local file and send the stream to the client.

I am using the following code for the server:

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;
        }
    }
});

The following code is for the client:

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;
        }
    }   
});

The video chunks are being sent perfectly from the server and received by the client too. Its just that the video player remains empty. All suggestions are welcome.

Thanks.

Alright. So after no help from stackoverflow, I kept on experimenting and finally corrected the problem. Posting it here just to help someone else.

I made some minor adjustment to the code and changed the file to a dash-compliant file. Need to now focus on how to convert a video buffer to dash-compliant on the fly. Anyways here is the code.

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;
        }
    }
});

Any help on the video buffer conversion in Nodejs is welcome.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM