deepch / RTSPtoWebRTC

RTSP to WebRTC use Pion WebRTC
MIT License
1.56k stars 416 forks source link

Можно ли использовать ваш сервер для вставки видео на свой сайт? #72

Closed vash-sa closed 3 years ago

vash-sa commented 3 years ago

Я испытал ваш продукт на orangepi pc +. Все получилось! Но у меня проблема. Я не понимаю как вставить видео на свой сайт. У меня там много дополнительной информации и вставлять видео как гиперссылку не хочется. Я профан в golang. Может вы подскажите, как вставить видео, используя ваш http сервер, в тег

И можно ли сделать опцию для получения скриншотов видео. Т.е. фото (кадры) в определенные момент времени, по какой-нибудь внешней команде.

deepch commented 3 years ago

Добрый день.

У нас нет продукта и мы не планируем его делать, это пример созданный в образовательных целях что бы показать возможность использования WebRTC на golang.

На базе данного примера вы можете создавать различные вариации в том числе и вставить видео на сайт но вы обретёте проблемы с NAT если устройство за роутером, нужно будет пробрасывать порты.

Но как технология WebRTC избыточна для таких задач. Она ориентированная на звонки браузер -> браузер.

В случаи работы с камерой я настоятельно рекомендую использовать https://github.com/deepch/RTSPtoWSMP4f если Вы не планируете смотреть видео с мобильных устройств.

Да мы можете создать скриншот, сами необходимо использовать FFmpeg из пакета vdk https://github.com/deepch/vdk/tree/master/cgo/ffmpeg сформировать annexb кадр из sps + pps + iframe через разделитель. Но это приведёт к тому что нужно будет использовать CGO что негативно влияет на компиляцию.

Самым лучшим решение будет дёргать скрин /dev/video или если вы используете ip камеру дергать метод получения скриншота для разных камер url разный например для Dahua

http://:9989/onvif/media_service/snapshot?channel=0&subtype=0

Вы можете написать простой get запрос и получать кадр на прямую с dev или http или можете делать скрин с video в браузере.

Мы поможем с кодом для вставки но делать скрин в в данном примере избыточно многие используют его в других целях а CGO усложнит компиляцию. Возможно мы создадим репозитарий с примером позднее.

vash-sa commented 3 years ago

Спасибо. Скиншоты, правда, можно брать с камер непосредственно. Помогите вот с этим, пожалуйста, "Мы поможем с кодом для вставки". Очень сильно на вас надеюсь

vash-sa commented 3 years ago

"В случаи работы с камерой я настоятельно рекомендую использовать https://github.com/deepch/RTSPtoWSMP4f " Здесь я понимаю та же ситуация. Http сервер слушает порт. В случае запроса по этому порту, пользователь перенаправляется на ваш templates/index.tmpl, который и воспроизводит видео на своей странице. Вставить видео у себя здесь также не получится.

vdalex25 commented 3 years ago

В данном случае сервер - забирает поток с камеры и отдает его в браузер в app.js содержится пример плеера этот плеер можно вставить на любую страницу и указать ему откуда получать данные, по умолчанию обмен SDP для установления связи между сервером и браузером происходит по адресу http://localhost:8083/stream/receiver/H264_PCMALAW если вы хотите получать видео с любого места а не только с локального компьютера то необходимо что бы ваш сервер имел внешний ip и порт 8083 был доступен извне

vash-sa commented 3 years ago

Не понял. Я брал app.js + jquery-3.4.1.min.js. Закидывал в папку с сайтом.

<!DOCTYPE html>

Что у меня не так, подскажите? Плэйр загружается, в консоли [GIN] 2021/02/09 - 11:11:48 | 200 | 4.933526ms | 192.168.1.121 | GET "/stream/player/H264_PCMALAW" и на этом все.

vash-sa commented 3 years ago

Если указываю http://192.168.1.58:8083/stream/receiver/H264_PCMALAW то в консоли: [GIN] 2021/02/09 - 11:18:33 | 404 | 4.625µs | 192.168.1.121 | GET "/stream/receiver/H264_PCMALAW"

vash-sa commented 3 years ago

Мне бы хотя бы с локального получить что-нибудь.

vash-sa commented 3 years ago

Если набрать в браузере http://192.168.1.58:8083, то в консоли: [GIN] 2021/02/09 - 11:22:21 | 200 | 442.234µs | 192.168.1.121 | GET "/stream/codec/H264_PCMALAW" [GIN] 2021/02/09 - 11:22:21 | 200 | 85.871983ms | 192.168.1.121 | POST "/stream/receiver/H264_PCMALAW"

и видео пошло

deepch commented 3 years ago

укажите место H264_PCMALAW ваше имя потока из конфига

vdalex25 commented 3 years ago

в данном случае видео играется не из тега необходимо в файле app.js исправить

function getCodecInfo() {
  $.get("../codec/" + suuid, function(data) {
.......................................................................
function getRemoteSdp() {
  $.post("../receiver/"+ suuid, {

на

function getCodecInfo() {
  $.get("http://192.168.1.58:8083/stream/codec/" + suuid, function(data) {
.......................................................................
function getRemoteSdp() {
  $.post("http://192.168.1.58:8083/stream/receiver/"+ suuid, {
vash-sa commented 3 years ago

все вставил ` <!DOCTYPE html>

` Результат:

[GIN] 2021/02/09 - 11:49:35 | 404 | 5.209µs | 192.168.1.121 | GET "/stream/receiver/H264_PCMALAW" [GIN] 2021/02/09 - 11:49:35 | 200 | 26.666µs | 192.168.1.121 | GET "/stream/codec/undefined" 2021/02/09 11:49:35 Stream Not Found [GIN] 2021/02/09 - 11:49:35 | 200 | 706.06µs | 192.168.1.121 | POST "/stream/receiver/undefined"

vash-sa commented 3 years ago

не видит потока

vash-sa commented 3 years ago

Отслеживается у вас 4 адреса: router.GET("/", HTTPAPIServerIndex) router.GET("/stream/player/:uuid", HTTPAPIServerStreamPlayer) router.POST("/stream/receiver/:uuid", HTTPAPIServerStreamWebRTC) router.GET("/stream/codec/:uuid", HTTPAPIServerStreamCodec)

и здесь нет router.GET("/stream/receiver/:uuid", HTTPAPIServerStreamWebRTC) поэтому ошибка 404

vash-sa commented 3 years ago

Добавил в http.go router.GET("/stream/receiver/:uuid", HTTPAPIServerStreamWebRTC) Скомпилировал, результат: [GIN-debug] Listening and serving HTTP on :8083 [GIN] 2021/02/09 - 12:07:36 | 200 | 30.04µs | 192.168.1.121 | GET "/stream/codec/undefined" 2021/02/09 12:07:36 Stream Not Found [GIN] 2021/02/09 - 12:07:36 | 200 | 141.535µs | 192.168.1.121 | GET "/stream/receiver/H264_PCMALAW" 2021/02/09 12:07:36 Stream Not Found [GIN] 2021/02/09 - 12:07:36 | 200 | 667.134µs | 192.168.1.121 | POST "/stream/receiver/undefined"

Как найти поток? Что обидно, что он там есть((

vdalex25 commented 3 years ago
<source src="http://192.168.1.58:8083/stream/receiver/H264_PCMALAW"/>

это не надо указывать браузер пытается получить это напрямую и получается ошибка

[GIN] 2021/02/09 - 11:49:35 | 404 | 5.209µs | 192.168.1.121 | GET "/stream/receiver/H264_PCMALAW"

далее

[GIN] 2021/02/09 - 11:49:35 | 200 | 26.666µs | 192.168.1.121 | GET "/stream/codec/undefined"

undefined - потому что suuid - это динамический параметр имя потока из конфигурации этот параметр получает данные в app.js

let suuid = $('#suuid').val();

добавьте в HTML

<input type="hidden" name="suuid" id="suuid" value="H264_PCMALAW">

если конечно в кофигурации есть поток с именем H264_PCMALAW

vash-sa commented 3 years ago

Исправил ` <!DOCTYPE html>

` Результат: 2021/02/09 12:17:26 Stream Try Connect H264_PCMALAW [GIN] 2021/02/09 - 12:17:27 | 200 | 954.795237ms | 192.168.1.121 | GET "/stream/codec/H264_PCMALAW" [GIN] 2021/02/09 - 12:17:27 | 200 | 82.030328ms | 192.168.1.121 | POST "/stream/receiver/H264_PCMALAW" [GIN] 2021/02/09 - 12:17:42 | 200 | 164.244µs | 192.168.1.121 | GET "/stream/codec/H264_PCMALAW" [GIN] 2021/02/09 - 12:17:42 | 200 | 74.96116ms | 192.168.1.121 | POST "/stream/receiver/H264_PCMALAW" 2021/02/09 12:17:47 Client Not Send ACK (probably the browser is minimized) or tab not active Close client 2021/02/09 12:17:47 WritePacket WebRTC Client Offline 2021/02/09 12:18:02 Client Not Send ACK (probably the browser is minimized) or tab not active Close client 2021/02/09 12:18:02 Stream Not Send Video Close 2021/02/09 12:18:02 WritePacket WebRTC Client Offline

vash-sa commented 3 years ago

{ "server": { "http_port": ":8083" }, "streams": { "H264_PCMALAW": { "on_demand": true, "url": "rtsp://....../Streaming/Channels/101" }

} } Вот config.json

vash-sa commented 3 years ago

"В случаи работы с камерой я настоятельно рекомендую использовать https://github.com/deepch/RTSPtoWSMP4f если Вы не планируете смотреть видео с мобильных устройств." В этом не работает, не открываются ни примеры, ни видео

deepch commented 3 years ago

Простите но не открывается слишком обширный диагноз и вопрос нужно задавать в репозитории проекта, нужно более детальное описание. Версия ОС Браузер скриншот консоли и консоли браузера. Попробуйте открыть в chrome

vash-sa commented 3 years ago

Я именно в chrome. Я хотел бы закончить начатое обсуждение в этом проекте.

vash-sa commented 3 years ago

2021/02/09 12:17:47 Client Not Send ACK (probably the browser is minimized) or tab not active Close client 2021/02/09 12:17:47 WritePacket WebRTC Client Offline 2021/02/09 12:18:02 Client Not Send ACK (probably the browser is minimized) or tab not active Close client 2021/02/09 12:18:02 Stream Not Send Video Close 2021/02/09 12:18:02 WritePacket WebRTC Client Offline

Откуда идут эти сообщения? Кто их генерирует и почему? Возможно это позволит завершить начатое обсуждение.

vdalex25 commented 3 years ago

https://github.com/deepch/RTSPtoWebRTC/commit/b6855335a897c1ab3d3fbc91dfb46dd700f17827 обновите код и попробуйте запустить еще раз https://github.com/deepch/RTSPtoWebRTC/issues/72#issuecomment-775897243

vash-sa commented 3 years ago

Перекомпилировал, перезагружал, что я только не делал. Результат тот же

vdalex25 commented 3 years ago

вот полностью рабочий пример для сервера запущенного по адресу 192.168.1.58, если запускается на том же компьютере то адрес должен быть 127.0.0.1

<!doctype html>
<html lang="en">
  <head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <script src="//code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/adapterjs/0.15.5/adapter.min.js"></script>
    <title>demo</title>
  </head>
  <body>
    <input type="hidden" name="suuid" id="suuid" value="H264_PCMALAW">
    <div id="remoteVideos">
        <video id="videoElem" autoplay muted controls></video>
    </div>
  </body>
  <script>
  let server='192.168.1.58';
  let stream = new MediaStream();
let suuid = $('#suuid').val();

let config = {
iceServers: [{
  urls: ["stun:stun.l.google.com:19302"]
}]
};

const pc = new RTCPeerConnection(config);
pc.onnegotiationneeded = handleNegotiationNeededEvent;
let log = msg => {
//document.getElementById('div').innerHTML += msg + '<br>'
}
pc.ontrack = function(event) {
stream.addTrack(event.track);
videoElem.srcObject = stream;
log(event.streams.length + ' track is delivered')
}

pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)

async function handleNegotiationNeededEvent() {
let offer = await pc.createOffer();
await pc.setLocalDescription(offer);
getRemoteSdp();
}

$(document).ready(function() {

getCodecInfo();
});

function getCodecInfo() {
$.get("//"+server+":8083/stream/codec/" + suuid, function(data) {
  try {
    data = JSON.parse(data);
  } catch (e) {
    console.log(e);
  } finally {
    $.each(data,function(index,value){
      pc.addTransceiver(value.Type, {
        'direction': 'sendrecv'
      })
    })
    //send ping becouse PION not handle RTCSessionDescription.close()
    sendChannel = pc.createDataChannel('foo');
    sendChannel.onclose = () => console.log('sendChannel has closed');
    sendChannel.onopen = () => {
      console.log('sendChannel has opened');
      sendChannel.send('ping');
      setInterval(() => {
        sendChannel.send('ping');
      }, 1000)
    }
    sendChannel.onmessage = e => log(`Message from DataChannel '${sendChannel.label}' payload '${e.data}'`);
  }
});
}

let sendChannel = null;

function getRemoteSdp() {
$.post("//"+server+":8083/stream/receiver/"+ suuid, {
  suuid: suuid,
  data: btoa(pc.localDescription.sdp)
}, function(data) {
  try {
    pc.setRemoteDescription(new RTCSessionDescription({
      type: 'answer',
      sdp: atob(data)
    }))
  } catch (e) {
    console.warn(e);
  }
});
}
  </script>
</html>
vash-sa commented 3 years ago

Просто шикарно!!!! Все получилось!!!

vash-sa commented 3 years ago

Спасибо огромное!!!

vash-sa commented 3 years ago

Добрый день! Вчера так все хорошо получилось в локальной сети. Решил сегодня испробовать во внешней. Пробросил все порты. Источник сигнала тот же. Выдает следующий результат:

[GIN-debug] Listening and serving HTTP on :8083 2021/02/10 12:28:56 Stream Try Connect H264_PCMALAW [GIN] 2021/02/10 - 12:28:56 | 200 | 151.66937ms | 212.3.142.215 | GET "/stream/codec/H264_PCMALAW" [GIN] 2021/02/10 - 12:28:56 | 200 | 99.237061ms | 212.3.142.215 | POST "/stream/receiver/H264_PCMALAW" 2021/02/10 12:29:16 Client Not Send ACK (probably the browser is minimized) or tab not active Close client 2021/02/10 12:29:16 Stream Not Send Video Close 2021/02/10 12:29:16 WritePacket WebRTC Client Offline

vdalex25 commented 3 years ago

в консоли браузера что написано?

vash-sa commented 3 years ago

ругается на этот код let log = msg => { document.getElementById('div').innerHTML += msg + '
' }

vash-sa commented 3 years ago

app.js:17 Uncaught TypeError: Cannot read property 'innerHTML' of null at log (app.js:17) at RTCPeerConnection.pc.ontrack (app.js:23) log @ app.js:17 pc.ontrack @ app.js:23

deepch commented 3 years ago

вы все udp порты прокинули?

deepch commented 3 years ago

Попробуйте DMZ

Или указать range портов udp и прокинуть их на роутере.

"server": {
     "http_port": ":8083",
     "ice_servers": ["stun:stun.l.google.com:19302"],
     "webrtc_port_min": 60000,
     "webrtc_port_max" 60005
   },
vash-sa commented 3 years ago

"webrtc_port_min": 60000, "webrtc_port_max" 60005
Это эти порты UDP?

deepch commented 3 years ago

да

vdalex25 commented 3 years ago

я вчера скинул рабочий код без использования app.js вы судя по ошибкам в консоли at log (app.js:17) используете свой вариант

vash-sa commented 3 years ago

image

vash-sa commented 3 years ago

К сожалению, он у меня так работает

vdalex25 commented 3 years ago

Смотрите - раздел issue служит для сообщениях о проблемах в нашем коде вы же пытаетесь узнать у нас об ошибках в вашем коде причем эти ошибки очень просто гуглятся и исправляются например Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https в вашем случае не работает из-за того что страница содержит запросы на другие сервера, которые возможны только через протоколы http, data, chrome, chrome-extension, https ваш же файл запускается по протоколом file:// запустите файл через протокол http и он будет работать

vash-sa commented 3 years ago

Да, действительно, начал работать. Прошу прошения, спасибо за подсказку. Я включил RTSPClient, err := rtspv2.Dial(rtspv2.RTSPClientOptions{URL: url, DisableAudio: true, DialTimeout: 3 time.Second, ReadWriteTimeout: 3 time.Second, Debug: true} в stream.go Выдает такие сообщения 2021/02/10 16:14:17 [Unsupported NAL Type 6] 2021/02/10 16:14:18 [Unsupported NAL Type 6] 2021/02/10 16:14:20 [Unsupported NAL Type 6]

deepch commented 3 years ago

Вы включили отладку и видите сообщения отладки. В чём ваш вопрос?

vash-sa commented 3 years ago

Видеомодуль работает аналогично как в локальной, так и во внешней сети. Видны перезапуски сессий и там, и там. Значит видео воспроизводится. Вопрос: почему не отображается в браузере? UDP порты пробросил.

deepch commented 3 years ago

убедитесь что настроили STUN и на странице JS и в конфиге сервера. убедитесь что прокинули порты udp.

в случаи если это не поможет обратитесь к разработчику библиотеки WebRTC https://github.com/pion/webrtc

deepch commented 3 years ago

если у вас локально всё работает по вашим совам а за роутером не работает, логично предположить что вы допустили ошибки настройки работы WebRTC за роутером почитайте про STUN сервера, учитывая что везде оборудование разное мы не как вам не можем помочь настроить вашу локальную сесть.

vash-sa commented 3 years ago

Спасибо. Попробую разобраться сам.

vash-sa commented 3 years ago

Я нашел свою ошибку. Я вместо UDP пробросил TCP порты. Исправил и все заработало