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 和更新版本上对此进行测试,但在旧版本上也可能如此。

希望这对以后的其他人有所帮助。