RTP forwarding: some delay

124 views
Skip to first unread message

Roberto Ostinelli

unread,
Jan 17, 2022, 9:35:42 AM1/17/22
to meetecho-janus
Hello,
I'm using RTP forwarding to send webrtc media from server A to server B via RTP, and then issuing a watch request on server B to receive this media.

The order is:
  • I create an RTP receive mountpoint on server B, with id set to publisher_id. I wait for the "streaming": "created" response.
  • Then, I create an RTP forwarder on server A to the mount-point on server B. I wait for the "videoroom": "rtp_forward" success response.
  • Finally, I issue a watch request on server B for the mount-point with id publisher_id, and I forward the offer included in the "status": "preparing" response message to the browser, which then starts the proxying of trickles, candidates and the answer from the browser.
Everything works nicely, however most of the time it takes up to 60 seconds for the forwarded videos to show up in the browser. When the videos finally shows up, no logs appear in Janus.

Any ideas on what I am doing wrong that introduces this delay? Is there a specific message from Janus that I should be waiting for instead of what I'm doing?

Thank you for any insights someone may have for this.

Best,
r.

Note: if I use simple subscribe mechanisms on the same server, the videos appear almost instantaneously for all participants.

Lorenzo Miniero

unread,
Jan 17, 2022, 10:15:28 AM1/17/22
to meetecho-janus
Asked many times, the cause is a missing keyframe request. You need to enable RTCP in both mountpoint and forwarder. Check older responses for more info.

L.

Roberto Ostinelli

unread,
Jan 17, 2022, 2:36:03 PM1/17/22
to meetecho-janus
I did search in the group, and I think that I already do enable RTCP. Unless there's something more to it than just setting the audiortcpport and videortcpport?

mountpoint creation:

%{
  request: "create",
  type: "rtp",
  id: publisher_id,
  audio: true,
  video: true,
  audioport: rtp_config.audioport,
  videoport: rtp_config.videoport,
  audiopt: 111,
  videopt: 96,
  audiortcpport: rtp_config.audiortcpport,
  videortcpport: rtp_config.videortcpport,
  audiortpmap: "opus/48000/2",
  videortpmap: "VP8/90000"
}

Forward request:

%{
  request: "rtp_forward",
  room: janus_room_id,
  publisher_id: publisher_id,
  host: rtp_config.host,
  audio_port: rtp_config.audioport,
  video_port: rtp_config.videoport,
  audio_pt: 111,
  video_pt: 96,
  audiortcpport: rtp_config.audiortcpport,
  videortcpport: rtp_config.videortcpport
}


Do you see something obvious missing there?

Thank you,
r.

Lorenzo Miniero

unread,
Jan 18, 2022, 4:40:15 AM1/18/22
to meetecho-janus
Audio RTCP is useless at the moment. Your syntax for RTCP in the forwarder is wrong, check the docs for the right one.

L.

Roberto Ostinelli

unread,
Jan 18, 2022, 5:12:45 AM1/18/22
to meetecho-janus
Posting here in case someone experience the same things. There are some mismatch in snake_case / single word param names which is what got me.

The correct (aka working in Janus v0.11.3) syntax is the following.

mountpoint creation request (portion).

%{
    audio: true,
    audioport: 0,
    audiopt: 111,
    audiortcpport: 0,
    audiortpmap: "opus/48000/2",
    id: 4156689202136007071,

    request: "create",
    type: "rtp",
    video: true,
    videoport: 0,
    videopt: 96,
    videortcpport: 0,
    videortpmap: "VP8/90000"
},


Notice for instance the param name audioport. If audio_port is provided instead, Janus replies with:  "error" => "Missing mandatory element (audioport)", "error_code" => 453.
Response (portion):

%{
  "plugindata" => %{
    "data" => %{
      "created" => "mp-4156689202136007071",
      "permanent" => false,
      "stream" => %{
        "audio_port" => 10000,
        "audio_rtcp_port" => 10001,
        "description" => "mp-4156689202136007071",
        "id" => 4156689202136007071,
        "is_private" => false,
        "type" => "live",
        "video_port" => 10002,
        "video_rtcp_port" => 10003
      },
      "streaming" => "created"
    }
  }
  ...
}

In the response, the param name is audio_port.

Now, the forwarder request MUST have snake_case variables, so it should look something like (portion):

%{
    audio_port: 10000,
    audio_pt: 111,
    audio_rtcp_port: 10001,
    host: "192.168.56.4",
    publisher_id: 4156689202136007071,
    request: "rtp_forward",
    room: 5059931385069278060,
    video_port: 10002,
    video_pt: 96,
    video_rtcp_port: 10003
  }


And you'll get a response confirming that both channels and RTCP are set up (also in snake_case):

  "plugindata" => %{
    "data" => %{
      "publisher_id" => 4156689202136007071,
      "room" => 5059931385069278060,
      "rtp_stream" => %{
        "audio" => 10000,
        "audio_rtcp" => 10001,
        "audio_stream_id" => 3429034396,
        "host" => "192.168.56.4",
        "video" => 10002,
        "video_rtcp" => 10003,
        "video_stream_id" => 3001958328
      },
      "videoroom" => "rtp_forward"
    },
    "plugin" => "janus.plugin.videoroom"
  },

  ...
}

If you use the same variable naming in the forwarder request as in the mountpoint (so non-snake_case variables such as  audioport, etc), then the forwarder is created but doesn't work, see the difference in the response that is missing all of the port information:

"plugindata" => %{
    "data" => %{
      "publisher_id" => 5650305750134037649,
      "room" => 5059931385069278060,
      "rtp_stream" => %{"host" => "192.168.56.4"},
      "videoroom" => "rtp_forward"
    }
  },
  ...
}

Lorenzo, I appreciate both of your help and the work you do on Janus. I'm actually working to promote its usage. However, I can assure you that if I post to a mailing list I've previously read docs & examples, and unfortunately sometimes there are confusing elements, hence my original question.

I hope this can provide some feedback and help others.

All the best,
r.

Lorenzo Miniero

unread,
Jan 18, 2022, 5:17:39 AM1/18/22
to meetecho-janus
Glad this was sorted out! Sorry if you saw my messages as a "RTFM", that was not my intent: what I meant by "check the docs" was more in the sense of "if you check the docs you'll find the exact syntax", since I was on the run when I wrote than post and didn't have time to point out the specific differences myself.

The syntax is indeed different for the two plugins, which can be confusing but should in theory be expected, since different plugins should actually be seen as different applications, and so with potentially very different APIs respectively. While I try to keep them mostly consistent when I can, in several cases features are added to different plugins at different times, and so when changes are made I try to keep consistency within the plugin itself, rather than across different plugins.

L.

Roberto Ostinelli

unread,
Jan 18, 2022, 5:21:16 AM1/18/22
to meetecho-janus
I understand. Thank you for your dedication. :)

Best,
r.
Reply all
Reply to author
Forward
0 new messages