1. 程式人生 > >Android MediaPlayer中的RTSP(一):RTSP簡介

Android MediaPlayer中的RTSP(一):RTSP簡介

背景:

我在最近的專案中遇到了使用Android的MediaPlayer來進行RTSP播放的場景。但對於RTSP這種流媒體協議,其實Android原生的播放器支援得不是很好,所以有許多需要修改的地方。

本文主要簡單介紹RTSP協議及其在MediaPlayer中的層級,後續會記錄下在專案中遇到的具體情況及對應的修改。

RTSP播放器架構

播放器的架構很清晰,
apk–>MediaPlayer->media_server–>廠商自己的Player(和NuPalyer/StagefrightPlayer一個層級)–>FFmpeg
如下圖。
 RTSP播放器架構
因為走Android MediaPlayer的流程,拉流的部分是使用FFmpeg實現的,所以FFmpeg是最核心的部分,主要的修改,也即是針對FFmpeg裡RTSP部分的修改,以適配專案的特殊性。

RTSP協議簡介

1、簡介

RTSP屬於應用層協議,被用於控制媒體流的傳輸,它為多媒體服務扮演“網路遠端控制”的角色,對流媒體提供了諸如暫停,快進等控制,而它本身並不傳輸資料。

因為RTSP的作用相當於流媒體伺服器的遠端控制,所以客戶端需要和伺服器進行命令互動,以到達建立/釋放連線及遠端控制的目的。命令連線基於TCP,一般使用554埠。而資料傳輸可以選擇TCP或UDP來傳送,這個需要看服務端的支援情況及客戶端的選擇。
RTSP負責建立和控制會話,RTP/TCP負責多媒體的傳輸,RTCP配合RTP做控制和流量統計,他們是合作的關係。
這裡寫圖片描述

2、RTSP的訊息

RTSP的訊息有兩大類,一是請求訊息(request),一是迴應訊息(response),兩種訊息的格式不同。

請求訊息格式:

方法 URI RTSP版本 CR LF
訊息頭 CR LF CR LF
訊息體 CR LF
其中方法包括OPTIONS、SETUP、PLAY、TEARDOWN等待,URI是接收方(服務端)的地址,例如:rtsp://192.168.22.136:5000/v0,每行後面的CR LF表示回車換行,需要接收端有相應的解析,最後一個訊息頭需要有兩個CR LF。

迴應訊息格式:

RTSP版本 狀態碼 解釋 CR LF
訊息頭 CR LF CR LF
訊息體 CR LF
其中RTSP版本一般都是RTSP/1.0,狀態碼是一個數值,200表示成功,解釋是與狀態碼對應的文字解釋。

狀態碼和HTTP差不多,由三位陣列成,表示方法執行的結果,定義如下:

1XX:保留,將來使用;
2XX:成功,操作被接收、理解、接受(received,understand,accepted);
3XX:重定向,要完成操作必須進行進一步操作;
4XX:客戶端出錯,請求有語法錯誤或無法實現;
5XX:伺服器出錯,伺服器無法實現合法的請求。

RTSP中定義的方法有:OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE, SCALE, GET_PARAMETER ,SET_PARAMETER 。
在下面的互動流程中的例子中,會簡單介紹這些方法的使用。

3 SDP各個引數簡單介紹

這裡寫圖片描述

注: “a=”欄位描述節目時長。直播用 clock=表示,描述直播時移時長;點播用 ntp=表示 ,描述點播節目時長。具體參見 rfc 2326。

舉例如下:
直播:直播時移時長為 1 小時
a=range:clock=20100817T000742.55Z-20100818T000742.55Z
點播: a=range:npt=0-246.655
注: “c=”欄位表示連線描述,可使用組播地址;如果是組播地址,欄位包含了媒體流的目的地址。也就是說,通過單播 rtsp 獲取當前直播頻道的組播地址,然後加入這個組播播放。具體參見 rfc 2326。例如: c=IN IP4 225.61.100.28/16
注: “m”欄位表示負載型別(PT): RTP 資訊包中的有效載荷域(Payload Type Field)的長度為 7位,因此 RTP 可支援 128 種不同的有效載荷型別。具體參見 rfc 3551。

SDP例子

DESCRIBE rtsp://61.149.64.212:554/live/ch11091521323921117877.sdp?playtype=1&boid=001&backupagent=61.149.64.212:554&clienttype=1&time=20180510144608+08&life=172800&ifpricereqsnd=1&vcdnid=001&userid=09-20170912003-01&mediaid=ch11091521323921117877&ctype=5&TSTVTimeLife=604800&contname=&authid=0&UserLiveType=1&stbid=801100c8bb1d8e97&nodelevel=3&terminalflag=1&bitrate=3 RTSP/1.0
Accept: application/sdp
CSeq: 2

RTSP/1.0 200 OK
Server: ZXUSS100 1.0
Cache-Control: no-cache
Content-Base: rtsp://61.149.64.212:554/live/ch11091521323921117877.sdp/
Content-Length: 267
Content-Type: application/sdp
CSeq: 2
Date: Thu, 10 May 2018 06:48:32 GMT
Expires: Thu, 10 May 2018 06:48:32 GMT

v=0
o=- 0 0 IN IP4 61.149.64.212
s=ZMSS RTSP Server
c=IN IP4 239.2.1.232/16 
b=AS:2500 
t=0 0
a=control:*
a=range:clock=20180503T064832.00Z-20180510T064832.00Z
m=video 8000 RTP/AVP 33
a=rtpmap:33 MP2T/90000
a=control:trackID=2
a=3GPP-Adaptation-Support:5

4、RTSP互動流程

一次基本的RTSP操作過程如下:

  1. 客戶端連線到流伺服器併發送一個RTSP描述命令(DESCRIBE)
  2. 流伺服器通過一個SDP描述來進行反饋,反饋資訊包括流數量、媒體型別等資訊
  3. 客戶端再分析該SDP描述,併為會話中的每一個流傳送一個RTSP建立命令(SETUP),RTSP建立命令告訴伺服器客戶端用於接收媒體資料的埠
  4. 客戶端傳送一個播放命令(PLAY),伺服器就開始在TCP/UDP上傳送媒體流(RTP包)到客戶端
  5. 在播放過程中客戶端還可以向伺服器傳送命令來控制快進、快退和暫停等
  6. 最後,客戶端可傳送一個終止命令(TERADOWN)來結束流媒體會話

例子如下:

/*OPTIONS 主要功能:獲取伺服器/客戶端支援的能力集,
關鍵欄位:
Public:伺服器支援的命令,在此例子中是用於獲取伺服器支援的命令,可以看到伺服器回覆我們支援DESCRIBE,OPTIONS,SETUP,TEARDOWN,PLAY,PAUSE,GET_PARAMETER,SET_PARAMETER
特殊說明:在一個RTSP互動流程中OPTIONS方法並不是必須的,前提是你知道伺服器支援哪些命令
*/
OPTIONS rtsp://61.149.64.212:554/live/ch11091521323921117877.sdp?playtype=1&boid=001&backupagent=61.149.64.212:554&clienttype=1&time=20180510144608+08&life=172800&ifpricereqsnd=1&vcdnid=001&userid=09-20170912003-01&mediaid=ch11091521323921117877&ctype=5&TSTVTimeLife=604800&contname=&authid=0&UserLiveType=1&stbid=801100c8bb1d8e97&nodelevel=3&terminalflag=1&bitrate=3 RTSP/1.0
CSeq: 1

RTSP/1.0 200 OK
Public: DESCRIBE,OPTIONS,SETUP,TEARDOWN,PLAY,PAUSE,GET_PARAMETER,SET_PARAMETER
Server: ZXUSS100 1.0 CSeq: 1

/*
DESCRIBE 主要功能:從伺服器獲取流媒體檔案格式資訊,從伺服器獲取流媒體檔案傳輸資訊
關鍵欄位:
Content-Type:一般是SDP
Content-length:一般是SDP的長度
特殊說明:媒體資訊通過SDP協議給出,例如這個例子中伺服器回覆range:clock=20180503T064832.00Z-20180510T064832.00Z,告訴客戶端伺服器的可時移range,並且是clock(絕對時間描述),也就是PLAY階段請求的時間是ISO 8601時間戳標準
*/
DESCRIBE rtsp://61.149.64.212:554/live/ch11091521323921117877.sdp?playtype=1&boid=001&backupagent=61.149.64.212:554&clienttype=1&time=20180510144608+08&life=172800&ifpricereqsnd=1&vcdnid=001&userid=09-20170912003-01&mediaid=ch11091521323921117877&ctype=5&TSTVTimeLife=604800&contname=&authid=0&UserLiveType=1&stbid=801100c8bb1d8e97&nodelevel=3&terminalflag=1&bitrate=3 RTSP/1.0
Accept: application/sdp
CSeq: 2

RTSP/1.0 200 OK
Server: ZXUSS100 1.0
Cache-Control: no-cache
Content-Base: rtsp://61.149.64.212:554/live/ch11091521323921117877.sdp/
Content-Length: 267
Content-Type: application/sdp
CSeq: 2
Date: Thu, 10 May 2018 06:48:32 GMT
Expires: Thu, 10 May 2018 06:48:32 GMT

v=0
o=- 0 0 IN IP4 61.149.64.212
s=ZMSS RTSP Server
c=IN IP4 239.2.1.232/16 
b=AS:2500 
t=0 0
a=control:*
a=range:clock=20180503T064832.00Z-20180510T064832.00Z
m=video 8000 RTP/AVP 33
a=rtpmap:33 MP2T/90000
a=control:trackID=2
a=3GPP-Adaptation-Support:5

/*
SETUP 主要功能:與伺服器協商流媒體傳輸方式,此過程中,建立RTP通道
關鍵欄位:
Transport:指明伺服器支援的傳輸方式及傳輸埠,地址等等資訊。
在例子中引數MP2T/RTP/UDP指明伺服器傳輸媒體資料將使用UDP傳輸;引數server_port=8000-8001;source=239.2.1.232指明瞭伺服器的地址和埠號;destination=192.168.1.4指明客戶端地址,這個例子中為內網地址,對於這種情況需要做NAT穿透。
特殊說明:需要注意的是,媒體伺服器的地址source=239.2.1.232,為組播地址,需要加入RTP組播來拉流。(但在此例子中,我試過使用該地址拉流也沒資料)
*/
SETUP rtsp://61.149.64.212:554/live/ch11091521323921117877.sdp/trackID=2 RTSP/1.0
Transport: MP2T/RTP/UDP;unicast;client_port=5000-5001
CSeq: 3

RTSP/1.0 200 OK
Server: ZXUSS100 1.0
CSeq: 3
Date: Thu, 10 May 2018 06:48:32 GMT
Expires: Thu, 10 May 2018 06:48:32 GMT
Session: 65536595
Transport: MP2T/RTP/UDP;destination=192.168.1.4;client_port=5000-5001;server_port=8000-8001;source=239.2.1.232

/*
PLAY 主要功能:與伺服器協商流媒體播放
關鍵欄位:
Range:播放時間支援兩種格式,Range: npt=0.0-end或者Range:clock=20100318T021919.35Z-20100318T031919.80Z
方法1 位置描述,相對時間描述——npt(normalplay time)
•beginning      節目起始點
•now            當前播放點
•end            節目結束點
•相對時間        媒體的相對時間
方法2 時間描述,絕對時間描述——clock,ISO 8601時間戳標準
•直接用數字形式表示與起始點的時間

Scale:播放速度 例如1倍速,Scale: 1.0
特殊說明:RTP-Info是前段回覆我們的媒體伺服器資訊,可以看到這裡和之前setup階段前端回覆的source地址並不一樣。
(這才是媒體伺服器的地址,這地方的衝突,可能是伺服器寫的不標準)
*/
PLAY rtsp://61.149.64.212:554/live/ch11091521323921117877.sdp/ RTSP/1.0
Range: clock=20180510T060000.00Z-
Scale: 1.0
CSeq: 4
Session: 65536595

RTSP/1.0 200 OK
Server: ZXUSS100 1.0
CSeq: 4
Range: clock=20180510T060000.00Z-20180510T064832.93Z
Scale: 1.0
Session: 65536595
RTP-Info: url=rtsp://61.149.64.132:12370/live/ch11091521323921117877.sdp/trackID=2;seq=0;rtptime=841899578

/*
GET_PARAMETER 主要功能:1、從伺服器獲取引數,目前主要獲取時間範圍;2、保持RTSP連線(傳送空的GET_PARAMETER)
在此例子中,是第二種用途,keep-alive
*/
GET_PARAMETER rtsp://61.149.64.212:554/live/ch11091521323921117877.sdp/ RTSP/1.0
CSeq: 5
Session: 65536595

RTSP/1.0 200 OK
Server: ZXUSS100 1.0
CSeq: 5
Session: 65536595

總結

本文介紹了一個相對簡單清晰的RTSP互動例項,但是在實際情況中,因為專案使用的是FFmpeg的RTSP來進行拉流的,特別是整合到MediaPlayer中使用,還是有許多情況需要考慮並完善的:

1、SETUP階段的協議選擇:載流協議是UDP還是TCP,是否使用RTP承載,嘗試一種載流協議不支援後的切換流程
2、重定向的完善:正常來說,一般在SETUP階段後,就不會再有重定向了,因為這樣需要重新斷開再連線,但是實際使用中有些伺服器是會在PLAY階段去重定向的
3、NAT穿透: 使用UDP載流時,處於內網的客戶端該如何進行NAT的打洞,以讓伺服器能將資料傳送給客戶端
4、與MediaPlayer的整合:PLAY中使用絕對時間描述時,該如何與MediaPlayer整合
5、媒體伺服器的選擇:即上面例子中提到的情況

這些是之前遇到的部分問題,我將在後續文章中說明這些問題。

相關推薦

Android MediaPlayerRTSPRTSP簡介

背景: 我在最近的專案中遇到了使用Android的MediaPlayer來進行RTSP播放的場景。但對於RTSP這種流媒體協議,其實Android原生的播放器支援得不是很好,所以有許多需要修改的地方。 本文主要簡單介紹RTSP協議及其在MediaPlayer

Android項目實戰 SpannableString與SpannableStringBuilder

append() 同時 uil 註意 1.5 查看 strong 尊重 bject 原文:Android項目實戰(一): SpannableString與SpannableStringBuilder前言: 曾經在一些APP中的一些類似“幫助”&ld

Android ANR分析實踐北京×××搭建ANR是什麽、產生的原因及如何避免ANR

例如 三種 handler 線程處理 不足 線程阻塞 種類 工具 input 一、 什麽是北京×××搭建 dsluntan.com VX:17061863513ANR ANR,(Application Not Responding) 即應用程序無響應,在android應

Android Skia程式設計系列Hello Skia

雖然在ndk文件中,google不推薦使用native C/C++來開發應用程式。但在實際開發中,可能不得不使用native C/C++的情況,比如跨平臺軟體開發。為手機開發軟體,為了能夠面向更廣泛的使用者群,免不了要同時開發symbian、windows mobile、an

android 開發問題集SDK更新後 執行程式報錯Location of the Android SDK has not been setup in the preferences

問題描述:android跟新後報錯location of the android sdk has not been setup in the preferences。eclipse裡的SDK Manager也打不開 原因:android跟新後ADT的版本過低造成的,但是有的人又因為跟新ADT失敗導致,也

Android Bluetooth Stack: Bluedroid綜述

    從Android 4.2開始,Bluetooth stack發生了重大改變:從Bluez換成了由Google和Broadcom聯合開發的Bluedroid(當然,核心的部分還是Broadcom的,Google主要是做了和上層Framework相關的部分)。通過htt

Android Studio 配置系列自定義程式碼註釋

1. 自定義檔案頭註釋 依次點選File -> Settings ->Editor ->File and Code Templates,在詳細展示視窗點選includes選項卡,找到FileHeader點選,在編輯視窗輸入自定義的註釋模板即可

C#可擴展編程之MEF學習筆記MEF簡介及簡單的Demo

com ring this exec hosting code .cn 引用 展開 在文章開始之前,首先簡單介紹一下什麽是MEF,MEF,全稱Managed Extensibility Framework(托管可擴展框架)。單從名字我們不難發現:MEF是專門致力於解決擴展性

微服務之SpringCloud乾貨SpringCloud簡介

什麼是微服務架構   微服務架構就是系統架構設計的一種風格,它主旨將一個獨立的系統,拆分成各個微服務,各個微服務獨立執行,他們之間通過Http的Restful API進行通訊,拆分出來的微服務是根據原系統高耦合部分進行構建(之後會單獨講解如何拆分微服務),每個微服務 都有自己的資料儲存(涉及到分散式事務的

GAN (生成式對抗網路) GAN 簡介

自從 Ian Goodfellow 在 14 年發表了 論文 Generative Adversarial Nets 以來,生成式對抗網路 GAN 廣受關注,加上學界大牛 Yann Lecun 在 Quora 答題時曾說,他最激動的深度學習進展是生成式對抗網路,使得 GAN 成為近年來在機器學習

JRtplib開發筆記JRtplib簡介、JThread庫編譯

原博主部落格地址:https://blog.csdn.net/qq21497936 本文章部落格地址:https://blog.csdn.net/qq21497936/article/details/84785284          

演算法演算法簡介

演算法簡介 ● 什麼是演算法        ➢一系列的計算步驟,用來將輸入資料轉化成輸出結果 ● 演算法的意義        ➢用於解決特定的問題        ➢解決同一個問題的不同演算法的效率常常相差非常大,這種差距的影響往往比硬體和軟體方面的差距還要大 ● 比較常聽到的

Git系列文章Git簡介

Git:一個開源的分散式版本控制系統,可以有效的高速的控制管理各種從小到大的專案版本。他的作者就是大名鼎鼎的Linux系統創始人Linus。 git命令教程:https://www.yiibai.com/git   常用的幾個命令: git init 初始化版本倉庫 git

python手記requests寫爬蟲爬蟲簡介

上次將python的圖片處理庫簡單寫了下,也就基本處於玩的地步。哈哈,蠻嘲諷的,這次我嘗試著寫下爬蟲,有多深肯定是不敢保證的,畢竟能力有限。但是我會盡量去從原理上把爬蟲的東西說明白一些。讓大家有個直觀的認識,最後能自己寫出個簡單的定向小爬蟲,爬個小說,爬個圖片,爬首歌曲什麼的

SpringBoot學習筆記SpringBoot簡介

SpringBoot為什麼這麼火? 為什麼學習SpringBoot?總的來說就是簡單。 使用SpringBoot免除了很多配置檔案,越來越容易上手。 更輕量級的Web開發,免除了我們以前的server(tomcat),我們只需要匯出一個jar包,用java -jar的方式啟動即可

python爬蟲系列爬蟲簡介

一 什麼是爬蟲 爬蟲:就是抓取網頁資料的程式。 二、爬蟲怎麼抓取網頁資料: 網頁三大特徵: -1. 網頁都有自己唯一的URL(統一資源定位符)來進行定位 -2. 網頁都使用HTML (超文字標

C#學習C#簡介

計算機硬件 主函數 符號 span options 不能 thread .net 動態鏈接 計算機語言計算機語言是指用於人與計算機之間通訊的語言機器碼——匯編語言——高級語言(面向過程(線性)、面向對象(類)、面向組件(Unity)) 一、計算機語言發展趨勢1、簡單:代碼生

從零開始微信機器人wxpy簡介登入、訊息傳送、註冊回覆

在過去的幾個月中,由於在新生群中回答問題費時費力,同時又有許多重複而又有固定答案的回答,我受到一些知乎文章的啟發,維護了一個基於itchat的群聊機器人。從剛開始接入圖靈機器人時只會尬聊的機器人,之後又加入了api.ai的按照訊息內容自動回覆,而後再加入了回覆表情功能

Redis系列Redis簡介

一、Redis概述   Redis是一個開源(遵循BSD協議)Key-Value資料結構的記憶體儲存系統,用作資料庫、快取和訊息代理。它支援5種資料結構:字串string、雜湊hash、列表list、集合set和有序的集合zset。Redis支援Lua指令碼,哨兵機制和叢集實現高可用。適用場景:快取、投票、抽

UniRx精講UniRx簡介&定時功能實現

# 1.UniRx 簡介 UniRx 是一個 Unity3D 的程式設計框架。它專注於解決時間上非同步的邏輯,使得非同步邏輯的實現更加簡潔和優雅。 ## 簡潔優雅如何體現? 比如,實現一個“只處理第一次滑鼠點選事件”這個功能,使用 UniRx 實現如下: ``` csharp Observable.Ever