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

目录

一、安装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 <

视频服务器(6) Kurento[1] rtsp2webrtc_第1张图片

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

在另一台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的自动更新导致的

视频服务器(6) Kurento[1] rtsp2webrtc_第2张图片

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

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

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

二、播放rtsp调研

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

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

视频服务器(6) Kurento[1] rtsp2webrtc_第3张图片

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

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

视频服务器(6) Kurento[1] rtsp2webrtc_第4张图片

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

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

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

具体的例子,稍微查一下就能查到这个 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年前的,而且运行执行教程的指令过程中发现很多都是过时了的。

视频服务器(6) Kurento[1] rtsp2webrtc_第5张图片

到bower install那执行不下去了

视频服务器(6) Kurento[1] rtsp2webrtc_第6张图片

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

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

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

视频服务器(6) Kurento[1] rtsp2webrtc_第7张图片

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

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

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

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

视频服务器(6) Kurento[1] rtsp2webrtc_第8张图片

代码(伪代码):

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,再启动,就没有错误了。

视频服务器(6) Kurento[1] rtsp2webrtc_第9张图片

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

视频服务器(6) Kurento[1] rtsp2webrtc_第10张图片

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

学习用的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,结果

视频服务器(6) Kurento[1] rtsp2webrtc_第11张图片

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

用https测试,结果可以。

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

视频服务器(6) Kurento[1] rtsp2webrtc_第12张图片

点击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上了。

视频服务器(6) Kurento[1] rtsp2webrtc_第13张图片

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

视频服务器(6) Kurento[1] rtsp2webrtc_第14张图片

视频服务器(6) Kurento[1] rtsp2webrtc_第15张图片

确实和前面猜测的一样,这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下面的

视频服务器(6) Kurento[1] rtsp2webrtc_第16张图片

修改java代码

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

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

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

还有个useEncodedMedia

视频服务器(6) Kurento[1] rtsp2webrtc_第17张图片

从说明来看,使用这个方法后,能减少一个解码(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,后面的没获取到的包越来越少,最后就能安装上了。应该是网络的问题。这个过程倒是不需要使用的。

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

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

视频服务器(6) Kurento[1] rtsp2webrtc_第18张图片

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

视频服务器(6) Kurento[1] rtsp2webrtc_第19张图片

满心欢喜的去启动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里面最后提示有错误,视频播放是正常的。

视频服务器(6) Kurento[1] rtsp2webrtc_第20张图片

在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进入就不行了。

视频服务器(6) Kurento[1] rtsp2webrtc_第21张图片

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

视频服务器(6) Kurento[1] rtsp2webrtc_第22张图片

摄像头是在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。

先继续下一步吧。

 

你可能感兴趣的:(RTSP,Kurento,WebRTC)