局域网镜像/屏幕共享/文件传输方案(MirrorCast/RTSP/RTP/RTCP/RTC/WebRTC/RTMP)

Airplay (可以广域网)

镜像原理: Airplay采集系统屏幕和声音,通过网络传输到Airplay Server上(APPLE TV) 自己在app上自建一个server将数据获取,然后再传输给对端app来显示
不能上架AppStore,只能私自搞一个企业证书的链接让用户下载
有法律风险


replaykit (可以广域网)

第一代只能获取某个app的数据,第二代可以获取某个app以及整个屏幕的数据
(操作路径:控制中心->屏幕录制->3d touch,选择指定的支持Replaykit的App即可)
A设备的某个app开启broadcast,然后系统检测出提供ReplayKit Live服务的App列表,手动选中某个app,配置参数,该app即可把数据推送到ReplayKit Live服务中
而在接收端中,则需要建立一个子进程Extendsion 去与ReplayKit Live服务建立连接并获取数据,然后再通过这个子进程Extendsion将数据喂给主进程(你的app)

子进程采集(YUV420的NV12存储方式)
采用H264压缩(H264数据量小 硬解也快)
然后数据通过socket传输到主进程(你的app发送端)
然后H264解码成YUV420给底层的音视频sdk


MirrorCast

WIFI联盟制定的标准, MirrorCast实际上就是WIFI联盟对支持WiFi Display设备的认证名称
基于WiFi Display技术,而WiFi Display技术的核心又是WiFi Direct技术(wifi直连)

优点:
1 局域网内,基于WIFI直连,不需要经过AP(路由器) 很稳定而且传输速率和帧率高
影响传输速率的因素 WIFI Direct端到端的延时 latency/lags

1) 受网卡影响
2) 受网络信道影响 因为有CSMA/CA策略 并不会导致信道冲突,
但是会导致信道的不断切换 从而导致延时

缺点:
1 只是局域网方案,广域网不行
2 机型兼容性问题 不兼容的一些老机器通过配置下发屏蔽了此功能

WiFi Direct定义了三种组件,分别如下:
(1)WiFi Direct Devices:即WiFi Direct中的实体设备,如source端设备与sink端设备。
(2)WiFi Direct Group Owner(GO): WiFi Direct中的一种角色,作用类似于Infrastructure BSS(basic service set)中的AP(Access Point)。
(3)WiFi Direct Group Client:(GC):WiFi Direct中的一种角色,作用类似于Infrastructure BSS中的STA(Station)。

WiFi Direct在构建Group时,首先通过WSC(WiFi Simple Configuration)进行安全信息的获取,接着,GC将协商好的安全信息去连接GO。

总体流程

发送端和接收端先通过WIFI Direct进行设备的发现和配对,获取到source和sink的ip地址(走的也是WIFI信道(1、6、11中选一个) 但是ip地址不是通过wifi获取的ip地址 是p2p的ip地址),然后基于该IP地址建立会话与参数协商(RTSP (建立两端的连接、协商音频编解码格式和视频format、拿到RTP的端口号),发送端采集、编码(H.264)、HDCP(加密)、流传输(RTP(UDP的socket)) 流控制(RTCP),接收端解码、(解密)、渲染播放


发现阶段(Discovery State): WIFI P2P

(1)设备发现: 分为search state 和 listen state 两种状态
过程:
Search:802.11扫描模式,在1、6、11频段发送probe request帧 不会去listen
Find: search state 和 listen state相互切换
在listen时会在1、6、11频段选一个监听 并且之后一直使用该channel直到结束
(2)服务发现:(option)
(3)GO协商(Group Owner Negotiation): 作用类似于Infrastructure BSS中的AP
由go Intent的值(0-15)确定谁做Group Owner 15一定做GO 默认为7
(4)激活 暂时/永久Group (P2P Invitation)

Source(sender)端
1 采集数据
2 编码 (H.264)
3 TS打包 加密(可选功能 )
|
|流传输
|
(Primary) Sink (Receiver)端
[Secondary Sink](option)(音频处理)
1 解码
2 解密( 若source端在RTSP协商阶段协商了 Link Content Protection Setup通过HDCP对音视频数据进行加密,则需要进行相应解密操作 )
3 渲染播放


Android端具体实现:

设备发现:
wifi p2p的发现原理 两端都开启WIFI Display功能并启动发现服务

开启wifiDisplay功能:
反射方式调用android.net.wifi.p2p.WifiP2pWfdInfo 类的setWfdEnabled等方法
开启发现服务:
调用WifiP2pManager的discoverPeers方法 这样source端开启WIFI Display功能即可搜索到该设备
开启广播监听相关事件并进行相关操作 如配对

WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION        
WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION
do  requestPeers
WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION
do  requestGroupInfo requestConnectionInfo 

请求配对连接

requestPeers

当source端点击了该设备,该设备会弹出一个连接邀请的选择框
点击接受邀请

配对连接成功去获取信息

requestGroupInfo

获取相关的group信息,isGO指自己是否为Group Owner 对端的ip、port等


权限:

    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

关闭:

send TEAR_DOWN
close rtp&rtcp socket
close rtsp socket
1 stopPeerDiscovery  
2 removeGroup
3 unregisterReceiver

注意:
1 只能获取GO的ip地址 若自己是GO 则要通过ARP表去获取对端设备的ip地址 此时的ARP table 会有p2p0标识 以及 MacAddress 若macAddr等于source端设备的macAddr(可以通过requestGroupInfo listener中获取) 则得到source的ip地址

若是自己提供source端 则可以自己定义GO 而系统的则是不同厂商固定了 所以可用性差

WifiP2pConfig wifiP2pConfig = new WifiP2pConfig();
wifiP2pConfig.groupOwnerIntent = 15;
Log.d("MainActivity", "  wifiP2pConfig.groupOwnerIntent "+  wifiP2pConfig.groupOwnerIntent );

2 默认port为7236 若自己是GO 则可以通过groupInfo获取source的WFD CtrlPort


建立会话与参数协商

RTSP(TCP Socket,默认端口为7236 采用 UTF-8 编码中的 ISO 10646 字符集) 用于会话建立与控制 是sink端去connect source端 在RTSP as a client
建立连接后进行RTSP协商。协商成功后建立会话,然后可以建立UIBC通道,用于Sink端反向控制Source端,该步骤为可选实现。接着对与传输的内容做加密保护(HDCP 见附2),最后,开始音频及视频流的传输与控制Payload Control

RTSP协议完整交互参考附1


数据传递与控制

RTP(UDP socket as a server 将端口传给RTSP去传给对端)用于获取真正数据流
为什么用RTP参考下方RTP

RTCP(UDP socket as a server 将端口传给RTSP去传给对端) 用来进行相关的流量监控和拥塞控制,保证实时传输的数据包的稳定性。

流传输

真实流是通过RTP Socket中获取的
创建RTP和RTCP的UDP socket as a server
然后传递RTP端口号给source(M3阶段)

隔离

本身就类似蓝牙那种 已经满足了进房后才允许连接 但是若A设备进房了,然后B立刻连接接收端去投 这种情况也可以加隔离 就是接收端去加多一个验证发送端的ip即可

为什么要发送端起虚服务 接收端那边进行进房判断以及ip判断不也可以吗
因为涉及到跨子网问题 或者关闭了组播

播放模块

解码
MirrorCast的视频编码方式为H.264,音频编码方式由RTSP阶段进行协商,如LPCM或者AAC编码方式
播放渲染


遇到的坑/问题:
0 Failed to connect via WiFi Direct. Other devices connect to the access point through different channels.
p2p连接没关闭,被占用了
一个手机的Wi-Fi某一时刻只能在一个频段上 所以若p2p与wifi信道不同 则会提示频道冲突 要先断开wifi连接?
都用了同一个信道导致冲突 要先断开wifi连接?

打开P2P的时候 需要打开WIFI 建立了连接后 是可以关闭的

1 java.net.ConnectException: Connection refused
1 ip地址或者端口错误
2 没有开启server
3 端口被占用 没有正确关闭好socket或者wifi direct 可以通过重启机器解除端口占用情况

2 RTP丢包问题
1 给RTP的UDP Socket 加个缓冲
2 网络问题
3 数据排序问题 要去重排

3 java.net.SocketException: Permission denied
加访问网络权限

    <uses-permission android:name="android.permission.INTERNET"/>

4 android.os.NetworkOnMainThreadException
原因:有在主线程执行的网络操作
解决:
1 将网络请求放在子线程中执行 最好采用该方式
2 若是有特殊需求,可以通过设置StrictMode去屏蔽

 StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy)

坑很多,如果真的要做,得解决了GO问题 通过ARP太不稳定 太慢了连接
8.0以上不能实现Miracast的接收端
9.0以上发送端也取消了这个功能 得自己做发送端 但是国内大部分厂商还是支持的

Demo链接:https://github.com/5ingwings/MirrorCast-SinkApp


RTSP (Real Time Streaming Protocol)

基于TCP/IP的应用层协议 是全双工的
主要进行建立会话与参数协商


RTP (Real-time Transport Protocol)

基于UDP 不保证可靠

ES (Elementary Stream) 音视频数据
PES (Packet Elemental Stream) 加了时间戳 对ES进行了分组打包操作
TS(Transport Stream) PES基础上加了传输识别信息 定长的

优点:
1 基于UDP,在实时音视频场景时延低
2 协议本身,如RTP包头中有很多流媒体特性的标识
比如用于帧边界标记的M标志位,方便接收端快速定位帧边界;比如负载类型字段,用来告诉接收端(或者播放器)传输的是哪种媒体格式,然后使用对应的解码器;比如时间戳字段,标识了数据流的时间戳,接收端可以利用这个时间戳来去除由网络引起的信息包的抖动,并且在接收端为播放提供同步功能
3 支持加密数据和身份验证功能
4 较少的首部开销
5 RTP的profile机制为具体的应用提供了非常大的灵活性,它将传输协议与具体的应用环境、具体的控制策略分开,传输协议本身只提供完成实时传输的机制,开发者可以根据不同的应用环境,自主选择合适的配置环境、以及合适的控制策略。

怎么实现可靠 通过RTCP?
由上层根据其重要性来选择性的重传。比如,对于I帧、P帧、B帧数据,在网络状况不好的情况下,可以考虑对B、P帧丢失的情况下不进行重传,只重传I帧


RTCP (Real-time Transport Control Protocol)

基于UDP
用来对RTP进行流控和服务控制,如进行保证可靠传输


附1

RTSP协议完整交互:

tryConnect rtsp socket host:192.168.49.118, port:7236

OPTIONS * RTSP/1.0
CSeq: 0
Require: org.wfa.wfd1.0

RTP session is running on port 38633
RTCP session is running on port 58672

RTSP/1.0 200 OK
Public: org.wfa.wfd1.0, GET_PARAMETER, SET_PARAMETER
Date: 2019 17:26:18 GMT+08:00
CSeq: 1

OPTIONS * RTSP/1.0
Require: org.wfa.wfd1.0
CSeq: 0

RTSP/1.0 200 OK
CSeq: 0
Public: org.wfa.wfd1.0, GET_PARAMETER, SET_PARAMETER, SETUP, PLAY, PAUSE, TEARDOWN

GET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0
CSeq: 1
Content-Length: 154
Content-Type: text/parameters

wfd_audio_codecs
wfd_video_formats
wfd_content_protection
wfd_client_rtp_ports
wfd_uibc_capability
wfd_standby_resume_capability
wd_initial_buffer

RTSP/1.0 200 OK
Content-type: text/parameters
Content-length: 372
CSeq: 1

wfd_audio_codecs: LPCM 00000002 00, AAC 00000001 00
wfd_video_formats: 78 00 01 01 00008400 00000000 00000000 00 0000 0000 00 none none
wfd_uibc_capability: input_category_list=HIDC;hidc_cap_list=Keyboard/USB, Mouse/USB, MultiTouch/USB, Gesture/USB, RemoteControl/USB;port=none
wfd_client_rtp_ports: RTP/AVP/UDP;unicast 38633 0 mode=play
wfd_content_protection: none

SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0
CSeq: 2
Content-Length: 441
Content-Type: text/parameters

wfd_audio_codecs: AAC 00000001 00
wfd_video_formats: 00 00 01 01 00000400 00000000 00000000 00 0000 0000 00 none none
wfd_presentation_URL: rtsp://255.255.255.255/wfd1.0/streamid=0 none
wfd_client_rtp_ports: RTP/AVP/UDP;unicast 38633 0 mode=play
wfd_uibc_capability: input_category_list=HIDC;generic_cap_list=none;hidc_cap_list=Keyboard/USB, Mouse/USB, MultiTouch/USB, Gesture/USB, RemoteControl/USB;port=4321
wfd_uibc_setting: enable

RTSP/1.0 200 OK
CSeq: 2

SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0
CSeq: 3
Content-Length: 27
Content-Type: text/parameters

wfd_trigger_method: SETUP


RTSP/1.0 200 OK
CSeq: 3

SETUP rtsp://192.168.49.118/wfd1.0/streamid=0 RTSP/1.0
Transport: RTP/AVP/UDP;unicast;client_port=38633
CSeq: 4

RTSP/1.0 200 OK
CSeq: 4
Date: Sat, Mar 16 2019 09:26:19 GMT
Session: 00000012
Transport: RTP/AVP/UDP;unicast;client_port=38633;server_port=19022

PLAY rtsp://192.168.49.118/wfd1.0/streamid=0 RTSP/1.0
Session: 00000012
CSeq: 4

RTSP/1.0 200 OK
CSeq: 4
Date: Sat, Mar 16 2019 09:26:20 GMT


发送端发起断开连接:
SET_PARAMETER rtsp://localhost/wfd1.0 RTSP/1.0
CSeq: 4
Content-Length: 30
Content-Type: text/parameters
Session: 00000012

wfd_trigger_method: TEARDOWN

自己回
RTSP/1.0 200 OK
CSeq: 4
Date: Sat, Mar 16 2019 09:26:21 GMT

PAUSE TEARDOWN(request 是SET_PARAMETER带body的TEARDOWN/PAUSE response的才是TEARDOWN/PAUSE作方法头)

PLAY之后 会有一个间断的GET_PARAMETER的交流   用于keep alive 

附2

高清数字内容保护(HDCP,High-Bandwidth Digital Content Protection)
是由英特尔公司所发展,用以确保数字化的影像与声音数据在透过DVI或HDMI接口发送时不至于遭到非法拷贝,MirrorCast的数据传输加密即采用该方式。


RTMP(Real Time Messaging Protocol)

基于 TCP 的流媒体传输协议,最大的特点是与 CDN 的强绑定,需要借助 CDN 的负载均衡系统将内容推送到接近用户的边缘节点,使用户就近取得所需内容,提高用户访问的响应速度和成功率,解决因分布、带宽、服务器性能带来的访问延迟问题。更多适用于站点加速、点播、短视频等场景。
适用场景: 在浏览图片、短视频等内容时用户感知不明显,对于不需要实时强互动的直播,比如体育赛事网络直播、演唱会网络直播、新闻现场直播,延迟是可以接受
缺点: 延迟稍微大一些 因为CDN的原因大概要3-5秒的延迟

优化点:

  • 主播不走CDN推流直接使用高速专用节点,优化主播间的延迟
  • RTMP Over UDP(Quic) 减少RTMP的延迟
  • 使用服务器合流减少观众的多路流带宽和性能压力
  • 使用P2P协议进行主播间的音视频传输,并由主播进行客户端合流推送到CDN

RTC (real time communication)

优点:低延时
缺点:使用 RTC 技术的成本比 RTMP+CDN 高。因为,从实践来看,UDP 传输比 TCP 传输对资源消耗要多,而且重传、封包、FEC 冗余计算等都会额外增加计算量,在多进程模式下可能还会遇到内存资源的过多消耗


WebRTC (web-based real-time communication )

RTC的子集,但是WebRTC本身也是包括很多东西 编解码等
是一种基于浏览器的实时通信的开源解决方案,使用 UDP 私有协议来进行媒体推流(无连接的,没有 TCP 连接断开时的挥手确认连接关闭的机制)

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值