目前从事无人机配套程序开发,之前一直使用的是RTMP进行直播流显示,由于网页端要弃用flash,转为使用WebRtc协议,改完后RTMP流延迟飙升,遂安卓端同步修改。
由于网络上大部分教程文章都是多人视频示例且不了解SRS和WebRtc通信流程 浪费了很多时间
本文章只涉及安卓端的webrtc流播放 适用于SRS推流
参考以下文章 macaruina
WebRTC源码研究(29)媒体能力协商过程
Web项目jswebrtc
SRS测试地址
1.SRS WebRtc通信流程
安卓端作为调用方 正常流程为由stable开始
createOffer->setLocalDescription->接收answer->setRemoteDescription
这里由于SRS的存在 接收answer这一步骤需要手动使用网络请求服务器进行创建answer操作 如下
请求接口后SRS会创建answer 并在接口返回Json数据包含spd 安卓端直接调用setRemoteDescription即可
2.安卓端整体代码
build.gradle
implementation 'org.webrtc:google-webrtc:1.0.32006'
布局
android:id="@+id/activity_main_svr_video"
android:layout_width="match_parent"
android:layout_height="match_parent" />
初始化EglBase PeerConnectionFactory
//初始化EglBase macaruina
EglBase.Context eglBaseContext = EglBase.create().getEglBaseContext();
PeerConnectionFactory.initialize(PeerConnectionFactory.InitializationOptions
.builder(context)
.createInitializationOptions());
//初始化PeerConnectionFactory macaruina
PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
DefaultVideoEncoderFactory encoderFactory =
new DefaultVideoEncoderFactory(eglBaseContext, true, true);
DefaultVideoDecoderFactory decoderFactory =
new DefaultVideoDecoderFactory(eglBaseContext);
PeerConnectionFactory peerConnectionFactory = PeerConnectionFactory.builder()
.setOptions(options)
.setVideoEncoderFactory(encoderFactory)
.setVideoDecoderFactory(decoderFactory)
.createPeerConnectionFactory();
//初始化SurfaceViewRenderer
surfaceViewRenderer.init(eglBaseContext, null);
//初始化peerConnectionFactory监听 macaruina
peerConnection = peerConnectionFactory.createPeerConnection(new ArrayList<>(),
new PeerConnection.Observer() {
......
@Override
public void onAddStream(MediaStream mediaStream) {
//在这里将流放进surfaceViewRenderer中 macaruina
mediaStream.videoTracks.get(0).addSink(surfaceViewRenderer);
}
......
});
peerConnection.createOffer(sdpObserver, new MediaConstraints());
SdpObserver sdpObserver = new SdpObserver() {
@Override
public void onCreateSuccess(SessionDescription sessionDescription) {
if (sessionDescription.type == SessionDescription.Type.OFFER) {
//设置setLocalDescription offer返回sdp macaruina
peerConnection.setLocalDescription(sdpObserver, sessionDescription);
//请求SRS服务器接口 macaruina
//HttpPost.....网络请求 得到结果后调用setRemoteDescription 传入返回的sdp
}
}
......
};
void setRemoteDescription(String sdp) {
SessionDescription remoteSpd = new SessionDescription(SessionDescription.Type.ANSWER, sdp);
peerConnection.setRemoteDescription(sdpObserver, remoteSpd);
}