Fix subscribers not closed when publisher is closed in Janus 1.x

In Janus 0.x when a publisher is closed the subscribers are also
automatically closed (if configured to do so, which is the default).
However, in Janus 1.x, as a subscriber can be connected to several
publishers, when a publisher is closed its subscribers just receive an
"updated" event with the new state of the streams.

As multistream connections are not used yet in Talk it still makes sense
to close its subscribers when a publisher is closed, so subscribers are
now automatically closed if they receive an "updated" event and all the
media streams are inactive (note that data channels will be always
active).

Note that, although it should not be received with the current usage of
Janus API, an "updated" event without streams could be received if the
subscriber was updated but there were no changes in the streams, so in
that case the subscriber should not be closed.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This commit is contained in:
Daniel Calviño Sánchez 2025-05-04 02:02:14 +02:00 committed by Joachim Bauch
commit 47f05c9163
No known key found for this signature in database
GPG key ID: 77C1D22D53E15F02

View file

@ -47,6 +47,23 @@ func (p *mcuJanusSubscriber) handleEvent(event *janus.EventMsg) {
case "destroyed":
log.Printf("Subscriber %d: associated room has been destroyed, closing", p.handleId)
go p.Close(ctx)
case "updated":
streams, ok := getPluginValue(event.Plugindata, pluginVideoRoom, "streams").([]interface{})
if !ok || len(streams) == 0 {
// The streams list will be empty if no stream was changed.
return
}
for _, stream := range streams {
if stream, ok := stream.(map[string]interface{}); ok {
if (stream["type"] == "audio" || stream["type"] == "video") && stream["active"] != false {
return
}
}
}
log.Printf("Subscriber %d: received updated event with no active media streams, closing", p.handleId)
go p.Close(ctx)
case "event":
// Handle renegotiations, but ignore other events like selected
// substream / temporal layer.