Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

长时间推流后,程序会崩溃 #3

Open
zhongren opened this issue May 16, 2019 · 11 comments
Open

长时间推流后,程序会崩溃 #3

zhongren opened this issue May 16, 2019 · 11 comments

Comments

@zhongren
Copy link

2019-05-16 09:55:52,414 INFO nioEventLoopGroup-3-2 [cn.org.hentai.jtt1078.server.Jtt1078Handler2] - start streaming to rtmp://10.20.129.54:1935/live/stream/018600000004_1 2019-05-16 09:56:02,409 INFO nioEventLoopGroup-3-3 [cn.org.hentai.jtt1078.server.Jtt1078Handler2] - start streaming to rtmp://10.20.129.54:1935/live/stream/018600000004_2 2019-05-16 09:56:14,484 INFO nioEventLoopGroup-3-4 [cn.org.hentai.jtt1078.server.Jtt1078Handler2] - start streaming to rtmp://10.20.129.54:1935/live/stream/018600000004_3 2019-05-16 09:56:23,488 INFO nioEventLoopGroup-3-5 [cn.org.hentai.jtt1078.server.Jtt1078Handler2] - start streaming to rtmp://10.20.129.54:1935/live/stream/018600000004_4 2019-05-16 10:02:55,193 WARN nioEventLoopGroup-3-2 [io.netty.channel.DefaultChannelPipeline] - An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception. java.nio.channels.AsynchronousCloseException at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:205) at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:216) at cn.org.hentai.jtt1078.video.PublisherManager$Publisher.publish(PublisherManager.java:188) at cn.org.hentai.jtt1078.video.PublisherManager.publish(PublisherManager.java:94) at cn.org.hentai.jtt1078.server.Jtt1078Handler2.channelRead0(Jtt1078Handler2.java:77) at cn.org.hentai.jtt1078.server.Jtt1078Handler2.channelRead0(Jtt1078Handler2.java:29) at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:297) at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:413) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1414) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:945) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:146) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748) 2019-05-16 10:02:55,212 WARN nioEventLoopGroup-3-2 [io.netty.channel.DefaultChannelPipeline] - An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception. java.lang.RuntimeException: no such publisher: 1 at cn.org.hentai.jtt1078.video.PublisherManager.publish(PublisherManager.java:80) at cn.org.hentai.jtt1078.server.Jtt1078Handler2.channelRead0(Jtt1078Handler2.java:77) at cn.org.hentai.jtt1078.server.Jtt1078Handler2.channelRead0(Jtt1078Handler2.java:29) at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:297) at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:413) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1414) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:945) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:146) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748)

长时间推流之后,fileChannel.write(byteBuffer) 推流就异常了

@glaciall
Copy link
Owner

你所说的长时间推流是有多长时间?
你发来的这一大串日志看得我脑壳疼,我找到了java.lang.RuntimeException: no such publisher: 1这个我自己报出来的错误,你仔细看看日志里面,看看是不是发生了超时而导致了自动关闭呢?如果车载终端5000毫秒以上不发送视频流到服务器端的话,就会自动触发关闭掉的。

@zhongren
Copy link
Author

大概4个摄像头 推了7分钟左右
nioEventLoopGroup-3-2 [io.netty.channel.DefaultChannelPipeline] - An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception. java.nio.channels.AsynchronousCloseException at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:205) at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:216) at cn.org.hentai.jtt1078.video.PublisherManager$Publisher.publish(PublisherManager.java:188) at cn.org.hentai.jtt1078.video.PublisherManager.publish(PublisherManager.java:94) at cn.org.hentai.jtt1078.server.Jtt1078Handler2.channelRead0(Jtt1078Handler2.java:77) at cn.org.hentai.jtt1078.server.Jtt1078Handler2.channelRead0(Jtt1078Handler2.java:29) at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105) at

FileChannelImpl.write(FileChannelImpl.java:216)这一行就报错了,后续的no such publisher 我觉得是不是因为exceptionCaught里面只是ctx.close,但是并没有在map里移除publisher

@zhongren
Copy link
Author

我看了下,没有数据的话,5秒后 publisher就从map里移除了,但是ctx还没关闭,然后再次收到推流后,从session里获取publishId 这时候就无法推流了, 那是不是需要在5秒断开后,给终端发送停止推流的指令呢

@glaciall
Copy link
Owner

不,首先exceptionCaught方法只是在当ChannelInBoundHandler处理消息时发生未捕获的异常时的最后一个处理的地方,这个位置没有什么意义。

no such publisher表示的是,通道与fifo文件的对照关系已经不复存在了,现在的问题就是为什么5秒之后会被删掉,按我原来的设计,是只要车载终端一直在推流,这就一直会维持这个关系的,你多多跟踪一下看看,我现在手头上不方便调试。

@glaciall
Copy link
Owner

PublisherManager里,有一个map维持了一个rtmp地址到fifo文件的关联关系,这个关系将在publisher推流器过期时被删掉,有两个地方你注意一下,分别是PublisherManager类的87行和104行这里。

@zhongren
Copy link
Author

public boolean publish(byte[] data) throws Exception { if (process.isAlive() == false) return false; byteBuffer.clear(); byteBuffer.put(data); byteBuffer.flip(); fileChannel.write(byteBuffer); byteBuffer.flip(); this.lastActiveTime = System.currentTimeMillis(); return true; }
好像是把数据写入fifo的这一段 如果数据写入成功,会在最后this.lastActiveTime = System.currentTimeMillis();
更新时间戳,也就是您在定时器里面用来判断是否超时.
目前就是fileChannel.write(byteBuffer);报错了,导致更新时间戳的这一行代码没有执行到,从而导致publisher从map里被移除了

@glaciall
Copy link
Owner

嗯,往FIFO管道文件写数据失败了,晚点我跟踪一下FFMPEG的控制台输出,你看到PublisherManager类的149行的那一大片注释掉的东西了吗?你把这里解开,看看ffmpeg发生了什么情况了没有。。。

@glaciall
Copy link
Owner

我今天测试过一次20多分钟的长时间推流,一直都没有报错,但是有时候也是会有5分钟就报错的情况发生,实际使用时,还是跟当时的网络情况有有关,需要你来制定发起实时音视频传输指令的策略来控制好,比如失败了就另外重新请求让车载终端再次推流等等,因为车辆在移动过程中,4G信号强度处于不断的变化之中,不可控的因素太多,还是做好事后处理比较好。

我这里只是提了一种使用FIFO管道文件处理这种应用程序间配合的一种方案,可以避开对opencv或ffmpeg深度集成的问题。

@zhongren
Copy link
Author

好的 谢谢大佬,我去想想重连的方案

@glaciall
Copy link
Owner

不客气啊,有什么发现了或是可以改进的地方告诉我一声。。。。

@glaciall
Copy link
Owner

@zhongren 更新一下,解决掉了一个读包的错误。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants