Я транслирую потоковую передачу с веб-камеры из браузера с помощью webrtc на сервер, на котором работает следующая настройка:
- используя firefox и модифицированный html echo-test со шлюза janus, я отправляю поток веб-камеры на сервер janus
- сервер janus работает с использованием модифицированного подключаемого модуля echotest, который просто выполняет udp-потоки заданного char * buf в janus_videorecv_incoming_rtp () на порт 5060 только для целей тестирования (примерно так же)
- следующая командная строка gstreamer фактически открывает окно, показывающее потоковое видео
GST_DEBUG=p*:5 gst-launch-1.0 -vvv udpsrc caps="application/x-rtp,media=video,clock-rate=90000,payload=96" port=5060 ! rtpvp8depay ! vp8dec ! autovideosink
в модифицированном javascript эхо-теста я удаляю несколько строк из ответа sdp, который браузер получит следующим образом:
//jsep.sdp = jsep.sdp.replace(/a=rtcp-mux[^\s]*\s*/g, '');
jsep.sdp = jsep.sdp.replace(/a=rtpmap[^\s]*\s*red[^\s]*\s*/g, '');
jsep.sdp = jsep.sdp.replace(/a=rtpmap[^\s]*\s*ulpfec[^\s]*\s*/g, '');
jsep.sdp = jsep.sdp.replace(/a=fmtp[^\r\n]*\r*\n*/g, '');
jsep.sdp = jsep.sdp.replace(/a=rtcp-fb[^\s]*\s*goog-remb[^\s]*\s*/g, '');
ниже можно найти измененный ответ firefox sdp, который работает для указанной выше команды gstreamer, но таким же образом модифицированный ответ sdp не работает в случае хрома, я думал о настройке полезной нагрузки в крышках gstreamer, но 32,33,96,100,120 не сработало
Итак, вопрос: что нужно в случае хрома, чтобы это работало?
Я также попытался добавить запросы fir / pli, например, в videoroom.c от janus, как предложено здесь
вывод gstreamer в случае chrome is, где команда просто ждет в последней строке:
0:00:00.025791492 22279 0x1954b90 DEBUG pipeline gstpipeline.c:219:gst_pipeline_init:<GstPipeline@0x1962180> set bus <bus2> on pipeline
Setting pipeline to PAUSED ...
0:00:00.029798090 22279 0x1954b90 DEBUG pipeline gstpipeline.c:282:reset_start_time:<pipeline0> reset start_time to 0
Pipeline is live and does not need PREROLL ...
/GstPipeline:pipeline0/GstUDPSrc:udpsrc0.GstPad:src: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, payload=(int)96, encoding-name=(string)VP8-DRAFT-IETF-01
Setting pipeline to PLAYING ...
0:00:00.030045034 22279 0x1954b90 DEBUG pipeline gstpipeline.c:377:gst_pipeline_change_state:<pipeline0> selecting clock and base_time
0:00:00.030053523 22279 0x1954b90 DEBUG pipeline gstpipeline.c:398:gst_pipeline_change_state:<pipeline0> Need to update start_time
0:00:00.030058181 22279 0x1954b90 DEBUG pipeline gstpipeline.c:403:gst_pipeline_change_state:<pipeline0> Need to update clock.
/GstPipeline:pipeline0/GstRtpVP8Depay:rtpvp8depay0.GstPad:src: caps = video/x-vp8, framerate=(fraction)0/1
/GstPipeline:pipeline0/GstVP8Dec:vp8dec0.GstPad:sink: caps = video/x-vp8, framerate=(fraction)0/1
0:00:00.030111345 22279 0x1954b90 DEBUG pipeline gstpipeline.c:443:gst_pipeline_change_state:<pipeline0> start_time=0:00:00.000000000, now=33:52:04.529345754, base_time 33:52:04.529345754
/GstPipeline:pipeline0/GstRtpVP8Depay:rtpvp8depay0.GstPad:sink: caps = application/x-rtp, media=(string)video, clock-rate=(int)90000, payload=(int)96, encoding-name=(string)VP8-DRAFT-IETF-01
New clock: GstSystemClock
хром ответ:
v=0
o=- 8913399741269897639 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS janus
m=audio 1 RTP/SAVPF 111 103 104 0 8 106 105 13 126
a=mid:audio
c=IN IP4 192.168.0.1
a=sendrecv
a=rtcp-mux
a=ice-ufrag:l0n9
a=ice-pwd:r1elT1Ew8lP3TNlzwAHUsC
a=ice-options:trickle
a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44
a=setup:active
a=connection:new
a=rtpmap:111 opus/48000/2
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:126 telephone-event/8000
a=maxptime:60
a=ssrc:600390024 cname:janusaudio
a=ssrc:600390024 msid:janus janusa0
a=ssrc:600390024 mslabel:janus
a=ssrc:600390024 label:janusa0
a=candidate:1 1 udp 2013266431 192.168.0.1 45728 typ host
m=video 1 RTP/SAVPF 100 116 117 96
a=mid:video
c=IN IP4 192.168.0.1
a=sendrecv
a=rtcp-mux
a=ice-ufrag:l0n9
a=ice-pwd:r1elT1Ew8lP3TNlzwAHUsC
a=ice-options:trickle
a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44
a=setup:active
a=connection:new
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtpmap:96 rtx/90000
a=ssrc-group:FID 3188003624 3419969288
a=ssrc:677441062 cname:janusvideo
a=ssrc:677441062 msid:janus janusv0
a=ssrc:677441062 mslabel:janus
a=ssrc:677441062 label:janusv0
a=candidate:1 1 udp 2013266431 192.168.0.1 45728 typ host
m=application 0 DTLS/SCTP 0
c=IN IP4 192.168.0.1
Ответ Firefox:
v=0
o=Mozilla-SIPUA-32.0.3 11426 0 IN IP4 127.0.0.1
s=SIP Call
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS janus
m=audio 1 RTP/SAVPF 109 0 8 101
a=mid:audio
c=IN IP4 192.168.0.1
a=sendrecv
a=rtcp-mux
a=ice-ufrag:BRBU
a=ice-pwd:2W4fGNr//HejhiC4UIabW6
a=ice-options:trickle
a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44
a=setup:active
a=connection:new
a=rtpmap:109 opus/48000/2
a=ptime:20
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ssrc:3725983979 cname:janusaudio
a=ssrc:3725983979 msid:janus janusa0
a=ssrc:3725983979 mslabel:janus
a=ssrc:3725983979 label:janusa0
a=candidate:1 1 udp 2013266431 192.168.0.1 56574 typ host
m=video 1 RTP/SAVPF 120
a=mid:video
c=IN IP4 192.168.0.1
a=sendrecv
a=rtcp-mux
a=ice-ufrag:jZ5b
a=ice-pwd:dQQej9UIpPl5zuXBQNg3Nz
a=ice-options:trickle
a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44
a=setup:active
a=connection:new
a=rtpmap:120 VP8/90000
a=rtcp-fb:120 nack
a=rtcp-fb:120 nack pli
a=rtcp-fb:120 ccm fir
a=ssrc:1425382999 cname:janusvideo
a=ssrc:1425382999 msid:janus janusv0
a=ssrc:1425382999 mslabel:janus
a=ssrc:1425382999 label:janusv0
a=candidate:2 1 udp 2013266431 192.168.0.1 39063 typ host
m=application 0 DTLS/SCTP 0
c=IN IP4 192.168.0.1
ОБНОВЛЕНИЕ: я изменил sdp-answer, так что и firefox, и chrome почти одинаковы, за исключением строк «o =» и «s =», которые я просто скопировал из sdp-offer v=0
o=- 7589782217972865757 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE audio video
a=msid-semantic: WMS janus
m=audio 1 RTP/SAVPF 111
a=mid:audio
c=IN IP4 192.168.0.1
a=sendrecv
a=rtcp-mux
a=ice-ufrag:g0kZ
a=ice-pwd:d5oEody1jqIzDYUdf1fg6t
a=ice-options:trickle
a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44
a=setup:active
a=connection:new
a=rtpmap:111 opus/48000/2
a=ssrc:1038736511 cname:janusaudio
a=ssrc:1038736511 msid:janus janusa0
a=ssrc:1038736511 mslabel:janus
a=ssrc:1038736511 label:janusa0
a=candidate:1 1 udp 2013266431 192.168.0.1 51232 typ host
m=video 1 RTP/SAVPF 100
a=mid:video
c=IN IP4 192.168.0.1
a=sendrecv
a=rtcp-mux
a=ice-ufrag:g0kZ
a=ice-pwd:d5oEody1jqIzDYUdf1fg6t
a=ice-options:trickle
a=fingerprint:sha-256 C5:5F:DA:7D:84:47:B1:BF:6B:55:16:62:48:31:3E:D3:F1:7B:25:89:92:4A:4B:4D:4D:D9:D5:AF:EA:D8:15:44
a=setup:active
a=connection:new
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 goog-remb
a=ssrc:2455978689 cname:janusvideo
a=ssrc:2455978689 msid:janus janusv0
a=ssrc:2455978689 mslabel:janus
a=ssrc:2455978689 label:janusv0
a=candidate:1 1 udp 2013266431 192.168.0.1 51232 typ host
m=application 0 DTLS/SCTP 0
c=IN IP4 192.168.0.1
a=rtcp-fb:100 goog-remb
? Исправьте полезные данные rtp, отображаемые в строке мультимедиа видео, и удалите ненужноеrtx
сопоставление rtp. Это должно продвинуть вас дальше по дороге. Вы уверены, что Chrome даже присылает вам какие-нибудь медиафайлы? Я предполагаю, что он волнуется от ответа и ничего не отправляет. Если он отправляет мультимедиа, вы можете разбить заголовок rtp и увидеть полезную нагрузку, чтобы убедиться, что это VP8 - person Benjamin Trent   schedule 26.09.2014m=video 1 RTP/SAVPF 100
, чтобы указывать только одно отображение (для VP8). Тогда должно существовать только отображение VP8. Некоторые указатели sdp webrtc. Вы можете преобразовать буфер как пакет rtp, а затем получить доступ к типу.rtp_header* packetheader = (rtp_header*) buf; packetheader->type; //payload
- person Benjamin Trent   schedule 26.09.2014udpsrc port=5060 caps="application/x-rtp, media=video, clock-rate=90000, encoding-name=VP8-DRAFT-IETF-01, payload=100" ! rtpvp8depay ! vp8dec ! ffmpegcolorspace ! autovideosink
- person Benjamin Trent   schedule 26.09.2014corrupt frame
- person John Doe   schedule 27.09.2014ERROR: from element /GstPipeline:pipeline0/GstVP8Dec:vp8dec0:
Не удалось декодировать кадр Дополнительная информация отладки: gstvp8dec.c (469): gst_vp8_dec_handle_frame (): / GstPipeline: pipeline0 / GstVP8Dec: vp8dec0: поврежденный кадр - person John Doe   schedule 27.09.2014