视频服务器(10) Kurento[5] 浏览器无法播放问题

目录

一、安装 TURN server(尝试失败)。

二、使用免费TURN

三、Chrome不能播放WebRtc视频的问题

3.1 服务端分析

3.2 客户端分析

3.3 解决方案


前面碰到的公网,firefox无法播放视频的问题,提示

ICE failed, add a TURN server and see about:webrtc for more details

现在测试环境是:有两个服务器,一个有外围ip,一个只有内网ip的。

现在的问题是纯js客户端(没有放在http服务器上的html文件),firefox情况下,连接外网或者内网的kurento服务器都是ice faild的。chrome连接内网,能够播放,连接外网,第一次能播放,后面就不行了。

其实可以先把unity部署到springboot中,不用纯js客户端的方式连接试试。

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

一、安装 TURN server(尝试失败)。

查到的资料都是安装coturn,实际操作一下看看。

参考:coturn穿透服务器搭建

git clone https://github.com/coturn/coturn
cd coturn 
./configure

不按照步骤先安装libevent的话,会提示

视频服务器(10) Kurento[5] 浏览器无法播放问题_第1张图片

我的系统是ubuntu18.4,不能用yum安装,

参考:Ubuntu18.04安装Openssl-1.1.1进行安装,

安装过程中出现 Authentication failure,参考:Linux下切换root用户提示Authentication failure错误的解决方法

回到上面的coturn,在生成密钥时碰到问题,输入指令openssl req -x509 ....,后提示,req:Use -help for summary,好像这个语句有问题。

其他教程没有这个,是拷贝的文件的,参考:Ubuntu下安装配置coturn

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

另外还有个教程提示要安装,sqlite,参考:webrtc笔记(1): 基于coturn项目的stun/turn服务器搭建

这个教程里面提示直接用apt-get安装libevent,参考:Ubuntu 下 coturn 配置实现 TURN 中继传输媒体数据

好吧,不同的环境,不同的教程,我一开始可能就不应该参考那个centos环境下的。

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

另外可以用网上免费的stun服务器,参考:webrtc之三 iceServer

https://gist.github.com/yetithefoot/7592580里面的

{
	url: 'turn:numb.viagenie.ca',
	credential: 'muazkh',
	username: '[email protected]'
}

似乎能使用,进入http://numb.viagenie.ca/,发现

视频服务器(10) Kurento[5] 浏览器无法播放问题_第2张图片

 

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

查一下openssl -req 的信息,参考:OpenSSL指令---req

用里面的最后的例子,可以的

产生一个自签名的根证书: openssl req -x509 -newkey rsa:1024 -keyout key.pem -out req.pem

至少第一次时会要求

Enter PEM pass phrase

 随便输入了一个123456,后面的其他信息也随便输入。

在这个基础上改成

sudo openssl req -x509 -newkey rsa:2048 -keyout /etc/turn_server_pkey.pem -out /etc/turn_server_cert.pem -days 99999 –nodes

难道是拷贝的和手动输入的不一样吗.....

继续吧。

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

内网电脑配置:

relay-device=enp6s0   #与前ifconfig查到的网卡名称一致
listening-ip=192.168.6.16    #内网IP
listening-port=3478
tls-listening-port=5349
relay-ip=192.168.6.16 #内网IP
external-ip=192.168.6.16    #公网IP
relay-threads=50
lt-cred-mech
cert=/etc/turn_server_cert.pem
pkey=/etc/turn_server_pkey.pem
pidfile="/var/run/turnserver.pid"
min-port=49152
max-port=65535
user=cww:123456    #用户名密码,创建IceServer时用

#创建IceServer
IceServer turnIceServer = new IceServer("turn:192.168.6.16:3478","cww","123456");
IceServer stunIceServer = new IceServer("stun:47.107.110.212:19302","","");

vim无法复制粘贴,手动输入了,但是因为没有外围ip,不知道怎么测试。

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

用免费的在https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/做了下测试,和https://www.cnblogs.com/yjmyzz/p/how-to-install-coturn-on-ubuntu.html的最后的结果一样,接下来用那个来配置一下kurento先吧,从看到的资料,turn应该是安装在某个公网电脑上的。

{
	url: 'turn:numb.viagenie.ca',
	credential: 'muazkh',
	username: '[email protected]'
}

接下来要设置kurento,发现官网(https://doc-kurento.readthedocs.io/en/6.12.0/user/installation.html#stun-and-turn-servers)也是推荐用numb和Coturn的。

视频服务器(10) Kurento[5] 浏览器无法播放问题_第3张图片

还有Coturn的安装说明(https://doc-kurento.readthedocs.io/en/6.12.0/user/faq.html)

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

二、使用免费TURN

1.在服务器上加上turn设置

[email protected]:[email protected]:3478

说实话不知道有没有用,有两个@ .....

2.在客户端的kurento-player的js代码中加上turn的设置:

    var iceservers={
        "iceServers":[
            {url:'stun:stun.xten.com'},
            {
                url: 'turn:numb.viagenie.ca',
                credential: 'muazkh',
                username: '[email protected]'
            }
        ]
    }
    var options = {
        remoteVideo : video,
        mediaConstraints : userMediaConstraints,
        onicecandidate : onIceCandidate,
        configuration: iceservers
    }

结果还是出不来:

ICE failed, see about:webrtc for more details

才想到这个【about:webrtc】和chrome的【chrome://webrtc-internals/】一样,是个调试界面。。。。

从html文件打开:

视频服务器(10) Kurento[5] 浏览器无法播放问题_第4张图片

而从网页打开并播放时是

视频服务器(10) Kurento[5] 浏览器无法播放问题_第5张图片

我的电脑是双网卡的,192.168.1.16连接内网,192.168.6.12连接外网。

从网页打开时Websocket连接的是内网的"ws://192.168.1.150:8444/player",似乎它居然用6.12的ip去连接1.150。1.16呢,干嘛不用1.16尝试?

把外围网卡网线拔了,果然,html也能播放了。插上还是不行。

chrome没有这个问题,说明chrome对多网卡的处理比firefox好一些?

chrome也有自己的的问题(外围时服务端的addicecandidate要5s)。

尝试用html连接192.168.6.16(是192.168.1.150电脑的内网ip),能够播放。

神奇的是这时再用html去连接192.168.1.150,也能播放。而且连接的是两个6网段的ip,而不是1网段的。

视频服务器(10) Kurento[5] 浏览器无法播放问题_第6张图片

好像有学习能力一样的。不是学习到自己有1网段的ip,去连接对方的1网段,而是学习都有6网段的ip。

我原本还想看看代码,能不能让它在有两个网卡的情况下从1连接1,结果它自己转到6了。

重启一下电脑,还是可以,换一台电脑,也是可以。

奇怪了,最早的问题(用6网段连接1网段)又是怎么回事呢。

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

连接外网服务器,http://60.191.23.20:8443/#,可以

视频服务器(10) Kurento[5] 浏览器无法播放问题_第7张图片

这个115.204.230.177应该是我们这个局域网的对外网关ip了吧。

将webgl部署到bootstrap上,也就是kurento所在电脑上,用网页打开,firefox可以播放视频。

三、Chrome不能播放WebRtc视频的问题

3.1 服务端分析

客户端提示的原因是ICE_ADD_CANDIDATE_ERROR,服务端对应的代码是

  private void onIceCandidate(String sessionId, JsonObject jsonMessage) {
    UserSession user = users.get(sessionId);

    if (user != null) {
      JsonObject jsonCandidate = jsonMessage.get("candidate").getAsJsonObject();
      IceCandidate candidate =
              new IceCandidate(jsonCandidate.get("candidate").getAsString(), jsonCandidate
                      .get("sdpMid").getAsString(), jsonCandidate.get("sdpMLineIndex").getAsInt());
      user.getWebRtcEndpoint().addIceCandidate(candidate);
    }
  }

这里的addIceCandidate部分会出异常。

加入打印语句

视频服务器(10) Kurento[5] 浏览器无法播放问题_第8张图片

发现start和end之间的时间有问题

在Firefox里面播放时是很快的直接就一起的

视频服务器(10) Kurento[5] 浏览器无法播放问题_第9张图片

而在Chrome里面则是无论是否有异常,start和end之间都查了5s。addIceCandidate里面用时5s。

视频服务器(10) Kurento[5] 浏览器无法播放问题_第10张图片而且很奇怪的是打印时间里的秒都是5的倍数。

另外就是Chrome的发送的sdpOffer很长要16310,而Firefox的只有2083。看来下sdpOffer的内容,chrome的有4个mid。

具体内容,完全看不懂。

参考:WebRTC56版本SDP详细解析,WebRTC 中的 SDP 协议(这个还有对应的腾讯视频课程)

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

3.2 客户端分析

查资料过程中发现,在使用代理的情况下,chrome播放视频16s,没有代理31s,没代理时可能播放不了,启动代理的情况下基本都能播放。

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

试着把Firefox的candidate保存起来(手动一个个保存起来),在Chrome环境下发送,结果可以播放,也很快,3s左右,说明是candidate的问题。

注释掉sendMessage里面的发送部分,在不发送任何消息的情况下,查看chrome的oncandidate的内容,发现

1.没有使用turn的情况下,只有2个

视频服务器(10) Kurento[5] 浏览器无法播放问题_第11张图片

视频出不来的。

2.使用turn的情况下,有6个,最后两个里面的158.69.221.198是numb.viagenie.ca的ip。

视频服务器(10) Kurento[5] 浏览器无法播放问题_第12张图片

3.曾经在没有使用turn,开着代理的情况下。

有时能出来4个,那种情况下,视频是能出来的,16s左右。

另外把这些candidate手动保存下来后,不发送前两个(包含20e66a9b-b883-43c4-b8c2-1fb6a8de9cab.local),的情况下,3s,左右视频就出来了,发送的话16s,同时服务端addCandidate时会报错,就是前面两个的错误。

3.3 解决方案

1.添加turn iceServers

        var iceservers={
            "iceServers":[
                {url:'stun:stun.xten.com'},
                {
                    url: 'turn:numb.viagenie.ca',
                    credential: 'muazkh',
                    username: '[email protected]'
                }
            ]
        }
        var options = {
            remoteVideo : player.video,
            mediaConstraints : userMediaConstraints,
            //....
            configuration: iceservers
        }
        player.webRtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options,
            function(error) {
                if (error)
                    return console.error(error);
                player.webRtcPeer.generateOffer(function(error, offerSdp){
                    player.onOffer(error,offerSdp);
                });
            });

2.缓存发送offer和candidate,同时要过滤.local的candidate

KurentoPlayer.prototype.onOffer=function(error, offerSdp) {
        console.info("******************************* onOffer",this);
        if (error)
            return console.error('Error generating the offer');
        console.info('Invoking SDP offer callback function ' + location.host);
        var message = {
            id : 'start',
            sdpOffer : offerSdp,
            videourl : this.config.videoUrl
        }
        //this.sendMessage(message);
        this.pushBUfferMessage(message);//缓存起来,到oncandidategatheringdone时一起发送出去
    }
    KurentoPlayer.prototype.onIceCandidate=function(candidate) {
        var player=this;
        player.candidateCount++;
        console.error('['+player.candidateCount+'][onIceCandidate : Local candidate]',JSON.stringify(candidate)); 
        player.sendCandidate(candidate);
    };
    KurentoPlayer.prototype.sendCandidate=function(candidate) {
        var isLocal=candidate.candidate.indexOf('.local');
        if(isLocal!=-1){//过滤,不发送
            console.error("sendCandidate isLocal",candidate,isLocal);
            return;
        }
        var message = {
            id : 'onIceCandidate',
            candidate : candidate
        }
        //this.sendMessage(message);
        this.pushBUfferMessage(message);
    };

3.在oncandidategatheringdone一起发送

       var options = {
            //...
            oncandidategatheringdone:function(evt){
                console.error("oncandidategatheringdone",evt);
                player.flushBUfferMessage();//一起发送
            },
            configuration: iceservers
        }

注意如果不缓存offer,只是缓存candidate,一起发送后服务端会出错,最终导致playEnd。

你可能感兴趣的:(Kurento)