@accountnujen

Как на сайте отобразить MJPG поток, который требует digest авторизации?

Пытался указать
<img src="http://adminka:admin@192.168.1.8/cgi-bin/mjpg/video.cgi?channel=1&subtype=1" width="720" height="480">

или через <video>, но результат не дало. На камере отключена basic авторизация, доступна только digest...

Если просто открыть ссылку в браузере, то откроется диалоговое окно для ввода логина и пароля и затем откроется картинка-видео.
Какие есть варианты решения?

UPD. Также указываю тег PHP, потому что веду разработку на нём. Может быть есть вариант как-нибудь обмануть сайт, проведя авторизацию?
  • Вопрос задан
  • 100 просмотров
Решения вопроса 1
@accountnujen Автор вопроса
Такс, если кто-то столкнётся с этим, то всё оказалось проще, чем я думал:
Вы создаёте файл, который будет постоянно возвращать то, что отдаёт поток. Загвостка у меня была с заголовком, поэтому ничего не работало. Всё вертится вокруг функции CURLOPT_WRITEFUNCTION => 'streamCallback'.
header('Content-Type: multipart/x-mixed-replace; boundary=myboundary');
function streamCallback($curl, $data) {
    echo $data;
    return strlen($data);
}
$ch = curl_init("$urlcam/cgi-bin/mjpg/video.cgi?channel=1&subtype=1");
curl_setopt_array($ch, [
        CURLOPT_USERPWD => "admin:password",
        CURLOPT_CONNECTTIMEOUT => 20,
        CURLOPT_TIMEOUT => 0,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_HTTPAUTH=>CURLAUTH_DIGEST,
        CURLOPT_CUSTOMREQUEST => "GET",
        CURLOPT_WRITEFUNCTION => 'streamCallback'
    ]);
$result = curl_exec($ch);
curl_close($ch);

На сайте уже просто указываете ссылку на ваш php файл в картинке:
<img src="https://website/mjpg.php" width="720" height="480">
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Anastasia2306
@Anastasia2306
PHP-разработчик.
Это не будет работать в таком виде, потому что это на уровне браузера стоит защита от таких вот конструкций. Вы правильно указали, что без PHP тут не обойтись. Я бы как-то решила этот вопрос:

<?php
$url = 'http://192.168.1.8/cgi-bin/mjpg/video.cgi?channel=1&subtype=1';

// Функция для digest-авторизации
function digest_parse($txt)
{
    $needed_parts = array('nonce'=>1, 'realm'=>1, 'qop'=>1);
    $data = array();
    $keys = implode('|', array_keys($needed_parts));

    preg_match_all('@('.$keys.')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);

    foreach ($matches as $m) {
        $data[$m[1]] = $m[3] ? $m[3] : $m[4];
        unset($needed_parts[$m[1]]);
    }

    return $needed_parts ? false : $data;
}

// Инициализация cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);

// получения заголовков www-Authenticate
$response = curl_exec($ch);

// разбор заголовк а WWW-Authenticate
if (preg_match('/^WWW-Authenticate: Digest (.*)$/im', $response, $matches)) {
    $digest_parts = digest_parse($matches[1]);

    // Создание заголовка Authorization
    // Здесь также надо сгенерить правильный ответ на основе полученных данных и вашего логина и пароля
    // наподобие этого
    $digest_response = ''; // ответ

    // Установка опций для cURL с заголовком Authorization
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Digest username="adminka", realm="'.$digest_parts['realm'].'", nonce="'.$digest_parts['nonce'].'", uri="/cgi-bin/mjpg/video.cgi?channel=1&subtype=1", response="'.$digest_response.'", qop='.$digest_parts['qop'].', nc=00000001, cnonce="d41d8cd98f00b204e9800998ecf8427e"'));
}

// Удаление предыдущих заголовков
curl_setopt($ch, CURLOPT_HEADER, 0);

// Передача потока клиенту
curl_exec($ch);
curl_close($ch);
?>


Ну а потом уже смело в теге img можно сделать так:
<img src="вашскрипт.php" width="720" height="480">

Пример с PHP кодом не полный - я лишь натолкнула вас на мысль, как это может работать. Удачи!
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы