一 AirPlay 接收端描述

AirPlay是苹果的私有协议,苹果官方未开放api和sdk,目前相对权威的一份非官方协议文档。这篇文档详细描述了aiplay 服务发现、图片、音视频、镜像投屏的相关协议,给我们开发airplay设备提供了很好的参考。但是不足之处是文档已经有6年多时间没有更新过,对于IOS的新变化可能没有完全同步。在开发过程中我们可能会面临一些未知的坑,需要针对具体问题来逐一解决。

1.1 Airplay服务发现

Airplay设备启动之后可以发布两类服务:

1.RAOP (Remote Audio Output Protocol),用于音频传输。

2.AirPlay service 用于图片、视频、镜像等媒体的传输。

实现AIRPLAY协议的APP不需要再做任何配置就能发现同一网络中的接收端设备,这主要得益于Bonjour(基于M-DNS协议实现)。Bonjour:苹果为基于组播域名服务(multicast DNS)的开放性Zeroconf标准所起的名字。Zeroconf (零设置网络标准):全称为Zero configuration networking,中文名则为零配置网络服务标准,是一种用于自动生成可用IP地址的网络技术,不需要额外的手动配置和专属的配置服务器。具体例子为:用户拥有一台apple tv和一台iPhone5s,只要都连入到同一个无线局域网内,iphone4s就会自动找出apple tv,那么在播放音乐或者视频时候,用户只要点击推送,就可以讲音乐和视频推送到apple tv上播放

对于接收端,我们主要关注RAOP服务:

RAOP service from Device Name
name: 5855CA1AE288@Device Name
type: _raop._tcp
port: 49152
txt:txtvers=1ch=2cn=0,1,2,3da=trueet=0,3,5md=0,1,2pw=falsesv=falsesr=44100ss=16tp=UDPvn=65537vs=130.14am=AppleTV2,1sf=0x4

服务名称由设备的mac地址和设备名称组成。

TXT属性包括:

name value description
txtvers 1 TXT记录版本
ch 2 音频通道:立体声
cn 0,1,2,3 音频编解码格式
et 0,3,5 支持的加密类型
md 0,1,2 支持的元数据类型
pw false 接收端是否需要密码
sr 44100 音频码率
ss 16 音频采样率
tp UDP 支持的传输层协议
vs 130.14 服务端版本
am AppleTV2,1 设备模式

音频编解码

cn 描述
0 PCM
1 Apple Lossless (ALAC)
2 AAC
3 AAC ELD (Enhanced Low Delay)

IOS设备作为AirPlay客户端,发送的音频流默认是ALAC格式,安卓设备作为接收端,系统自带的MediaPlayer无法解码ALAC格式,因此需要先使用开源的代码对ALAC格式的音频流进行解码,解码生成PCM数据,最后可以通过AudioTrack来播放PCM流。

加密类型

et 描述
0 没加密
1 RSA (AirPort Express)
3 FairPlay
4 MFiSAP (3rd-party devices)
5 FairPlay SAPv2.5

元数据

md 描述
0 text 文本
1 artwork 插图
2 progress 播放进度

总结:

通过RAOP服务发现协议中的描述,可以知道Airplay接收端服务的名称、支持的音频编解码格式、加密类型以及音频播放的进度、插入、歌曲和歌手名称等。这些可以满足我们使用IOS手机或者pad向安卓平台AirPlay接收端同步歌曲的基本需求。

二 音频流传输

音频流传输采用RTSP(Real Time Streaming Protocol)协议 (RFC 2326)。实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学、网景和RealNetworks公司提交的IETF RFC标准。

音频传输协议主要包括:RTSP请求、RTP流、音量控制、元数据、认证、远程控制。

2.1 RTSP请求

OPTIONS请求向RTSP服务端询问它支持的方法,以Apple TV为例,它支持:ANNOUNCE, SETUP, RECORD, PAUSE, FLUSH, TEARDOWN, OPTIONS, GET_PARAMETER, SET_PARAMETER, POST and GET.当客户端知道服务端支持的方法之后,便可以通过这些方法名向服务器发送数据来实现指定的功能。我们来详细看一下主要的方法描述:

ANNOUNCE

通过SDP(Session Description Protocol)服务描述协议向RTSP服务端发送音频流数据的属性,编解码器和加密密钥等信息。

RECORD

RECORD请求启动音频流传输

FLUSH

FLUSH请求停止音频流传输

TEARDOWN

结束RTSP会话

2.2 RTP流

音频包完全符合RTP协议。控制和定时分组并不完全符合RTP标准。

2.3 音量控制

通过SET_PARAMETER请求可以用来调节音量。音量值是float类型,-144表示静音,音量范围在-30到0之间。

示例

client → serverSET_PARAMETER rtsp://fe80::217:f2ff:fe0f:e0f6/3413821438 RTSP/1.0
CSeq: 6
Session: 1
Content-Type: text/parameters
Content-Length: 20
User-Agent: iTunes/10.6 (Macintosh; Intel Mac OS X 10.7.3) AppleWebKit/535.18.5
Client-Instance: 56B29BB6CB904862
DACP-ID: 56B29BB6CB904862
Active-Remote: 1986535575volume: -11.123877
server → clientRTSP/1.0 200 OK
Server: AirTunes/130.14
CSeq: 6

2.4 元数据

SET_PARAMETER请求可以用来传输元数据,元数据内容包括:音频名称、作者名字、专辑名称、插图、音频时长。RTP-Info 头部包含了rtptime参数,表示元数据的有效时间。

2.5 认证

发送的音频数据需要通过RSA认证,所有的二进制数据需要使用Base64 (RFC 4648) 进行加密。

客户端:

  • 在ANNOUNCE 请求中,通过Apple-Challenge 发送128位随机数据。

  • 生成一个128位的AES key,使用RSA公钥加密。

服务端:

  • 使用RSA私钥解密AES key,AES key将被用来解密音频数据

  • 使用RSA私钥对Apple-Challenge进行签名,通过Apple-Response头部发送返回结果给客户端

客户端:

使用RSA公钥对Apple-Response进行解密,检查数字与之前发送的数字是否相同。

2.6 远程控制

airplay服务端可以通过DACP (Digital Audio Control Protocol)协议向客户端发送命令:改变当前播放的音轨状态、暂停、重播,调整播放列表等。airplay客户端通过在RTSP请求中包含DACP-ID头文件来告诉服务端自己支持的命令范围。

总结:

airplay客户端通过向服务端发送OPTIONS请求获取服务端支持的方法列表,随后可以向服务端发送这些命令来建立和结束RTSP会话。客户端发送的音频数据需要RSA认证:首先客户端通过RSA公钥加密128位的AES key,然后服务端通过RSA私钥解密key,随后使用解密后的key来解密音频负荷数据包。客户端可以SET_PARAMETER 请求来调节音量,传输音轨名称、专辑名手、作者名称、音轨播放进度等信息。airplay服务端可以通过DACP发送远程控制命令来实现:改变当前播放的音轨状态、暂停、重播,调整播放列表等。

三 代码参考实现

AirReceiver(https://github.com/fgp/AirReceiver)使用Java写的运行在PC端的AirPlay接收端

DroidAirPlay(https://github.com/pentateu/DroidAirPlay) 基于AirReceiver代码转换成安卓项目的实现代码

AndroidAirPlayReceiver(https://github.com/zhhp1121/AndroidAirPlayReceiver)基于DroidAirPlay改造后能直接使用的安卓工程

AirPlay Android接收端学习一 协议相关推荐

  1. Android Studio --- [学习笔记]RadioButton、CheckBox、ImageView、ListView、TCP的三次握手

    说明 源代码 在2.x里有TCP的三次挥手与四次握手,先对它进行简单的回答(百度).预计在下一篇里,会继续说明TCP 接上一篇: Android Studio - > [学习笔记]Button. ...

  2. Android RIL学习

    Android RIL学习 tomorrow.cyz@gmail.com 1.Android RIL概念 Android RIL是基于telephony 服务和raido 硬件层的抽象层.Androi ...

  3. android p2p 学习

    android p2p 学习 TCP的三次握手(建立连接)和四次挥手(关闭连接) http://www.cnblogs.com/Jessy/p/3535612.html C/S(客户/服务器)模型: ...

  4. android开发用百度识别图片格式,Android开发学习之路-机器学习库(图像识别)、百度翻译...

    对于机器学习也不是了解的很深入,今天无意中在GitHub看到一个star的比较多的库,就用着试一试,效果也还行.比是可能比不上TensorFlow的,但是在Android上用起来比较简单,毕竟Tens ...

  5. Android设备标准HID协议(外接输入设备)接入蓝牙扫描枪的各种坑与解决办法

    因工作需要最近在做一款蓝牙条码.二维码扫描器枪支持Android设备(执行标准HID协议)的外接输入设备,在开发过程中遇到一些问题,在此记录下来,以便供大家借鉴学习,希望有类似需求的同行少走些弯路.好 ...

  6. Android USB的AOA协议设备端(主机模式,配件模式),ADB连接

    USB的ADB/AOA协议(一种是ADB模式,一种是AOA模式).AOA协议是Google公司推出的用于实现Android设备与外围设备之间USB通信的协议. ADK中与USB配件模式相关的两个类是U ...

  7. JAVA软件海豚_[Java教程]海豚星空扫码投屏 Android 接收端 SDK 集成 六步骤

    [Java教程]海豚星空扫码投屏 Android 接收端 SDK 集成 六步骤 0 2020-08-20 12:00:32 扫码投屏,开放网络,独占设备,不需要额外下载软件,微信扫码,发现设备.支持标 ...

  8. Android逆向 学习Android安全和逆向开发的路线总结,啃下这些Framework技术笔记

    此篇整理了最完整的–Android逆向学习线路知识体系.希望给迷糊的入门者指出一个明确的方向. 真心建议:先正向开发几年再搞逆向吧--正向都不会破解的是啥?不看代码只会脱壳?只会xposed ?远远不 ...

  9. java/android 设计模式学习笔记(1)--- 单例模式

    前段时间公司一些同事在讨论单例模式(我是最渣的一个,都插不上嘴 T__T ),这个模式使用的频率很高,也可能是很多人最熟悉的设计模式,当然单例模式也算是最简单的设计模式之一吧,简单归简单,但是在实际使 ...

最新文章

  1. AI一周热闻:GitHub免费开放无限私有库;苹果市值蒸发超450亿美元;小米入股TCL...
  2. 程序员的疯狂:打工与创业的残酷区别
  3. 微服务平台的发展趋势
  4. linux sort命令
  5. 关于QMap的几点总结思考
  6. NC119-最小的k个数
  7. Docker入门-docker compose的使用
  8. Matplotlib常用库方法
  9. 2020年末总结,脚踏实地,一步一个脚印——致敬自己一年的心酸历程
  10. mysql查询某张表的所有外键_oracle中查询所有外键引用到某张表的记录
  11. spring mvc学习(15)Referenced file contains errors
  12. java变量命名规则_浅谈JAVA开发规范与开发细节(上)
  13. HTML_CSS_JS_JSON
  14. shell 脚本中 while 只执行一次
  15. inputstreamreader未关闭会导致oom_【搞定面试官】你还在用Executors来创建线程池?会有什么问题呢?
  16. tensorflow内存溢出问题
  17. CAS Tomcat实现单点登录
  18. ajax跨域请求wcf服务,jQuery ajax跨域发布到WCF休息服务
  19. 模拟信号幅度调制之AM
  20. 安卓桌面软件哪个好_每日提醒软件哪个好?电脑上有什么好用的可以每天提醒的桌面便签软件...

热门文章

  1. Springboot集成Durid远程连接数据库一直报ERROR 1045 (28000): Access denied for user
  2. 0x80070570文件或目录损坏且无法读取 CHKDSK修复方法
  3. 不想学python也不想写博客的第四天
  4. 小米vr一体机html,小米VR一体机体验:一款让你大开眼界的产品
  5. Iphone 免费申请App ID
  6. 备份oracle错误12546,解决了ORACLE数据备份出现Message 206错误
  7. python抢票系统代码及解说_python抢票程序
  8. 成功解决Exception unhandled RuntimeError run loop already started File: F:\Program Files\Python\Python
  9. spring注解是怎么实现的?
  10. 越想越难,越做越简单,电磁兼容性设计