diff --git a/plugins/janus_streaming.c b/plugins/janus_streaming.c index 27eab431ef..f9b73a32fd 100644 --- a/plugins/janus_streaming.c +++ b/plugins/janus_streaming.c @@ -144,6 +144,8 @@ The following options are only valid for the 'rtsp' type: url = RTSP stream URL rtsp_user = RTSP authorization username, if needed rtsp_pwd = RTSP authorization password, if needed +rtsp_quirk = Some RTSP servers offer the stream using only the path, instead of the fully qualified URL. + If set true, this boolean informs Janus that we should try a path-only DESCRIBE request if the initial request returns 404. rtsp_failcheck = whether an error should be returned if connecting to the RTSP server fails (default=true) rtspiface = network interface IP address or device name to listen on when receiving RTSP streams rtsp_reconnect_delay = after n seconds passed and no media assumed, the RTSP server has gone and schedule a reconnect (default=5s) @@ -1097,6 +1099,7 @@ typedef struct janus_streaming_rtp_source { char *rtsp_url; char *rtsp_username, *rtsp_password; char *rtsp_stream_uri; + gboolean rtsp_quirk; gint64 ka_timeout; char *rtsp_ahost, *rtsp_vhost; gboolean reconnecting; @@ -1222,7 +1225,7 @@ janus_streaming_mountpoint *janus_streaming_create_file_source( janus_streaming_mountpoint *janus_streaming_create_rtsp_source( uint64_t id, char *id_str, char *name, char *desc, char *metadata, char *url, char *username, char *password, - gboolean doaudio, int audiopt, char *artpmap, char *afmtp, + gboolean quirk, gboolean doaudio, int audiopt, char *artpmap, char *afmtp, gboolean dovideo, int videopt, char *vrtpmap, char *vfmtp, gboolean bufferkf, const janus_network_address *iface, int threads, gint64 reconnect_delay, gint64 session_timeout, int rtsp_timeout, int rtsp_conn_timeout, @@ -2133,6 +2136,7 @@ int janus_streaming_init(janus_callbacks *callback, const char *config_path) { janus_config_item *file = janus_config_get(config, cat, janus_config_type_item, "url"); janus_config_item *username = janus_config_get(config, cat, janus_config_type_item, "rtsp_user"); janus_config_item *password = janus_config_get(config, cat, janus_config_type_item, "rtsp_pwd"); + janus_config_item *quirk = janus_config_get(config, cat, janus_config_type_item, "quirk"); janus_config_item *audio = janus_config_get(config, cat, janus_config_type_item, "audio"); janus_config_item *artpmap = janus_config_get(config, cat, janus_config_type_item, "audiortpmap"); janus_config_item *acodec = janus_config_get(config, cat, janus_config_type_item, "audiopt"); @@ -2156,6 +2160,7 @@ int janus_streaming_init(janus_callbacks *callback, const char *config_path) { continue; } gboolean is_private = priv && priv->value && janus_is_true(priv->value); + gboolean rtsp_quirk = quirk ? TRUE : FALSE; gboolean doaudio = audio && audio->value && janus_is_true(audio->value); gboolean dovideo = video && video->value && janus_is_true(video->value); gboolean bufferkf = video && vkf && vkf->value && janus_is_true(vkf->value); @@ -2190,6 +2195,7 @@ int janus_streaming_init(janus_callbacks *callback, const char *config_path) { (char *)file->value, username ? (char *)username->value : NULL, password ? (char *)password->value : NULL, + rtsp_quirk, doaudio, (acodec && acodec->value) ? atoi(acodec->value) : -1, artpmap ? (char *)artpmap->value : NULL, @@ -2617,6 +2623,8 @@ static json_t *janus_streaming_process_synchronous_request(janus_streaming_sessi json_object_set_new(ml, "rtsp_user", json_string(source->rtsp_username)); if(source->rtsp_password) json_object_set_new(ml, "rtsp_pwd", json_string(source->rtsp_password)); + if(source->rtsp_quirk) + json_object_set_new(ml, "rtsp_quirk", json_true()); } } #endif @@ -3221,6 +3229,7 @@ static json_t *janus_streaming_process_synchronous_request(janus_streaming_sessi json_t *url = json_object_get(root, "url"); json_t *username = json_object_get(root, "rtsp_user"); json_t *password = json_object_get(root, "rtsp_pwd"); + json_t *quirk = json_object_get(root, "rtsp_quirk"); json_t *iface = json_object_get(root, "rtspiface"); json_t *threads = json_object_get(root, "threads"); json_t *failerr = json_object_get(root, "rtsp_failcheck"); @@ -3265,6 +3274,7 @@ static json_t *janus_streaming_process_synchronous_request(janus_streaming_sessi (char *)json_string_value(url), username ? (char *)json_string_value(username) : NULL, password ? (char *)json_string_value(password) : NULL, + quirk ? TRUE : FALSE, doaudio, (audiopt ? json_integer_value(audiopt) : -1), (char *)json_string_value(audiortpmap), (char *)json_string_value(audiofmtp), dovideo, (videopt ? json_integer_value(videopt) : -1), @@ -3418,6 +3428,7 @@ static json_t *janus_streaming_process_synchronous_request(janus_streaming_sessi janus_config_add(config, c, janus_config_item_create("rtsp_user", source->rtsp_username)); if(source->rtsp_password) janus_config_add(config, c, janus_config_item_create("rtsp_pwd", source->rtsp_password)); + janus_config_add(config, c, janus_config_item_create("rtsp_quirk", source->rtsp_quirk ? "yes" : "no")); #endif janus_config_add(config, c, janus_config_item_create("audio", mp->codecs.audio_pt >= 0 ? "yes" : "no")); if(mp->codecs.audio_pt >= 0) { @@ -3632,6 +3643,7 @@ static json_t *janus_streaming_process_synchronous_request(janus_streaming_sessi janus_config_add(config, c, janus_config_item_create("rtsp_user", source->rtsp_username)); if(source->rtsp_password) janus_config_add(config, c, janus_config_item_create("rtsp_pwd", source->rtsp_password)); + janus_config_add(config, c, janus_config_item_create("rtsp_quirk", source->rtsp_quirk ? "yes" : "no")); #endif janus_config_add(config, c, janus_config_item_create("audio", mp->codecs.audio_pt >= 0 ? "yes" : "no")); if(mp->codecs.audio_pt >= 0) { @@ -6522,7 +6534,7 @@ static int janus_streaming_rtsp_connect_to_server(janus_streaming_mountpoint *mp long code = 0; res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); #if CURL_AT_LEAST_VERSION(7, 62, 0) - if(code == 404) { + if(source->rtsp_quirk && code == 404) { /*Possibly a quirk in the RTSP server, where the DESCRIBE request expects a path only.*/ CURLU *curl_u = curl_url(); char *path = NULL; @@ -7110,7 +7122,7 @@ static int janus_streaming_rtsp_play(janus_streaming_rtp_source *source) { janus_streaming_mountpoint *janus_streaming_create_rtsp_source( uint64_t id, char *id_str, char *name, char *desc, char *metadata, char *url, char *username, char *password, - gboolean doaudio, int acodec, char *artpmap, char *afmtp, + gboolean quirk, gboolean doaudio, int acodec, char *artpmap, char *afmtp, gboolean dovideo, int vcodec, char *vrtpmap, char *vfmtp, gboolean bufferkf, const janus_network_address *iface, int threads, gint64 reconnect_delay, gint64 session_timeout, int rtsp_timeout, int rtsp_conn_timeout, @@ -7186,6 +7198,7 @@ janus_streaming_mountpoint *janus_streaming_create_rtsp_source( live_rtsp_source->rtsp_username = username ? g_strdup(username) : NULL; live_rtsp_source->rtsp_password = password ? g_strdup(password) : NULL; live_rtsp_source->rtsp_stream_uri = NULL; + live_rtsp_source->rtsp_quirk = FALSE; live_rtsp_source->arc = NULL; live_rtsp_source->vrc = NULL; live_rtsp_source->drc = NULL; @@ -7313,7 +7326,7 @@ janus_streaming_mountpoint *janus_streaming_create_rtsp_source( janus_streaming_mountpoint *janus_streaming_create_rtsp_source( uint64_t id, char *id_str, char *name, char *desc, char *metadata, char *url, char *username, char *password, - gboolean doaudio, int acodec, char *audiortpmap, char *audiofmtp, + gboolean quirk, gboolean doaudio, int acodec, char *audiortpmap, char *audiofmtp, gboolean dovideo, int vcodec, char *videortpmap, char *videofmtp, gboolean bufferkf, const janus_network_address *iface, int threads, gint64 reconnect_delay, gint64 session_timeout, int rtsp_timeout, int rtsp_conn_timeout,