但,如果是需要帳號和密碼呢?
加密有二種格式:
1. Basic Authentication
Context context = getApplicationContext(); sUrl = "rtsp://xxxx"; sAccount = "xx"; sPassword = "xx"; Uri source = Uri.parse(sUrl); Map<String, String> headers = getRtspHeaders(); mediaPlayer.setDataSource(context, source, headers); Map<String, String> getRtspHeaders() { Map<String, String> headers = new HashMap<String, String>(); String basicAuthValue = getBasicAuthValue(sAccount, sPassword); headers.put("Authorization", basicAuthValue); return headers; } private String getBasicAuthValue(String usr, String pwd) { String credentials = usr + ":" + pwd; int flags = Base64.URL_SAFE | Base64.NO_WRAP; byte[] bytes = credentials.getBytes(); return "Basic " + Base64.encodeToString(bytes, flags); }上面是處理basic authentication的方式,
另外一個簡單的方式,是在路徑裡直接給定帳號和密號,例如: sUrl = "rtsp://admin:pwd@xxxx";
2. Digest Authentication
原本以為,如果是digest authentication,用sUrl = "rtsp://admin:pwd@xxxx"可能也可以,
但總是得到"error 100, Media server died"之類的錯誤訊息,
查了一下網路,得到的大都是 MediaPlayer不支援rtsp digest authentication的答案,
原本想放棄了,某天心血來潮,想說用Wireshark來抓一下封包看看,
結果發現,
在RTSP DESCRIBE封包裡,它的格式都對啊,也支援digest authentication,
(以上的截圖,有可能不是原來用MediaPlayer時所抓的,日子久了,有點忘記,但以下的分析的確是MediaPlayer的)
研究了一下DESCRIBE封包,username沒錯,uri沒錯,nonce是前一次發DESCRIBE時,RTSP server reply回來的,比了一下,也沒錯,
難道,是response算錯了?
response= md5(md5(username:realm:password):nonce:md5(uri));
自己手動算了一下,耶?真的有問題...
自己算的response和DESCEIBE 封包裡的response不一樣,
沒辦法,只好去看一下android裡的有關authentication 的 source codes,
原來在ARTSPConnection.cpp裡,它在算response時,
所用的realm不是從RTSP server Reply時取出的,
而是hard code成"Streaming Server",
難怪算出來的response不對,
雖然發現原因了,但好像也不能幹嘛,
因為我們只能透過 setDataSource(), 之後的事,有問題,也無能為力...
看來,要用RTSP Digest Authentication,只能放棄 MediaPlayer,改採它法
沒有留言:
張貼留言