IP Camera - Streaming video with the basic authentication on Chrome

◇◆丶佛笑我妖孽 提交于 2019-12-06 12:43:28

问题


I have an Amcrest IP Camera. I would like to stream video to my web page. Its url is rtsp://mycamera.com:5554/stream

In order to get the stream of the camera, the camera has a following API http://mycamera.com/video.mjpg

It requires the basic authentication to work.

By formatting the URL and putting it into the image tag like below, I can make it work on Firefox, Safari

<img src="http://username:password@mycamera.com/video.mjpg" />

However, Chrome (v.40 on mine) does not allow this kind of URL, the browser will promt the user password form to be filled, or simply refuses the request. Setting header Authorization: "Basic encode64(username, password)" in the script does not help, the URL always return 401 error (Unauthorized)

Sometimes, it raises the CORS error. If my website is running with HTTPS, the HTTP API call will get blocked by the browser.


回答1:


  1. Disable authentication of IP camera:

If the camera does not have that option on the admin panel, just add an user without a password with any username like "none", then we can setup like this

<iframe src="http://none:@mycamera.com/video.mjpg" width="1280" height="768"></iframe>

Without password, my Chrome no longer throws the user name/password. (tested on Chrome of Windows and MacOSX & Safari)

  1. Proxy the output to my own website's server:

Download the framework CORS of the mohsen1

Install node js and run this server on the same with domain of the website. We need to edit the index.js file as below

var fs = require('fs');
var request = require('request');
var http = require('http');
var https = require('https');
var privateKey = fs.readFileSync('/var/private_key.pem', 'utf8');
var certificate = fs.readFileSync('/var/certificate.crt, 'utf8');

var credentials = {key: privateKey, cert: certificate};
var express = require('express');


var proxy_http_port = 9009
var proxy_https_port = 9443

var app = express();

// your express configuration here

var auth = "";

app.use(function (req, res, next) {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');

    next();
});

var t = app.get('/', function (req, res, next) {
    var username = "";
    var password = "";

    if (req.query.auth) {
        username = req.query.auth.split(":")[0];
        password = req.query.auth.split(":")[1];

        auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');


        res.header('Authorization', auth);

    } else {
        res.send('please specify auth query param');
    }

    if (req.query.url) {



        var options = {
            method: 'GET',
            url: req.query.url,
            headers: {
                "Authorization": auth,
                //'User-Agent': req.headers['user-agent']
            },
            encoding: null
        };


        var r = request(options, function callback(error, response, body) {

            if (!error && response.statusCode == 200) {
                res.write(body);

                delete response.headers['access-control-allow-origin'];

            }
        }).pipe(res);


    } else {
        res.send('You have to specify URL query');
    }

});

http.globalAgent.maxSockets = 100; 

var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);

httpServer.listen(proxy_http_port);
httpsServer.listen(proxy_https_port);

Encode the video stream URL below:

http://mycamera.com/video.mjpg

to:

http%3A%2F%2Fmycamera.com%2Fvideo.mjpg

The URL of stream video should be

https://mywebsite.com:9443/?auth=username:password&url=(put above encoded video URL here)

THe advantage of this approach is to bypass most of problems around and get rid of the errors(CORS, HTTPS) because my website will request to its own server

The drawback is the video would be fetch twice, it caused delay pretty much.




回答2:


Error 401 means invalid credentials so there's a good chance you are simply not formatting the basic auth string correctly. The header format should be Authorization Basic [base64 encoded username:password] using a colon symbol : to separate the two before encoding that entire string into base 64.

For example the resulting header should look something like this: Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l

You can try installing the Chrome "Advanced REST Client" plugin and use that plugin to test accessing your URL link with basic auth parameters. If you can get it to work with the REST client plugin then go back and update your script to fix the format of the auth headers.

Link to Advanced REST Client: https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?hl=en-US

Link to auth headers format info: https://en.wikipedia.org/wiki/Basic_access_authentication



来源:https://stackoverflow.com/questions/36217887/ip-camera-streaming-video-with-the-basic-authentication-on-chrome

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!