關於airplay協議實現鏡像功能研究

工作中需要研究airplay以實現IOS的鏡像服務端,將瞭解到的內容記錄下來。

 

Airplay可以實現將設備中音頻、視頻、圖像通過本地無線網絡發送遠端設備;Airplay功能實現利用了很多標準協議,包括multicast DNS,HTTP,RTSP,RTP,RAOP,NTP,見下表1

AirPlay Technology

Display photos and slideshows

Stream audio

Stream video

Display mirroring

Commonly Know as

-

AirPlay, AirTunes

AirPlay

AirPlay Mirroring

Used Protocols, Technology

HTTP

RAOP, RTSP, RTP

HTTP

HTTP, NTP

 

Bonjour是蘋果爲基於組播域名服務(multicast DNS)的開放性零設置網絡標準所起的名字。使用Bonjour的設備在網絡中自動傳播它們自己的服務信息並聆聽其它設備的服務信息,設備之間就象在打招呼,這也是命名爲Bonjour(法語:你好)的原因

 

 

ios手機接入wifi後用wireshark抓包能夠看到192.168.1.100 向 224.0.0.251 port 5353 發送廣播.

 


 

操作手機,打開媒體播放器時,ios會用MDNS發送Queries,其中有兩項服務_raop._tcp.local_airplay._tcp.local,如下圖:

 

 

 

AirplayBonjour做設備發現,在windows中安裝BonjourSDKforWin,在任務管理器中有mDNSResponder.exe進程用於mdns協議處理。

 

 

----------------------------------------------------------------------------------

BonjourSDK Demo

 

BonjourSDK文件夾中Samples目錄是一個示例工程,將該工程編譯運行,進行測試並對MDNS抓包分析如下:

dns-sd.exe -I   (Test registering and then immediately updating TXT record)

 

 

pid_t pid = getpid();/*current process id*/
Opaque16 registerPort = { { pid >> 8, pid & 0xFF } };
static const char TXT[] = "\x09" "Test Data";
printf("Registering Service Test._testtxt._tcp.local.\n");
err = DNSServiceRegister(&client, 0, opinterface /*kDNSServiceInterfaceIndexAny*/, "Test", "_testtxt._tcp.", "", NULL, registerPort.NotAnInteger, 0, NULL, reg_reply, NULL); 
if (!err) err = DNSServiceUpdateRecord(client, NULL, 0, sizeof(TXT)-1, TXT, 0);
break;

上面這段代碼在mDns中註冊一個服務,對應在MDNS數據包中會有一個QueryAuthoritativeDNSServiceRegister函數的第三個參數爲kDNSServiceInterfaceIndexAny指定Query中Type=ANY,第四個參數是服務名稱、第五個參數是支持協議名稱,第四、五個參數組合成Name,服務端口號爲registerPort,在這個DEMO中是該進程ID(7948),如下如所示:

 

 

由於上面有query Test._Testtxt._tcp.local,那麼mDNS正常對這個query進行應答,由於在query指定TYPE=ANY,所以Answers中除了Test._testtxt.tcp.local外,還有其它服務信息。

DEMO程序中DNSServiceUpdateRecord用於更新TXT文本,如下圖所示,在Answers中的TXT字段信息中TXT內容爲DEMO程序中所設置的“Test Data”。

 

 

 

 

----------------------------------------------------------------------------------

Airplayer

 

在網上找到一款可以在windows使用的Airplay服務端(AirPlayer),當然首先需要安裝Bonjour,AirPlayer可以實現將ios音頻、圖像同步在pc端播放,也可以將ios屏幕鏡像到pc,我使用wireshark抓包情況如下:

 

1.Airplayer程序啓動後,首先向mDNS註冊了兩個服務,分別支持兩個不同的協議_airplay_raop_airplay協議用於視頻傳輸,_raop用於音頻流傳輸(可參考表1)。

 

 

2.接下來Airplayer程序會針對_airplay_raop這兩個服務Answers進行服務描述。

  iTools[CMCC-BAIJIE]._airplay._tcp.local描述airplay協議服務端口爲648850C54A5569D80@iTools[CMCC-BAIJIE]._raop._tcp.local描述raop協議服務端口爲64886

  重點在於兩個服務分別對TXT的描述部份,如下圖:

 

 

協議TXT描述內容必需按Airplay協議標準要求進行描述,該標準在網上未能找到官方文檔,但有一個非官方資料可供參考,地址如下:

http://nto.github.io/AirPlay.html

 

我們以_airplay協議TXT描述內容爲例,對照Airplay.html文檔來看應該不難理解吧..

iTools[CMCC-BAIJIE]._airplay._tcp.local: type TXT, class IN, cache flush

deviceid=0c:54:a5:56:9d:80

features=0x100029FF

flags=0x4

model=AppleTV3,1

srcvers=150.33

vv=1

 

Airplay.html文檔中內容描述如下:

AirPlay service

name: Apple TVtype: _airplay._tcpport: 7000txt: deviceid=58:55:CA:1A:E2:88 features=0x39f7 model=AppleTV2,1 srcvers=130.14

The following fields are available in the TXT record:

name

value

description

model

AppleTV2,1

device model

deviceid

58:55:CA:1A:E2:88

MAC address of the device

features

0x39f7

bitfield of supported features

pw

1

server is password protected

The pw field appears only if the AirPlay server is password protected. Otherwise it is not included in the TXT record.

The features bitfield allows the following features to be defined:

bit

name

description

0

Video

video supported

1

Photo

photo supported

2

VideoFairPlay

video protected with FairPlay DRM

3

VideoVolumeControl

volume control supported for videos

4

VideoHTTPLiveStreams

http live streaming supported

5

Slideshow

slideshow supported

7

Screen

mirroring supported

8

ScreenRotate

screen rotation supported

9

Audio

audio supported

11

AudioRedundant

audio packet redundancy supported

12

FPSAPv2pt5_AES_GCM

FairPlay secure auth supported

13

PhotoCaching

photo preloading supported

 

這裏需要說明的是,在Screen Mirroring(鏡像)的功能處理中,airplay提供的端口號64885並未使用,而是client直接連接7100這個端口,關於這點在《Unofficial AirPlay Protocol Specification》中有相關描述。

Screen mirroring does not use the standard AirPlay service. Instead it connects to an apparently hard-coded port 7100

Airplay中的roap服務0C54A5569D80@iTools[CMCC-BAIJIE]._raop._tcp.local,這裏的0C54A5569D80@iTools[CMCC-BAIJIE]做爲name使用,且必須以這樣的格式命名,不然airplay的手機端不會識別,0C54A5569D80串字符爲本機的物理地址。

當pc上的接收端程序DEMOAirplayer應用退出時,也就是所註冊的服務關閉時,mDNS廣播服務註銷消息,在數據包Answers中的服務項指定Time to live = 0,宣告服務停止。

 

 

 

 

=======================================

 

現在開始嘗試註冊自己的服務,希望最終能夠達到可以鏡像同步的目地。首先需要先註冊一個自己的_airplay服務併發布到mDNS,這是第一步,也就是先要在IOS手機的airplay選項中找到自己,如果自己重新實現mDNS服務耗時就太長了,先做DEMO的話我們可以利用一下SDK中的例子,簡單修改一下就OK,我在dns-sd 示例工程的main函數中加入下面代碼:

 

#ifdef _DEMO
Demo:
	{

#define kRaopPort	50001
#define kAirplayPort	50002

		static DNSServiceRef airplayRef    = NULL;
		static DNSServiceRef raopRef    = NULL;

		Opaque16 AirplayPort = { { kAirplayPort >> 8, kAirplayPort & 0xFF } };
		Opaque16 RaopPort = { { kRaopPort >> 8, kRaopPort & 0xFF } };

		static const char AirplayTXT[] = 
			"\x1A" "deviceid=0c:54:a5:56:9d:80" \
			"\x0F" "features=0x3FFF"; \
			//"\x10" "model=AppleTV3,1";
			//"\x0E" "srcvers=150.33";

		static const char RaopTXT[] = 
			"\x06" "tp=UDP" \
			"\x08" "sm=false" \
			"\x08" "sv=false" \
			"\x04" "ek=1" \
			"\x06" "et=0,1" \
			"\x06" "cn=0,1" \
			"\x04" "ch=2" \
			"\x05" "ss=16" \
			"\x08" "sr=44100" \
			"\x08" "pw=false" \
			"\x04" "vn=3" \
			"\x09" "txtvers=1";
			

		err = DNSServiceRegister(&airplayRef, 0, opinterface, "JieTools", "_airplay._tcp.", "", NULL, AirplayPort.NotAnInteger, 0, NULL, reg_reply, NULL);
		if (!err) err = DNSServiceUpdateRecord(airplayRef, NULL, 0, sizeof(AirplayTXT)-1, AirplayTXT, 0);

		err = DNSServiceRegister(&raopRef, 0, opinterface, "0C54A5569D80@JieTools", "_raop._tcp.", "", NULL, RaopPort.NotAnInteger, 0, NULL, reg_reply, NULL);
		if (!err) err = DNSServiceUpdateRecord(raopRef, NULL, 0, sizeof(RaopTXT)-1, RaopTXT, 0);

		while(1)getchar();
		
		return 0;
	}
#endif

前兩行定義指定服務端口,而後的AirplayTXT與RaopTXT分別兩個服務的描述內容,下面對AirplayTXT做簡單說明:

"\x1A"這樣的寫法,是爲字符串前添加長度字值,爲16進制,deviceid後面的值是本機網卡的物理地址,features這個參數不能少,它是airplay服務所支持的特性或能力描述,其它的參數可以忽略。

RaopTXT描述內容是我通過抓包COPY下來的,沒有修改過;再接下來調用了兩個mDNS SDK中的兩個API,DNSServiceRegister用於註冊,DNSServiceUpdateRecord用來更新服務的TXTRecord信息。

這裏有兩組調用服務註冊,這裏需要注意的是,如果你想實現_airplay服務,那麼就必須將這兩個服務一起註冊,並且服務名稱必須一致,如第四個參數是服務名稱“JieTools”及“0C54A5569D80@JieTools”,注意命名規則。

 

OK,不出意外的話,運行它,打開你的手機,就能在airplay中發現自己註冊的這個服務了。



未完待續 .....


 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章