技术背景
在 RTSP的 URL 中,如果包含用户名、密码以及特殊字符串,一般来说,需要遵循特定的格式和处理方式:
- 用户名和密码:RTSP URL 中包含用户名和密码时,通常使用
username:password@
的格式放在主机地址之前。例如:rtsp://admin:daniulive12345@192.168.1.100:554/cam/realmonitor?channel=1&subtype=0
,其中admin
是用户名,daniulive12345
是密码。 - 特殊字符处理:对于 URL 中包含的特殊字符,一般需要进行 URL 编码。URL 编码是将特殊字符转换为
%
加上两位十六进制数的形式。例如,空格字符 需要编码为%20
。假设你的 RTSP URL 中有一个路径包含空格,如rtsp://server/path with space/stream
,应该编码为rtsp://server/path%20with%20space/stream
。不同特殊字符对应的编码值是固定的,比如&
编码为%26
,?
编码为%3F
等。
技术实现
在实际应用中,不同的编程语言和库对 RTSP URL 的处理方式可能略有不同。以大牛直播SDK的RTSP播放器为例,我们的实现思路如下:
/*
* smart_player_sdk.h
* Created by daniusdk.com (C) All rights reserved.
*/
....
/*
* 设置RTSP用户名和密码
* 如果RTSP URL已包含用户名和密码, 此接口设置的用户名和密码将无效. 就是说要用这个接口设置的用户名和密码去做认证, RTSP URL不能包含用户名和密码.
* 例如:设置的RTSP URL:"rtsp://test:123@192.0.1.2/stream1", 调用这个接口设置的用户名:test2, 密码:456, 播放时不会用test2:456去做认证,
* 应该将URL设置为:"rtsp://192.0.1.2/stream1".
* user_name 和 password 不能包含URL编码串, 如果含有URL编码字符串, 请解码后再传入, 例如:user_name:"test%40123", 请先解码为:"test@123", 再传入
*/
NT_UINT32 (NT_API* SetRtspAuthenticationInfo)(NT_HANDLE handle, NT_PCSTR user_name, NT_PCSTR password);
....
demo调用示例如下:
auto new_url = try_remove_user_password_from_rtsp_url(url);
player_api_.SetURL(player_handle_, new_url.c_str());
player_api_.SetRtspAuthenticationInfo(player_handle_, user_name.c_str(), password.c_str());
if ( is_playing_ )
{
player_api_.StartPlay(player_handle_);
}
try_remove_user_password_from_rtsp_url()实现示例代码:
namespace {
/*
*实际中可能会遇到不规范的URL, 调用这个接口返回的结果不一定正确,如果不正确,请按实际URL特点自行解析
*/
std::string try_remove_user_password_from_rtsp_url(const std::string& in_url) {
const std::string protocol_prefix = "rtsp://";
auto pos = in_url.find(protocol_prefix);
if (pos == std::string::npos)
return in_url;
auto str1 = in_url.substr(protocol_prefix.length());
pos = str1.find('/');
auto last_at_pos = str1.rfind('@', pos);
if (last_at_pos == std::string::npos)
return in_url;
return protocol_prefix + str1.substr(last_at_pos + 1);
}
}