Search code examples
javascriptnode.jswebserverintel-edison

Streaming server: TypeError: Cannot call method 'replace' of undefined


I'm absolutely new to webservers and node JS and I was following this tutorial to create - and understand - a streaming server on my Intel Edison board. I already read the other posts about this problem on this website but I could not find an answer for my case

After starting the .js server I can correctly connect to it typing in my client browser [I'm using Chrome] something like: http://192.168.1.31:8888/ and a video, the same given with the tutorial, is displayed. If I want I can even activate it and it works fine

But looking to the code provided:

http.createServer(function (req, res) {

    var reqResource = url.parse(req.url).pathname;
    //console.log("Resource: " + reqResource);

    if(reqResource == "/"){

        //console.log(req.headers)
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.write(indexPage);
        res.end();

    } else if (reqResource == "/favicon.ico"){

        res.writeHead(404);
        res.end();

    } else {

            var total;
            if(reqResource == "/movie.mp4"){
                total = movie_mp4.length;
            } else if(reqResource == "/movie.ogg"){
                total = movie_ogg.length;
            } else if(reqResource == "/movie.webm"){
                total = movie_webm.length;
            } 

            var range = req.headers.range;

            var positions = range.replace(/bytes=/, "").split("-");
            var start = parseInt(positions[0], 10);
            // if last byte position is not present then it is the last byte of the video file.
            var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
            var chunksize = (end-start)+1;

            if(reqResource == "/movie.mp4"){
                res.writeHead(206, { "Content-Range": "bytes " + start + "-" + end + "/" + total, 
                                     "Accept-Ranges": "bytes",
                                     "Content-Length": chunksize,
                                     "Content-Type":"video/mp4"});
                res.end(movie_mp4.slice(start, end+1), "binary");

            } else if(reqResource == "/movie.ogg"){
                res.writeHead(206, { "Content-Range": "bytes " + start + "-" + end + "/" + total, 
                                     "Accept-Ranges": "bytes",
                                     "Content-Length": chunksize,
                                     "Content-Type":"video/ogg"});
                res.end(movie_ogg.slice(start, end+1), "binary");

            } else if(reqResource == "/movie.webm"){
                res.writeHead(206, { "Content-Range": "bytes " + start + "-" + end + "/" + total, 
                                     "Accept-Ranges": "bytes",
                                     "Content-Length": chunksize,
                                     "Content-Type":"video/webm"});
                res.end(movie_webm.slice(start, end+1), "binary");
            }
    }
}).listen(8888);

I think I should also be able to type in my client something like: http://192.168.1.31:8888/movie.mp4 and solve this address correctly receiving slices of video on my chrome client. The problem is that when I try to do this I get the following error:

 var positions = range.replace(/bytes=/, "").split("-");
                                  ^
TypeError: Cannot call method 'replace' of undefined
    at Server.<anonymous> (/home/root/streaming-video-html5/streaming-video-html5/server.js:66:35)
    at Server.emit (events.js:98:17)
    at HTTPParser.parser.onIncoming (http.js:2109:12)
    at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:122:23)
    at Socket.socket.ondata (http.js:1967:22)

I understood from here that this error comes from having range.replace.split undefined but why?

Any idea on how to fix this annoying problem?

Thanks in advance to those who will try to help


Solution

  • client may not be sending a range in the request header - it's not mandatory, so try this

        var range = req.headers.range;
        var start = 0, end = total - 1;
        if(range) {
            var positions = range.replace(/bytes=/, "").split("-");
            start = parseInt(positions[0], 10);
            // if last byte position is not present then it is the last byte of the video file.
            end = positions[1] ? parseInt(positions[1], 10) : total - 1;
        }
    

    I think that should fix it