chenzx
(陈志祥)
July 23, 2021, 4:48am
1
I’ve confirmed that chrome can play H264 video via WebRTC (using Janus server), no special config needed(audio still using Opus encoding).
Does mediasoup support H264 streaming? There is no detailed documentation about that.
Please help clarify this. thanks!
chenzx
(陈志祥)
July 23, 2021, 9:13am
3
Hi, ibc
i tried with the below config:
{
mimeType : 'video/H264',
clockRate : 90000,
payloadType : 96,
parameters : {
"packetization-mode" : 1,
"profile-level-id": "640032",
"x-google-start-bitrate" : 1000,
"level-asymmetry-allowed" : 1
},
rtcpFeedback : [
{
"type" : "nack",
"parameter" : "pli"
},
{
"type" : "ccm",
"parameter" : "fir"
},
{
"type" : "goog-remb",
"parameter" : ""
},
{
"type" : "transport-cc",
"parameter" : ""
}
], // FFmpeg does not support NACK nor PLI/FIR. ?
}
This can support chrome’s page2page H264 streaming with 640*480 size.
But when i use the ffmpeg RTP push command(video only):
const callRTPStreamPushCmd = `ffmpeg \
-re \
-v info \
-stream_loop -1 \
-i ${input_mp4_filepath} \
-an \
-c:v copy \
-f rtp \
-sdp_file video.sdp \
"[select=v:f=rtp:ssrc=22222222:payload_type=96]rtp://127.0.0.1:${ports.videoRtp}?rtcpport=${ports.videoRtcp}"`
Failed.
And also tried using gstreamer: (modified according to mediasoup-demo/gstreamer.sh at v3 · versatica/mediasoup-demo · GitHub )
const callRTPStreamPushCmd = `gst-launch-1.0 \
rtpbin name=rtpbin \
filesrc location=${input_mp4_filepath} \
! qtdemux name=demux \
demux.video_0 \
! queue \
! decodebin \
! rtph264pay pt=96 ssrc=22222222 picture-id-mode=2 \
! rtpbin.send_rtp_sink_0 \
rtpbin.send_rtp_src_0 ! udpsink host=127.0.0.1 port=${ports.videoRtp} \
rtpbin.send_rtcp_src_0 ! udpsink host=127.0.0.1 port=${ports.videoRtcp} sync=false async=false`
Also failed. How can i do a H264 RTP stream push with ffmpeg or gstreamer?
nazar-pc
(Nazar Mokynskyi)
July 23, 2021, 9:31am
4
You need to configure profile-level-id
to be the same as the video you’re using AND browser in question should support that particular profile. It is only really safe to use constrained baseline profile if you want H264 to work everywhere.
chenzx
(陈志祥)
July 23, 2021, 9:41am
5
Hi nazar-pc,
How can i know which is the correct profile-level-id
with my test input mp4 file? (i don’t want to use any transcoding at client side) and how can i know if chrome browser’s WebRTC+H264 stack supports this profile?
My test input mp4 file is 1080p with aac audio encoding(audio is not used here), is inout resolution the reason?
nazar-pc
(Nazar Mokynskyi)
July 23, 2021, 9:48am
6
Try ffprobe
and see what it says about the file.
ibc
(Iñaki Baz Castillo)
July 23, 2021, 10:09am
7
If you take a look to test folder in h246-profile-level-id library (created by us and used in mediasoup) you may figure it out. Otherwise you have to read the H264 RFC spec.
chenzx
(陈志祥)
July 23, 2021, 10:17am
8
I tried the value ffmpeg geneated in sdp file & the value from chrome://webrtc-internals page: 640028、640032、640015, none works
chenzx
(陈志祥)
July 23, 2021, 10:18am
9
% ffprobe ./test.mp4
…
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from './test.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.76.100
Duration: 00:01:31.61, start: 0.000000, bitrate: 1295 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 1158 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 59.94 tbc (default)
Metadata:
handler_name : Core Media Video
vendor_id : [0][0][0][0]
Stream #0:1(zho): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : Core Media Audio
vendor_id : [0][0][0][0]
nazar-pc
(Nazar Mokynskyi)
July 23, 2021, 10:24am
10
H264 High profile will not work in many browsers when sent over WebRTC (it will using <video>
tag though).
chenzx
(陈志祥)
July 23, 2021, 10:37am
11
I have converted the test.mp4 to constrained basic profile, but still not works:
% ffmpeg -i ./test_640p.mp4 -vcodec libx264 -acodec aac -b:a 256k -profile:v baseline test_640p_basic.mp4
The symptom: chrome page cannot receive RTP video stream data.
mediasoup server side log:
mediasoup:Channel request() [method:transport.consume, id:6] +5ms
mediasoup:Channel [pid:87109] RTC::SimpleConsumer::CreateRtpStream() | [ssrc:365044946, payloadType:96] +1ms
mediasoup:Channel [pid:87109] RTC::SimpleConsumer::CreateRtpStream() | FIR supported +0ms
mediasoup:Channel [pid:87109] RTC::SimpleConsumer::CreateRtpStream() | NACK supported +0ms
mediasoup:Channel [pid:87109] RTC::SimpleConsumer::CreateRtpStream() | PLI supported +0ms
mediasoup:Channel request succeeded [method:transport.consume, id:6] +1ms
mediasoup:Consumer constructor() +0ms
mediasoup:WebRtcTransport connect() +18ms
mediasoup:Channel request() [method:transport.connect, id:7] +10ms
mediasoup:Channel request succeeded [method:transport.connect, id:7] +1ms
mediasoup:Channel [pid:87109] RTC::IceServer::HandleTuple() | transition from state 'new' to 'connected' +8ms
mediasoup:Channel [pid:87109] RTC::WebRtcTransport::OnIceServerSelectedTuple() | ICE selected tuple +0ms
mediasoup:Channel [pid:87109] RTC::WebRtcTransport::OnIceServerConnected() | ICE connected +0ms
mediasoup:Channel [pid:87109] RTC::WebRtcTransport::MayRunDtlsTransport() | running DTLS transport in local role 'server' +1ms
mediasoup:Channel [pid:87109] RTC::WebRtcTransport::OnDtlsTransportConnecting() | DTLS connecting +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::Run() | running [role:server] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | DTLS handshake start +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'before SSL initialization'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | role: server, waiting:'before SSL initialization'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'before SSL initialization'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS read client hello'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS write server hello'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS write certificate'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS write key exchange'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS write certificate request'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS write server done'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | role: server, waiting:'SSLv3/TLS write server done'] +1ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS write server done'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS read client certificate'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS read client key exchange'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS read certificate verify'] +1ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS read change cipher spec'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS read finished'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS write change cipher spec'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | [role:server, action:'SSLv3/TLS write finished'] +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::OnSslInfo() | DTLS handshake done +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::CheckRemoteFingerprint() | valid remote fingerprint +0ms
mediasoup:Channel [pid:87109] RTC::DtlsTransport::GetNegotiatedSrtpCryptoSuite() | chosen SRTP crypto suite: SRTP_AEAD_AES_256_GCM +0ms
mediasoup:Channel [pid:87109] RTC::WebRtcTransport::OnDtlsTransportConnected() | DTLS connected +0ms
mediasoup:Consumer resume() +33ms
mediasoup:Channel request() [method:consumer.resume, id:8] +11ms
mediasoup:Channel request succeeded [method:consumer.resume, id:8] +1ms
mediasoup:Channel [pid:87109] RTC::Transport::HandleRtcpPacket() | PLI received, requesting key frame for Consumer [sender ssrc:1, media ssrc:365044946] +1ms
mediasoup:Channel [pid:87109] RTC::IceServer::HandleTuple() | transition from state 'connected' to 'completed' +33ms
mediasoup:Channel [pid:87109] RTC::WebRtcTransport::OnIceServerCompleted() | ICE completed +0ms
nazar-pc
(Nazar Mokynskyi)
July 23, 2021, 10:43am
12
What do you mean by “not works”? I don’t see any errors server-side, check browser logs and dev tools, see if it found decoder for this video.
chenzx
(陈志祥)
July 23, 2021, 10:52am
13
from chrome://webrtc-internals page, i can see 2 rtc inbound rtp video stream, no data received displayed here, normally there is H264 encoding info here
chenzx
(陈志祥)
July 23, 2021, 10:57am
14
normally if i use chrome page client to publish, mediasoup server log:
mediasoup:Producer constructor() +0ms
mediasoup:Channel [pid:87330] RTC::IceServer::HandleTuple() | transition from state 'connected' to 'completed' +41ms
mediasoup:Channel [pid:87330] RTC::WebRtcTransport::OnIceServerCompleted() | ICE completed +0ms
mediasoup:Channel [pid:87330] RTC::Producer::GetRtpStream() | ignoring RTX packet for not yet created RtpStream (ssrc lookup) +137ms
mediasoup:WARN:Channel [pid:87330] RTC::Producer::ReceiveRtpPacket() | no stream found for received packet [ssrc:3741614746] +0ms
mediasoup:Channel [pid:87330] RTC::Producer::CreateRtpStream() | [encodingIdx:0, ssrc:2379022241, rid:, payloadType:123] +0ms
mediasoup:Channel [pid:87330] RTC::Producer::CreateRtpStream() | FIR supported +0ms
mediasoup:Channel [pid:87330] RTC::Producer::CreateRtpStream() | NACK supported +0ms
mediasoup:Channel [pid:87330] RTC::Producer::CreateRtpStream() | PLI supported +0ms
mediasoup:Channel [pid:87330] RTC::Producer::ReceiveRtpPacket() | key frame received [ssrc:2379022241, seq:4653] +0ms
and then open subscribe page:
mediasoup:Channel [pid:87330] RTC::Transport::HandleRtcpPacket() | PLI received, requesting key frame for Consumer [sender ssrc:1, media ssrc:399602566] +0ms
mediasoup:Channel [pid:87330] RTC::IceServer::HandleTuple() | transition from state 'connected' to 'completed' +52ms
mediasoup:Channel [pid:87330] RTC::WebRtcTransport::OnIceServerCompleted() | ICE completed +0ms
mediasoup:Channel [pid:87330] RTC::Producer::ReceiveRtpPacket() | key frame received [ssrc:2379022241, seq:22431] +1ms
mediasoup:Channel [pid:87330] RTC::SimpleConsumer::SendRtpPacket() | sync key frame received +0ms
mediasoup:Channel [pid:87330] RTC::SimpleConsumer::SendRtpPacket() | sending sync packet [ssrc:399602566, seq:1, ts:503037965] from original [seq:22431] +0ms
The difference is, when using ffmpeg/gstream to do RTP stream push, seems no “key frame received” log?
nazar-pc
(Nazar Mokynskyi)
July 23, 2021, 11:23am
15
What is GOP/key frame interval in that video? It might be expected behavior if you have key frame interval of 8 seconds to have no video for around 8 seconds.
chenzx
(陈志祥)
July 23, 2021, 3:51pm
16
i wait about ~20s but there is no response in subscribe page.
i guess it’s not GOP
problem.
something error happened, causing the RTP streaming stuck
chenzx
(陈志祥)
July 26, 2021, 6:06am
17
according to 使用 WebRTC 的 GPU 加速流式传输 | 云架构中心 | Google Cloud
i changed rtp config to profile-level-id=42001f,payloadType=102
but still not working
nazar-pc
(Nazar Mokynskyi)
July 26, 2021, 7:17am
18
There must be something else. Maybe port or ssrc is incorrect in ffmpeg command.
chenzx
(陈志祥)
July 26, 2021, 10:39am
19
i checked the browser page ==> browser page
WebRTC streaming case, in chrome://webrtc-internals , i could see that the outbound video stream and the inbound one have different SSRC, also, why there is 2 inbound video streams?
initially, when i used the mediasoup’s official ffmpeg rtp push case(H264 file converted to VP8 encoding, everything works fine.) but why when i tried to directly use H264 video data, the streaming proc is blocked by something unknown?
chenzx
(陈志祥)
July 28, 2021, 6:23am
20
When i modify the ffmpeg RTP push stream command string by changing “libvpx” to “libx264”, H264 streaming is OK, except for “profile-level-id” is re-negotiated from “4d0032” in setting to “4d0015”.
I can see the server log says:
mediasoup:Channel [pid:12857] RTC::Producer::ReceiveRtpPacket() | key frame received [ssrc:22222222, seq:8122]
But the browser page consumer/player side is not playing video fluent, looks like “jumping from keyframe to next keyframe”? wierd.
But my mp4 file is already H264 encoded, why need re-encoding to let everything OK?
I’ll retry gstreamer case.