Git Product home page Git Product logo

jtt1078-video-server's Introduction

目录

  1. 简介说明
  2. 分支说明
  3. 项目说明
  4. 准备工具
  5. 测试步骤
  6. 测试环境
  7. TODO
  8. 致谢
  9. 推荐群友项目
  10. 交流讨论

jtt1078-video-server

基于JT/T 1078协议实现的视频转播服务器,当车机服务器端主动下发音视频实时传输控制消息(0x9101)后,车载终端连接到此服务器后,发送指定摄像头所采集的视频流,此项目服务器完成音视频数据接收并转码,完成转播的流程,提供各平台的播放支撑。

同时,本项目在配置 ffmpeg路径rtmp url 后,将同时输出一路到 RTMP 服务器上去,为移动端播放提供音视频支持(注意,由于旁路的RTMP流是通过ffmpeg子进程实现,并且有音频转码的过程,所以性能将有很大的下降)。

非常感谢 孤峰赏月/hx(github/jelycom 提供的mp3音频支持。

分支说明

原项目有4个分支不同的实现方式,现将其它分支全部删除,已经用不上了。 配置了ffmpeg和rtmp,可以想办法同时输出到比如HLS等。

有其它语言的开发者,可以参考我的“JTT/1078音视频传输协议开发指南”,我所知道的官方文档里的错误或是缺陷以及坑,我全部写了下来,希望对你有帮助。

项目说明

本项目接收来自于车载终端发过来的音视频数据,视频直接封装为FLV TAG,音频完成G.711A、G.711U、ADPCMA、G726到PCM的转码,并使用MP3压缩后再封装为FLV TAG。

视频编码支持

目前几乎所有的终端视频,默认的视频编码都是h264,打包成flv也是非常简单的,有个别厂家使用avs,但是我没有碰到过。本项目目前也只支持h264编码的视频。

音频编码支持

音频编码 支持 备注
G.711A Y 支持
G.711U Y 支持
ADPCMA Y 支持
G.726 Y 支持

音频编码太多,也没那么多设备可以测试的,比较常见的就G.711A和ADPCMA这两种,本程序对于不支持的音频,将作 静音处理

音频编码转码扩展实现

继承并实现AudioCodec类的抽象方法,完成任意音频到PCM编码的转码过程,并且补充AudioCodec.getCodec()工厂方法即可。AudioCodec抽象类原型如下:

public abstract class AudioCodec
{
	// 转换至PCM
    public abstract byte[] toPCM(byte[] data);
    // 由PCM转为当前编码,可以留空,反正又没有调用
    public abstract byte[] fromPCM(byte[] data);
}

准备工具

项目里准备了一个测试程序(src/main/java/cn.org.hentai.jtt1078.test.VideoPushTest.java),以及一个数据文件(src/main/resources/tcpdump.bin),数据文件是通过工具采集的一段几分钟时长的车载终端发送上来的原始消息包,测试程序可以持续不断的、慢慢的发送数据文件里的内容,用来模拟车载终端发送视频流的过程。

另外,新增了 cn.org.hentai.jtt1078.test.RTPGenerate 类,用于读取bin文件,并且修改SIM卡号和通道号,创建大量数据文件以便于压力测试。

测试步骤

  1. 配置好服务器端,修改app.properties里的配置项。
  2. 直接在IDE里运行cn.org.hentai.jtt1078.app.VideoServerApp,或对项目进行打包,执行mvn package,执行java -jar jtt1078-video-server-1.0-SNAPSHOT.jar来启动服务器端。
  3. 运行VideoPushTest.java,开始模拟车载终端的视频推送。
  4. 开始后,控制台里会输出显示start publishing: 013800138999-2的字样
  5. 打开浏览器,输入 http://localhost:3333/test/multimedia#013800138999-2 后回车
  6. 点击网页上的play video,开始播放视频

测试环境

我在我自己的VPS上搭建了一个1078音视频环境,完全使用了flv分支上的代码来创建,各位可以让终端将音视频发送到此服务器或是使用netcat等网络工具发送模拟数据来仿真终端,来体验音视频的效果。下面我们说一下通过netcat来模拟终端的方法:

标题 说明
1078音视频服务器 185.251.248.4:10780
实时音视频播放页面 http://1078.hentai.org.cn/test/multimedia#SIM-CHANNEL
  1. 首先,本项目的 /src/main/resources/ 下的 tcpdump.bin 即为我抓包存下来的终端音视频数据文件,通过cat tcpdump.bin | pv -L 40k -q | nc 185.251.248.4 10780即可以每秒40kBPS的速度,向服务器端持续的发送数据。
  2. 在浏览器里打开http://1078.hentai.org.cn/test/multimedia#SIM-CHANNEL (注意替换掉后面的SIM和CHANNEL,即终端的SIM卡号,不足12位前面补0,CHANNEL即为通道号),然后点击网页上的play video即可。

由于我的服务器IP随时可能会发生变化,建设在尝试连接测试服务器前,先通过ping www.hentai.org.cn来确定最新的IP。

项目文件说明



├── doc
│   ├── 1078.png(图标)
│   └── ffmpeg.png
├── LICENSE(开源协议)
├── pom.xml
├── README.md(项目说明)
├── src
│   └── main
│       ├── java
│       │   └── cn
│       │       └── org
│       │           └── hentai
│       │               └── jtt1078
│       │                   ├── app
│       │                   │   └── VideoServerApp.java(主入口程序)
│       │                   ├── codec
│       │                   │   ├── ADPCMCodec.java(ADPCM编解码器)
│       │                   │   ├── AudioCodec.java(音频编解码抽象父类)
│       │                   │   ├── G711Codec.java(G711A/alaw编解码器)
│       │                   │   ├── G711UCodec.java(G711U/ulaw编解码器)
│       │                   │   ├── g726(G726编解码实现)
│       │                   │   │   ├── G726_16.java
│       │                   │   │   ├── G726_24.java
│       │                   │   │   ├── G726_32.java
│       │                   │   │   ├── G726_40.java
│       │                   │   │   ├── G726.java
│       │                   │   │   └── G726State.java
│       │                   │   ├── G726Codec.java(G726编解码器)
│       │                   │   ├── MP3Encoder.java(PCM到MP3压缩编码器)
│       │                   │   └── SilenceCodec.java(静音化解码器)
│       │                   ├── entity
│       │                   │   ├── Audio.java
│       │                   │   ├── MediaEncoding.java
│       │                   │   ├── Media.java
│       │                   │   └── Video.java
│       │                   ├── flv
│       │                   │   ├── AudioTag.java
│       │                   │   ├── FlvAudioTagEncoder.java
│       │                   │   ├── FlvEncoder.java(H264到FLV封装编码器)
│       │                   │   └── FlvTag.java
│       │                   ├── http(内置HTTP服务,提供HTTP-CHUNKED传输支持)
│       │                   │   ├── GeneralResponseWriter.java
│       │                   │   └── NettyHttpServerHandler.java
│       │                   ├── publisher
│       │                   │   ├── Channel.java(一个通道一个Channel实例,Subscriber订阅Channel上的音频与视频)
│       │                   │   └── PublishManager.java(管理Channel和Subscriber)
│       │                   ├── server(负责完成1078 RTP消息包的接收和解码)
│       │                   │   ├── Jtt1078Decoder.java
│       │                   │   ├── Jtt1078Handler.java
│       │                   │   ├── Jtt1078MessageDecoder.java
│       │                   │   └── Session.java
│       │                   ├── subscriber
│       │                   │   ├── RTMPPublisher.java(通过ffmpeg子进程将http-flv另外传输一份到RTMP服务器的实现)
│       │                   │   ├── Subscriber.java(订阅者抽象类定义)
│       │                   │   └── VideoSubscriber.java(视频订阅者)
│       │                   ├── test(测试代码)
│       │                   │   ├── AudioTest.java
│       │                   │   ├── ChannelTest.java
│       │                   │   ├── FuckTest.java
│       │                   │   ├── G711ATest.java
│       │                   │   ├── MP3Test.java
│       │                   │   ├── RTPGenerate.java(通过读取原始消息数据文件,创建N个修改了sim卡号的新数据文件,可用于压力测试)
│       │                   │   ├── VideoPushTest.java
│       │                   │   ├── VideoServer.java
│       │                   │   └── WAVTest.java
│       │                   └── util
│       │                       ├── ByteBufUtils.java
│       │                       ├── ByteHolder.java
│       │                       ├── ByteUtils.java
│       │                       ├── Configs.java
│       │                       ├── FileUtils.java
│       │                       ├── FLVUtils.java
│       │                       ├── Packet.java
│       │                       └── WAVUtils.java
│       └── resources
│           ├── app.properties(主配置文件)
│           ├── audio.html
│           ├── g726
│           │   ├── in_16.g726
│           │   ├── in_24.g726
│           │   ├── in_32.g726
│           │   └── in_40.g726
│           ├── log4j.properties
│           ├── multimedia.html(测试用音视频播放页面)
│           ├── tcpdump.bin(测试用数据文件,音频ADPCM含海思头,视频H264)
│           ├── nginx_sample.conf(NGINX反向代理样例,解决6路并发问题)
│           ├── test.html
│           └── video.html

项目打包说明

通过mvn package直接打包成jar包,通过java -jar jtt1078-video-server-1.0-SNAPSHOT.jar即可运行,最好把app.propertiesmultimedia.html一并放在同一个目录下,因为项目会优先读取文件系统中的配置文件信息。而如果没有本地测试的需求,multimedia.html可以不要。

注意事项

  1. 本项目为JT 1078协议的流媒体服务器部分的实现,不包括1078协议的控制消息交互部分,就是在0x9101指令下发后,终端连接到的音视频服务器的实现。
  2. 在一般的浏览器里,比如Chrome下,浏览器限制了对于同一个域名的连接最多只能够有6个并发,所以如果要同时播放多路视频,需要准备多个域名或是端口,通过轮循分配的方式,把视频的传输连接,分配到不同的URL上去。

致谢

本项目一开始只是个简单的示例项目,在开源、建立QQ交流群后,得到了大批的同道中人的帮助和支持,在此表示谢意。本项目尚未完全完善,非常高兴能够有更多的朋友一起加入进来,一起提出更加闪亮的想法,建设更加强大的视频监控平台!

致谢名单

非常感谢以下网友的帮助和支持,以及其他默默支持的朋友们!

推荐群友项目

项目 URL 作者 说明
JT1078 https://github.com/yedajiang44/JT1078 SmallChi/yedajiang44 C#,支持音视频,通过websocket传输flv到前端

交流讨论

QQ群:808432702,加入我们,群里有热心的同道中人、相关资料、测试数据、代码以及各种方案的先行者等着你。

捐助

开源不易,请我抽支芙蓉王吧。

jtt1078-video-server's People

Contributors

295477887 avatar bigbeef avatar dependabot[bot] avatar glaciall avatar liupinjin avatar tmyam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jtt1078-video-server's Issues

长时间推流,会抛出异常

java.nio.channels.AsynchronousCloseException at java.nio.channels.spi.AbstractInterruptibleChannel.end(AbstractInterruptibleChannel.java:205) at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:216)
PublisherManager中的publish方法中的fileChannel.write(byteBuffer)方法会在推流一段时间后抛出异常,是推流的速度太慢,跟不上接收速度的原因嘛

请教一下,无法处理终端上来的1080p的视频流

在终端实时视频640x360的分辨率是没问题的
但调取历史视频是1080p分辨率的未见报错,但ffmpeg推流一直在报这种错误,试了一下,在线flv播放也无法进行
我尝试用了另外的项目,是直接把原始h264流写到fifo通道推到rtmp,可以播放视频,但没有声音,尝试用作者的这个项目又遇到这个问题
DTS 4294927314, next:19923000 st:0 invalid dropping00:00.00 bitrate=N/A speed= 0x
PTS 4294927314, next:19923000 invalid dropping st:0
DTS 4294927380, next:19989000 st:0 invalid dropping00:00.00 bitrate=N/A speed= 0x
PTS 4294927380, next:19989000 invalid dropping st:0
DTS 4294927447, next:20055000 st:0 invalid dropping
PTS 4294927447, next:20055000 invalid dropping st:0
DTS 4294927514, next:20121000 st:0 invalid dropping
PTS 4294927514, next:20121000 invalid dropping st:0
DTS 4294927580, next:20187000 st:0 invalid dropping

請教一下

請問一定有要httpserver才能進行rtmp server的傳送嗎?
我看ffmpeg的命令是抓推送到httpserver的URL
有可能可以直接收到串流就傳送到 rtmp server?

转码之后播放的很快

我是这样转码的-c copy -codec:v mpeg1video -s 600x400 -r 20 -f mpegts
你这有帧率,码率和分辨率的要求没?播放的时候就像快进一样

Connection to tcp://localhost:1935 failed

java.io.IOException: Broken pipe
at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
at sun.nio.ch.FileDispatcherImpl.write(FileDispatcherImpl.java:60)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
at sun.nio.ch.FileChannelImpl.write(FileChannelImpl.java:211)
at cn.org.hentai.jtt1078.video.PublisherManager$Publisher.publish(PublisherManager.java:194)
at cn.org.hentai.jtt1078.video.PublisherManager.publish(PublisherManager.java:82)
at cn.org.hentai.jtt1078.server.Jtt1078Handler.channelRead0(Jtt1078Handler.java:60)
at cn.org.hentai.jtt1078.server.Jtt1078Handler.channelRead0(Jtt1078Handler.java:19)
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.channelRead(ByteToMessageDecoder.java:284)
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)
ideo: h264 (Main), yuv420p, 352x288, 25 fps, 25 tbr, 1200k tbn, 50 tbc
[tcp @ 0x24f38c0] Connection to tcp://localhost:1935 failed (Connection refused), trying next address
rtmp://localhost/ccav/013800138000-1: Input/output error
[hentai] 2019-06-25 15:14:10,684 [DEBUG] [video-server] - PublisherManager - publisher-1 timeout and close automatically

qq群搜不到了

readme中的qq群搜不到了,是人满了,还是解散了?还有其它能查看相关项目的地方吗

用子进程合并音视频流时第二个管道文件打开时就会卡死

请教下大佬,采用fifo这分分支,通过ffmpeg子进程合并音视频流时,如下:
process = Runtime.getRuntime().exec(
String.format("%s -report -re -r 25 -f h264 -i %s -f h264 -f s16le -ar 8000 -ac 1 -i %s -vcodec copy -acodec aac -strict -2 "
+ " -map 0:v:0 -map 1:a:0 -probesize 512 -analyzeduration 100 -f flv %s",
Configs.get("ffmpeg.path"),
videoFifoPath,
audioFifoPath,
"/mnt/d/temp/muxTest.flv"
)
);
第一个输入管道文件 videoFifoPath可以调用FileOutputStream打开,第二则会卡死,导致音频数据无法写。我 又通过其它测试,发现用ffmpeg 接受多个管理文件输入时,只有第一个打得开
比如上 面就有如下现象:
FileOutputStream videoFos = new FileOutputStream(videoFifoPath); //可以正常执行
FileOutputStream audioFos = new FileOutputStream(audioFifoPath); //卡死在这(调试跟踪是内部方法 native open0()时卡住
这就导致音频数据无法写入,大家有这种现象吗?

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

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) 推流就异常了

为什么会报权限不够

java.lang.RuntimeException: java.io.IOException: Cannot run program "/monchickey/mkfifo": error=13, 权限不够
at cn.org.hentai.jtt1078.video.PublisherManager.mkfifo(PublisherManager.java:230)
at cn.org.hentai.jtt1078.video.PublisherManager.access$100(PublisherManager.java:20)
at cn.org.hentai.jtt1078.video.PublisherManager$Publisher.open(PublisherManager.java:143)
at cn.org.hentai.jtt1078.video.PublisherManager.request(PublisherManager.java:66)
at cn.org.hentai.jtt1078.server.Jtt1078Handler.channelRead0(Jtt1078Handler.java:47)
at cn.org.hentai.jtt1078.server.Jtt1078Handler.channelRead0(Jtt1078Handler.java:19)
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.channelRead(ByteToMessageDecoder.java:284)
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)
Caused by: java.io.IOException: Cannot run program "/monchickey/mkfifo": error=13, 权限不够
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at java.lang.Runtime.exec(Runtime.java:620)
at java.lang.Runtime.exec(Runtime.java:450)
at java.lang.Runtime.exec(Runtime.java:347)
at cn.org.hentai.jtt1078.video.PublisherManager.mkfifo(PublisherManager.java:224)
... 26 more
Caused by: java.io.IOException: error=13, 权限不够
at java.lang.UNIXProcess.forkAndExec(Native Method)
at java.lang.UNIXProcess.(UNIXProcess.java:247)
at java.lang.ProcessImpl.start(ProcessImpl.java:134)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 30 more

我用我自己的设备发送数据会报错

io.netty.handler.codec.DecoderException: java.lang.RuntimeException: exceed the max buffer size, max length: 4096, data length: 512
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:459)
at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:392)
at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:359)
at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:342)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:224)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1409)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:245)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:231)
at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:927)
at io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:822)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:463)
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)
Caused by: java.lang.RuntimeException: exceed the max buffer size, max length: 4096, data length: 512
at cn.org.hentai.jtt1078.util.ByteHolder.write(ByteHolder.java:32)
at cn.org.hentai.jtt1078.util.ByteHolder.write(ByteHolder.java:26)
at cn.org.hentai.jtt1078.server.Jtt1078Decoder.write(Jtt1078Decoder.java:16)
at cn.org.hentai.jtt1078.server.Jtt1078Decoder.write(Jtt1078Decoder.java:23)
at cn.org.hentai.jtt1078.server.Jtt1078MessageDecoder.decode(Jtt1078MessageDecoder.java:31)
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489)
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428)
... 17 more

内存泄漏

Subscriber类中的take方法被interrupt异常拦截时需要再标记下interrupt,否则线程无法正常结束导致越来越多,最终结果就可能内存溢出
protected byte[] take()
{
byte[] data = null;
try
{
synchronized (lock)
{
while (messages.isEmpty())
{
lock.wait(100);
if (this.isInterrupted()) return null;
}
data = messages.removeFirst();
}
return data;
}
catch(Exception ex)
{
this.interrupt(); //需加入
return null;
}
}

多摄像头同时推流,cpu占用接近100,导致卡死

目前单个摄像头单通道可以稳定直播,cpu占用也还行,
目前我的服务器是16核的,同时15个通道一起推流,用top看 cpu占用到了90%,然后各种卡顿了,请问有什么解决方案吗?是需要FFmpeg调用gpu去推流还是什么?

G711 音頻 toPCM問題

你好,最近我使用裝置送上來的音頻,編碼是G711,但經過toPCM轉換之後,聲音會變成怪怪的,有把來源data直接存成檔案是清楚的,稍微改動了一下,G711 toPCM裡面的程式碼,但還是沒法讓聲音清楚,所以想跟您請教一下,如果需要我也能將dump下來的音頻檔案寄給您。

unknown directive "rtmp"

我的nginx版本信息如下
nginx version: nginx/1.9.12
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --add-dynamic-module=/usr/local/nginx_http_flv/nginx-http-flv-module

为何include nginx_rtmp.conf后会出现这个报错提示
unknown directive "rtmp" in /usr/local/nginx/conf/nginx_rtmp.conf:4

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.