分享

基于webrtc的android和windows音视频通讯

 柠檬冰啡咖 2018-04-18

经过了数月的努力,浪费了一大把时间去搞这东西,总算有个样子了。话说经历了曲折过程真是让人觉得倍感心酸啊。

  • 前三个月百度了很多教程下载不到webrtc的代码只有用热心网友们提供的webrtc代码;vs的工程慢慢的编译通过了,简单的修改跑通了windows对windows的音视频功能;如果想在一台机器上做测试需要改下代码:
void Conductor::AddStreams() {
    if (active_streams_.find(kStreamLabel) != active_streams_.end())
        return;  // Already added.

    rtc::scoped_refptr<webrtc::AudioTrackInterface> audio_track(
        peer_connection_factory_->CreateAudioTrack(
        kAudioLabel, peer_connection_factory_->CreateAudioSource(NULL)));

    rtc::scoped_refptr<webrtc::MediaStreamInterface> stream =
        peer_connection_factory_->CreateLocalMediaStream(kStreamLabel);

    cricket::VideoCapturer *video = OpenVideoCaptureDevice();
    if (video)
    {
        rtc::scoped_refptr<webrtc::VideoTrackInterface> video_track(
            peer_connection_factory_->CreateVideoTrack(
            kVideoLabel,
            peer_connection_factory_->CreateVideoSource(video,
            NULL)));
        main_wnd_->StartLocalRenderer(video_track);

        stream->AddTrack(video_track);
    }

    stream->AddTrack(audio_track);

    if (!peer_connection_->AddStream(stream)) {
        LOG(LS_ERROR) << "Adding stream to PeerConnection failed";
    }
    typedef std::pair < std::string,
        rtc::scoped_refptr<webrtc::MediaStreamInterface> >
        MediaStreamPair;
    active_streams_.insert(MediaStreamPair(stream->label(), stream));
    main_wnd_->SwitchToStreamingUI();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

注意:这里主要是因为摄像头是程序独占的,打开一个peerconnect_client.exe以后不能在本机再次开一个,否则视频时候找不到摄像头就崩溃了。当然你机器多的话可忽视上面代码!

  • 由于觉得webrtc的peer_connetc工程写的很清晰明了,觉得android也应该是很简单的,后来才发现并非如此。由于鄙人学个java,soandroid学起来并不难,对我理解android对于java就行Qt对于c++一样,都是对语言的一种封装(当然我只是打个比方,不恰当的话请见谅)。同样经过了许多努力才搞到了android版本的webrtc代码,(感谢@Antonius http://blog.csdn.net/chenyafei617/article/details/38085409),仔细研究了andoroid对webrtc的封装,感慨为何c++为何没有java那么简洁优雅的语法呢?
  • 很快就是着手做android的开发,由于网络通讯用了rsa+aes加密,服务器用的c++,所以服务器要处理c++客户端和android不同平台发过来的数据包(加密、解密、转发等等),在处理跨平台加密上面浪费了两三周的时间,经过不屑的努力,嘿嘿终于能相互通讯了。下面就是痛苦的开始!!!
  • 首先像peerconnect_client.exe一样,android先给windows客户端发送sdp数据(包含了 ip、端口、音视频编解码等信息),当windows客户端收到第一个sdp数据时(一共需要发送5个,后面4个主要是用于传输、打动、转发等等)崩溃了!!!我开始怀疑是java和c++不同编码的问题吗,可我用的都是utf-8的编码而且都是英文和数字,无语的很;于是我打印了android对windows的sdp日志A,有打印了windows对windows的sdp日志B,经过比较发现:两个sdp数据结果完全一样,包含的数据乃至属性信息都完全一样!!后来多次调试,又浪费了大约一个月的时间,我放弃了。。。。。。
  • 我开始不再想这个问题,老婆问我为啥看不到你研究东西了,我说:没思路,做不下去了。
  • 无意间我想起我以前的同事有个日本的vps,而且送给我一个vpn账号;我侥幸试了一下(大约半夜了)下载速度非常可观,有400k/s,我开始尝试下载webrtc的最新代码,sync、 runhook了不知道多少次都失败了,几乎又浪费了一个月。后来在github认识了一个老外@vsimon,用我不咋滴的英语沟通了下,它提供了一个下载代码的shell脚本,我万分感谢。他的主页https://github.com/vsimon,在这里你可以找到很多你想要的关于webrtc的东西。老外真的很够意思,很耐心的解答,而且很愿意开源,我真的很佩服!!!当天晚上我又试验了一下,成功下载了所有的代码已经runhook 但是编译遇到了点小问题,由于webrtc编译属性中有一项是:将警告视为错误!(我次哦太严谨了吧,不得不佩服人家做事的耐心和细心,我们不该有浮躁之心):这里写图片描述
    解决这个问题很简单,需要改一下系统的区域设置为美国,如下:
    这里写图片描述
    第二天晚上我又悄悄地下载了代码,第二天早上一看,哇塞全部编译通过,当时喜出望外,哪知道后面还会有诸多问题。
  • 接着又找到了一个shell脚本,可以编译ubuntu和ios的库文件,地址公布一下:https://github.com/pristineio/webrtc-build-scripts 不过也经过了好久才搞到了android的代码并且编译出jar和so文件,感觉有了希望。
  • 有了这些东西,我又开始搞android和windows的音视频通讯。结果不在崩溃了,但是windows客户端无法获取摄像头,搞了好几次都是醉了。(由于windows使用ninja编译的,没有vs工程文件,不方便修改和调试,不过调试的话是有pdb文件的)。过了数日,我索性
set GYP_GENERATORS=ninja,ninja-msvs
#改成了 
set GYP_GENERATORS=ninja,msvs
  • 1
  • 2
  • 3

然后执行runhook 居然生成了vs2013的工程文件all.sln ,原来官方网上介绍的可能会失败,真的是可能会失败呀,意思就是可能会成功!!!
由此小小的修改后成功编译出了所有的文件包含lib和exe,也能正确捕捉到摄像头了。

  • 再次跑了android和windows的通讯,发现windows傻傻的没反应,这次又把我吓坏了,我又担心除了上面类似的问题。经过了仔细的排查,发现是我自己的失误,上个代码吧,呵呵:
    rtc::EnsureWinsockInit();
    rtc::Win32Thread w32_thread;
    rtc::ThreadManager::Instance()->SetCurrentThread(&w32_thread);
  • 1
  • 2
  • 3

不管你是WinMain还mian 这段代码一定要放在webrtc的功能调用之前,索性直接放在WinMain函数第一行。这个东西是webrtc消息循环和内部发送消息的驱动。
有了这个东西再次跑了一下。哇,出现了两张脸(当然都是我自己的脸了):
 
 
本人颜值不高,so打了码,怕吓到大家,呵呵。
windows端使用duilib做的界面库,感谢开源的力量。

总结吧

  • 所有的平台都是用webrtc的PeerConnectionFactory以及PeerConnection等等,这一次小小的实验让我了解到谷歌的强大,开源的强大,自己内心的强大才是真正的强大。
  • 如今实现了android和windows的音视频通讯,我揣测linux、mac和ios,浏览器的javascript等亦应该是如此的流程,殊途同归(所以不要跟我要代码,自己好好研究peerconnection_client,谷歌不是乱写一个demo),事实上就是如此,我也已经验证过了!!!
  • 好几年了没有如此的成就感了,一直在撸代码。鄙人一机械生出道,由于兴趣开始学习编程,当时没人指导,学了java,半年后发现其不适合做桌面应用,遂放弃了。导师要我做项目,然学习了c++,走上了一条不归路,呵呵。大学时做了个开源项目:“quickwifi”,目的是方便大家使用电脑搭建wifi网络供手机使用,后来出现了360一键wifi等等好多诸如此类的软件,真的悔恨自己当初没有坚持,或者说没有人家那份眼光。只能怪自己愚昧喽。webrtc我很看好他,不仅仅是他集成了业界最先进的技术,更看好的是音视频在未来的应用场景:智能家居,视频会议等等,试想一下,你走到哪一个角落任何一台电子设备都可以跟外界通讯那是何等有意思的事情。

另外本人还喜欢php,html,javascript等等,也写过自己的blog,当时出于资金问题放弃了。
有兴趣的话可以跟我沟通 emailto: 345252622@qq.com ,我很喜欢交朋友,也很喜欢帮助别人,大家一同进步。


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多