Android 的媒体播放器未添加自定义 Headers
Android's Media Player is not adding custom Headers
我正在尝试使用 Android 内置 MediaPlayer
class 来播放 RTSP 流。我已经编写了一个单独的库,可以正确形成我的 IP 摄像机所需的 Digest 身份验证。
我正在尝试使用以下代码附加生成的授权 header:
private void initPlayback(){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDisplay(mSurfaceHolder);
Context context = getActivity();
Map<String, String> headers = getRtspHeaders();
Uri source = Uri.parse(mCameraURI);
try {
// Specify the IP camera's URL and auth headers.
mMediaPlayer.setDataSource(context, source, headers);
// Begin the process of setting up a video stream.
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.prepareAsync();
}
catch (Exception e) {
}
}
出于测试目的,我在以下函数中对哈希图进行了硬编码:
private Map<String, String> getRtspHeaders() {
Map<String, String> headers = new HashMap<String, String>();
String digestAuthValue = "Digest username=\"admin\", realm=\"d8eb97cdf7d8\", nonce=\"3583e1908677b7af62f3e295eddec2f0\", uri=\"rtsp://10.20.30.62:554/Streaming/Channels/1?transportmode=unicast&profile=Profile_1\", response=\"42682812bfaf14b5406abafa179dabf9\"";
headers.put("Authorization", digestAuthValue);
return headers;
}
现在理论上我 运行:
mMediaPlayer.start();
它应该发送一个 DESCRIBE
请求,其中包含我添加的 header。
MediaPlayer
改为发送此数据包(使用 Wireshark/Ettercap 捕获):
DESCRIBE rtsp://10.20.30.62:554/Streaming/Channels/1?transportmode=unicast&profile=Profile_1 RTSP/1.0
Accept: application/sdp
User-Agent: stagefright/1.2 (Linux;Android 5.1.1)
CSeq: 1
我一直跟踪到本机代码的函数调用,但仍然无法弄清楚为什么它不添加这个 header。这些值一直到 MediaPlayer
中的 nativeSetDataSource
调用,并且看起来仍然正确。据我所知,我没有办法在本机代码中放置断点。
任何指导将不胜感激。
最终我的 co-worker 和我能够深入研究 Android 源代码以找到解决方法,但还不足以真正找出为什么自定义 header 未添加。
特别是 Authorization
headers 你实际上可以传递 MediaPlayer
一个修改过的 uri。在 rtsp 流的情况下,它看起来像这样:
rtsp://user:password@192.168.0.3:554/stream
当用户名和密码在 uri 中时,Android MediaPlayer
实际上会将它们提取出来并放入授权 header 中(使用 WireShark 验证)。我们能够在 Android 4.0 和更新版本上对此进行测试,但在旧版本上也可能如此。
希望这对以后的其他人有所帮助。
我正在尝试使用 Android 内置 MediaPlayer
class 来播放 RTSP 流。我已经编写了一个单独的库,可以正确形成我的 IP 摄像机所需的 Digest 身份验证。
我正在尝试使用以下代码附加生成的授权 header:
private void initPlayback(){
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDisplay(mSurfaceHolder);
Context context = getActivity();
Map<String, String> headers = getRtspHeaders();
Uri source = Uri.parse(mCameraURI);
try {
// Specify the IP camera's URL and auth headers.
mMediaPlayer.setDataSource(context, source, headers);
// Begin the process of setting up a video stream.
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.prepareAsync();
}
catch (Exception e) {
}
}
出于测试目的,我在以下函数中对哈希图进行了硬编码:
private Map<String, String> getRtspHeaders() {
Map<String, String> headers = new HashMap<String, String>();
String digestAuthValue = "Digest username=\"admin\", realm=\"d8eb97cdf7d8\", nonce=\"3583e1908677b7af62f3e295eddec2f0\", uri=\"rtsp://10.20.30.62:554/Streaming/Channels/1?transportmode=unicast&profile=Profile_1\", response=\"42682812bfaf14b5406abafa179dabf9\"";
headers.put("Authorization", digestAuthValue);
return headers;
}
现在理论上我 运行:
mMediaPlayer.start();
它应该发送一个 DESCRIBE
请求,其中包含我添加的 header。
MediaPlayer
改为发送此数据包(使用 Wireshark/Ettercap 捕获):
DESCRIBE rtsp://10.20.30.62:554/Streaming/Channels/1?transportmode=unicast&profile=Profile_1 RTSP/1.0
Accept: application/sdp
User-Agent: stagefright/1.2 (Linux;Android 5.1.1)
CSeq: 1
我一直跟踪到本机代码的函数调用,但仍然无法弄清楚为什么它不添加这个 header。这些值一直到 MediaPlayer
中的 nativeSetDataSource
调用,并且看起来仍然正确。据我所知,我没有办法在本机代码中放置断点。
任何指导将不胜感激。
最终我的 co-worker 和我能够深入研究 Android 源代码以找到解决方法,但还不足以真正找出为什么自定义 header 未添加。
特别是 Authorization
headers 你实际上可以传递 MediaPlayer
一个修改过的 uri。在 rtsp 流的情况下,它看起来像这样:
rtsp://user:password@192.168.0.3:554/stream
当用户名和密码在 uri 中时,Android MediaPlayer
实际上会将它们提取出来并放入授权 header 中(使用 WireShark 验证)。我们能够在 Android 4.0 和更新版本上对此进行测试,但在旧版本上也可能如此。
希望这对以后的其他人有所帮助。