视频服务器(6) Kurento[1] rtsp2webrtc

8 篇文章 0 订阅
6 篇文章 0 订阅

目录

一、安装Kurento

二、播放rtsp调研

三、播放RTSP实现

四、wsl(ubuntu)安装使用


官网:https://www.kurento.org/

参考:Kurento流媒体开发环境搭建流程以及连接海康威视摄像头

参考:Kurento流媒体开发环境搭建流程

安装:https://doc-kurento.readthedocs.io/en/6.12.0/user/installation_dev.html

环境:Win10系统,安装VM,虚拟机Ubuntu18

一、安装Kurento

1.1 ubuntu(或者虚拟机)安装

参考:https://doc-kurento.readthedocs.io/en/6.12.0/user/installation.html#local-installation

指令:

# 1.安装相关指令
sudo apt-get update && sudo apt-get install --no-install-recommends --yes gnupg

# Run ONLY ONE of these lines:
DISTRO="xenial"  # KMS for Ubuntu 16.04 (Xenial)
DISTRO="bionic"  # KMS for Ubuntu 18.04 (Bionic)

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 5AFA7A83
sudo tee "/etc/apt/sources.list.d/kurento.list" >/dev/null <<EOF
# Kurento Media Server - Release packages
deb [arch=amd64] http://ubuntu.openvidu.io/6.12.0 $DISTRO kms6
EOF

# 安装
sudo apt-get update && sudo apt-get install --yes kurento-media-server
# 这里我出现了Unable to fetch some archives,maybe run apt-get update or try with --fix-missing
# 然后我再执行了
# sudo apt-get update
# 和
# sudo apt-get install --yes kurento-media-server
# Unable to fetch问题,多试几次,无法获取的包会越来越少,最后安装成功的。

# 2.启动相关指令
sudo service kurento-media-server start
# sudo service kurento-media-server stop

# 3.测试启动正常
ps -fC kurento-media-server
sudo netstat -tupln | grep -e kurento -e 8888
# 先安装curl
curl -i -N \
    -H "Connection: Upgrade" \
    -H "Upgrade: websocket" \
    -H "Host: 127.0.0.1:8888" \
    -H "Origin: 127.0.0.1" \
    http://127.0.0.1:8888/kurento

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

在另一台ubuntu电脑上安装时,好像是中间死机了,出现了问题:

The following packages have unmet dependencies: gstreamer-...

参考:如何解决apt-get中Unmet dependencies问题

总之用下面的指令,就可以继续安装了

sudo apt --fix-broken install
sudo apt-get update
sudo apt-get upgrade

结果安装完,在解压时电脑又卡死了。

Upacking libdevmapper1.02.1:amd64 (2:1.02.145-4.1ubuntu3.18.10.1) over (2:1.02.145-4.1ubuntu3) ...

Preparing to unpack .../03-console-setup-linux_1.178ubuntu9.2_all.deb ...

Unpacking console-setup-linux (1.178ubuntu9.2) over (1.178ubuntu9) ...

就整个电脑卡着了

重启后,还是不行。还是

sudo apt-get -y install kurento-media-server
Reading package lists... Done
Building dependency tree
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
kurento-media-server : Depends: gstreamer1.5-plugins-bad but it is not going to be installed
Depends: gstreamer1.5-plugins-ugly but it is not going to be installed
E: Unable to correct problems, you have held broken packages.

参考了https://askubuntu.com/questions/564282/apt-get-unmet-dependencies-but-it-is-not-going-to-be-installed里面的几种方法,也没用。

最后我发现电脑上的ubuntu版本居然是18.10 !!!! 版本代号是cosmic。

wsl和虚拟机里面的版本都是18.04。

安装教程里面的改成cosmic,也是不行,暂时只能考虑是不支持18.10版本了。话说这个电脑装了挺久的啊。重装系统吧。幸亏这个ubuntu系统本身没装什么东西。

重装系统后,能够装上。

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

后来有次同事重装了一个ubuntu电脑,安装过程中碰到这样的

下列软件包有未满足的依赖关系:
 ............
E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。

是在输入sudo apt-get update && sudo apt-get install --yes kurento-media-server时出现的

经过搜索,发现是没有打开ubuntu的自动更新导致的

他在安装ubuntu时跳过了自动更新

参考:E:无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系

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

二、播放rtsp调研

在kurento的文档中没有找到rtsp的东西,有rtp何srtp的

参考:RTSP/RTP/RTCP之间的关系

那其实kurento应该能对接rtsp的啊,为什么官方的例子里面没有呢

官方有两个文章,https://www.kurento.org/tags/rtsp

说实话 看不懂 并且没有操作教程 。

先再找找有操作的教程,不行再来啃一啃。

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

具体的例子,稍微查一下就能查到这个 https://github.com/lulop-k/kurento-rtsp2webrtc

相关指令有:

# Be sure to have installed Node.js in your system:
curl -sL https://deb.nodesource.com/setup | sudo bash -
#上面这个执行的话,有弹出提示,感觉像是说不要用了。
sudo apt-get install -y nodejs

# Also be sure to have installed Bower in your system:
sudo npm install -g bower
#bower已经过时了

# To launch the demo, run:
cd kurento-rtsp2webrtc
bower install

# An HTTP server is required for these demos. A very simple way of doing this is by means of a NodeJS server. This server can be installed as follows:
sudo npm install -g http-server

# Then, in each demo folder execute this command:

http-server
# Finally, open this URL in your browser: http://localhost:8080/

但是从实际来看这个是5年前的,而且运行执行教程的指令过程中发现很多都是过时了的。

到bower install那执行不下去了

从git上下载下代码,它自己的note.txt里面的git地址都不见了的。

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

查了一些,都指向这个例子,打开下载下来的index.html

我都在怀疑用kurento作rtsp方式是否正确了,资料怎么这么少啊,这么旧啊。

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

又查到一个资料,关于直播的技术整理2,虽然还是那个例子,但这里提到了例子中的2s延迟的解决办法。

同时看了一下前面的rtsp的英文的文章的内容,似乎对kurento来说,rtsp2webrtc很好实现。

代码(伪代码):

var pipeline = ...//Use Kurento Client API for obtaining your pipeline.

//Create the PlayerEndpoint for receiving from the IP camera. HTTP and RTSP uris are supportd
pipeline.create("PlayerEndpoint", {uri: "rtsp://your.rtsp.address"}, function(error, playerEndpoint){

    //Create the WebRtcEndpoint
    pipeline.create("WebRtcEndpoint", function(error, webRtcEndpoint){

    //If working with trickle ice, some code for candidate management is required here.

        //Connect playerEndpoint to webRtcEndpoint. This connection activates the agnostic media
        //capability and the appropriate transcodings are configured and activated.
  	playerEndpoint.connect(webRtcEndpoint, function(error){

                //Media starts flowing ... enjoy
  		player.play(function(error){
  		});
  	});
    });
});

现在的问题是这些代码是什么?哪里来的?

pipeline,PlayerEndpoint,WebRtcEndpoint,play....

Java吗?要找官方Demo看看了。

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

三、播放RTSP实现

下载Demo代码,地址:https://github.com/Kurento/kurento-tutorial-java

用IDEA启动,需要先安装IDEA。参考:Ubuntu18.04 安装 Idea 2018.2 Ultimate

我安装后虚拟机死机了,然后就没有了快捷方式,现在启动都要进入目录,启动idea.sh........

下载安装Java18,参考:ubuntu18.04 安装java

Ubuntu自带的Java不行,会出现问题什么 java:error:option -source can not ... togather with -release。

安装好Java18后,修改项目SDK,再启动,就没有错误了。

另外在没有安装Kurento环境下启动,或者没有启动kurento服务,也是会报错的。

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

学习用的demo选择两个helloworld和player,因为上面的PlayerEndpoint

现在的问题是,idea正常启动了,页面怎么进去啊?没有提示啊?

 

application.properties的内容是

# LOGGING
logging.level.root=INFO
logging.level.org.apache=WARN
logging.level.org.springframework=WARN
logging.level.org.kurento=INFO
logging.level.org.kurento.tutorial=INFO

# OUTPUT
# Terminal color output; one of [ALWAYS, DETECT, NEVER]
spring.output.ansi.enabled=DETECT


# ----------------------------------------
# WEB PROPERTIES
# ----------------------------------------

# EMBEDDED SERVER CONFIGURATION
server.port=${demo.port}
server.ssl.key-store=classpath:keystore.jks
server.ssl.key-store-password=kurento
server.ssl.key-store-type=JKS
server.ssl.key-alias=kurento-selfsigned

通过在banner.txt里面添加

${server.port}

打印出端口8443,在网页中输入http://127.0.0.1:8443,结果

查到8443端口是 tomcat的SSL端口,

用https测试,结果可以。

中间会弹出一个不安全,是否要继续的界面。

点击Start,能够播放视频,但是有些慢,接下来理解并修改代码。

这个页面其实就是我要的功能了。

修改下面的播放视频的地址为公司的摄像头的rtsp地址,结果能够成功播放!

到这里,算是完成了第一阶段。确认技术可行性。

播放效果有些延迟,还有丢帧,说啥话不如前面的go语言的方案的效果。

但是至少比shinobi好,是用webrtc的。

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

浏览器支持情况

Chrome和Firefox支持,

Edge不支持,最后提示一个 

Timeout for addRemoteCandidate. Consider sending an end-of-candidates notification

就没有播放出来了。

用IE打开页面,提示需要安装 Temasys WebRTC Plugin插件,下载、安装、刷新,可以播放。

另外多个浏览器同时打开也是支持的,这点比前面的go好。

接下来是延迟问题、纯js客户端。

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

代码分析:

在官方文档里(https://doc-kurento.readthedocs.io/en/6.12.0/_static/client-javadoc/index.html)PlayerEndpoint是支持RTSP的,就相当于一个播放器了,他来播放,然后结合WebRtcEndpoint,就能转换到webrtc上了。

kurento-player例子里面的PlayerHandler的代码:

确实和前面猜测的一样,这rtsp2webrtc的功能kurento很好实现。

但是为什么找到的资料都指向那个老的例子(https://github.com/lulop-k/kurento-rtsp2webrtc)呢,明明这个kurento-player才是啊。

不过这个是java的例子,纯js的例子还要看看。

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

处理延迟问题

参考前面的关于直播的技术整理2里面的

pipeline.create("PlayerEndpoint", {networkCache: 0, uri: address.value}, function(error, player){...

还有官方文档中的Class PlayerEndpoint.Builder下面的

修改java代码

 final PlayerEndpoint playerEndpoint = new PlayerEndpoint.Builder(pipeline, videourl).withNetworkCache(0).build();

结果,延迟和丢帧问题都好了,效果很满意

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

还有个useEncodedMedia

从说明来看,使用这个方法后,能减少一个解码(decode)的过程,降低cpu利用率,提高延迟(应该),但是对于丢帧、视频质量无法保证,不建议使用。

实际加上后测试,感觉快了那么一点点,不知道是不是心理原因。

final PlayerEndpoint playerEndpoint = new PlayerEndpoint.Builder(pipeline, videourl)
            .useEncodedMedia()
            .withNetworkCache(0)
            .build();

后续实际生产环境再测试一下。另外这些都可以作为配置项开放出来,这样就不用改代码了。

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

四、wsl(ubuntu)安装使用

试着在wsl里面安装,出现问题 

E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/f/fftw3/libfftw3-double3_3.3.7-1_amd64.deb  Connection timed out [IP: 91.189.88.173 80]
E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/universe/s/spandsp/libspandsp2_0.0.6+dfsg-0.1_amd64.deb  Connection timed out [IP: 91.189.88.149 80]
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

发现多试几次 sudo apt-get install --yes kurento-media-server,后面的没获取到的包越来越少,最后就能安装上了。应该是网络的问题。这个过程vpn倒是不需要使用的。

另外wsl安装总感觉比较慢一点。

在wsl安装好kurento,启动服务后,用ps查看进程马上就能找到了,因为就那几个启动着,不需要查找。

启动服务后查询端口监听,发现在wsl里面没有端口,在windows里面有监听端口,而且kurento-media-server在任务管理器里面也作为一个进程显示出来了。

满心欢喜的去启动idea,启动项目,结果启动失败了。

执行看提示

The Tomcat connector configured to listen on port 8443 failed to start. The port may already be in use or the connector may be misconfigured.

查找占用8443的进程,发现是vmnat.exe,想起来VMware做了一些8443端口映射,为了在外面访问虚拟机里面的服务。

删除那个映射后,IDEA就能启动项目了,然后也能进入网页(https://127.0.0.1:8443)播放视频了!

虽然console里面最后提示有错误,视频播放是正常的。

在idea中打印有错误

2019-11-07 14:33:53.454 ERROR 17924 --- [nio-8443-exec-5] o.kurento.tutorial.player.PlayerHandler  : 
Exception handling message {"id":"onIceCandidate","candidate":{"candidate":"candidate:2628012269 1 udp 2113937151 77b31313-368c-41b5-8f55-c62ecf5eb6d6.local 64065 typ host generation 0 ufrag dl6M network-cost 999","sdpMid":"1","sdpMLineIndex":1}} in sessionId 452f1e30-eeb8-9409-2069-c8826ed2286c

org.kurento.client.internal.server.KurentoServerException: Error adding candidate (Code:40401, Type:null, Data: {"type":"ICE_ADD_CANDIDATE_ERROR"})
	at org.kurento.client.internal.transport.jsonrpc.RomClientJsonRpcClient.sendRequest(RomClientJsonRpcClient.java:264) ~[kurento-client-6.11.1-20191014.135655-5.jar:6.11.1-SNAPSHOT]
	at org.kurento.client.internal.transport.jsonrpc.RomClientJsonRpcClient.invoke(RomClientJsonRpcClient.java:117) ~[kurento-client-6.11.1-20191014.135655-5.jar:6.11.1-SNAPSHOT]
	at org.kurento.client.internal.transport.jsonrpc.RomClientJsonRpcClient.invoke(RomClientJsonRpcClient.java:99) ~[kurento-client-6.11.1-20191014.135655-5.jar:6.11.1-SNAPSHOT]
	at org.kurento.client.internal.client.RomManager.invoke(RomManager.java:162) ~[kurento-client-6.11.1-20191014.135655-5.jar:6.11.1-SNAPSHOT]
	at org.kurento.client.internal.client.RemoteObject.invoke(RemoteObject.java:186) ~[kurento-client-6.11.1-20191014.135655-5.jar:6.11.1-SNAPSHOT]
	at org.kurento.client.internal.client.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:182) ~[kurento-client-6.11.1-20191014.135655-5.jar:6.11.1-SNAPSHOT]
	at org.kurento.client.internal.client.RemoteObjectInvocationHandler.internalInvoke(RemoteObjectInvocationHandler.java:142) ~[kurento-client-6.11.1-20191014.135655-5.jar:6.11.1-SNAPSHOT]
	at org.kurento.client.internal.client.DefaultInvocationHandler.invoke(DefaultInvocationHandler.java:39) ~[kurento-client-6.11.1-20191014.135655-5.jar:6.11.1-SNAPSHOT]
	at com.sun.proxy.$Proxy65.addIceCandidate(Unknown Source) ~[na:na]
	at org.kurento.tutorial.player.PlayerHandler.onIceCandidate(PlayerHandler.java:259) ~[classes/:na]
	at org.kurento.tutorial.player.PlayerHandler.handleTextMessage(PlayerHandler.java:93) ~[classes/:na]
	at org.springframework.web.socket.handler.AbstractWebSocketHandler.handleMessage(AbstractWebSocketHandler.java:43) [spring-websocket-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.web.socket.handler.WebSocketHandlerDecorator.handleMessage(WebSocketHandlerDecorator.java:75) [spring-websocket-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator.handleMessage(LoggingWebSocketHandlerDecorator.java:56) [spring-websocket-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator.handleMessage(ExceptionWebSocketHandlerDecorator.java:58) [spring-websocket-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.handleTextMessage(StandardWebSocketHandlerAdapter.java:113) [spring-websocket-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.access$000(StandardWebSocketHandlerAdapter.java:42) [spring-websocket-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:84) [spring-websocket-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:81) [spring-websocket-5.1.7.RELEASE.jar:5.1.7.RELEASE]
	at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:395) [tomcat-embed-websocket-9.0.19.jar:9.0.19]
	at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:119) [tomcat-embed-websocket-9.0.19.jar:9.0.19]
	at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:495) [tomcat-embed-websocket-9.0.19.jar:9.0.19]
	at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:294) [tomcat-embed-websocket-9.0.19.jar:9.0.19]
	at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:133) [tomcat-embed-websocket-9.0.19.jar:9.0.19]
	at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:82) [tomcat-embed-websocket-9.0.19.jar:9.0.19]
	at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:171) [tomcat-embed-websocket-9.0.19.jar:9.0.19]
	at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:151) [tomcat-embed-websocket-9.0.19.jar:9.0.19]
	at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148) [tomcat-embed-websocket-9.0.19.jar:9.0.19]
	at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54) [tomcat-embed-core-9.0.19.jar:9.0.19]
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53) [tomcat-embed-core-9.0.19.jar:9.0.19]
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836) [tomcat-embed-core-9.0.19.jar:9.0.19]
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1747) [tomcat-embed-core-9.0.19.jar:9.0.19]
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.19.jar:9.0.19]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_202]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_202]
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.19.jar:9.0.19]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_202]

对我来说,能播放就行,这个问题如果不影响播放,就可以不处理了。

 

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

用https://127.0.0.1:8443测试没问题后,打算用其他电脑连接测试,结果,在自己电脑上用https://192.168.1.16:8443进入就不行了。

而用https://192.168.6.12:8443,则和127.0.0.1一样最后有两个错误提示,但是没有视频。

摄像头是在192.168.1.134的和6不是一个网段,有关系吗?

后来127.0.0.1也不行了......

然后发现,重启一次kurento-media-server,就可以播放视频,播放后,刷新页面或者停止播放,然后就不能播放了,必须再次重启服务。

192.168.6.12和127.0.0.1是可以播放的。

而192.168.1.16则是出于websocket无法发送信息的阶段,根本进不了后端的代码。

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

后来更是出现,怎么重启都无法播放的情况-------我的电脑有两个网卡,一个连接内网,一个连接外网,摄像头是在内网上的,假如把外网网卡禁掉,怎么重启都无法播放视频。难道它必须连接外网吗?

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

发现虚拟机里面的,无论外网网卡是否启动,都能播放视频。而外网网卡禁用时,外面电脑访问虚拟机里面的网页会出现

Uncaught DOMException: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.
    at sendMessage (https://192.168.136.129:8443/js/index.js:263:5)
    at WebRtcPeerRecvonly.onIceCandidate (https://192.168.136.129:8443/js/index.js:140:2)
    at WebRtcPeerRecvonly.EventEmitter.emit (https://192.168.136.129:8443/js/kurento-utils.js:737:17)
    at RTCPeerConnection.iceCandidateFunction (https://192.168.136.129:8443/js/kurento-utils.js:275:26)

192.168.136.129是虚拟机的ip

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

纠结.....最理想还是不要放到虚拟机里面,影响性能。最明显的就是能看到延迟。

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

在另一台电脑上安装kurento,运行java项目,结果不会出现Error。

先继续下一步吧。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值