RTSP协议 转 RTMP协议并推流,java实现

采用JavaCv + Nginx + maven + Idea + JDK1.8 + VLC播放器

通过java代码的方式实现实时直播 通过获取RTSP协议转码为RTMP协议,通过设置对应的RTMP输出地址为推流地址,

	@PostMapping("/v1/trans-Coding")
    public Object transCoding(String link, String linkName) throws Exception {
        // 读取RTSP视频资源 传入Rtsp连接
        final FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(link);
        // 设置分辨率宽度
        int captureWidth = 1280;
        grabber.setImageWidth(captureWidth);
        // 设置分辨率高度
        int captureHeight = 720;
        grabber.setImageHeight(captureHeight);
        // rtsp格式一般添加TCP配置,否则丢帧会比较严重
        // 该参数改成udp可以解决部分电脑出现的下列报警,但是丢帧比较严重 不采用
        // av_interleaved_write_frame() error -22 while writing interleaved video packet.
        grabber.setOption("rtsp_transport", "tcp");
        grabber.start();
        // 流媒体输出地址,最后一个参数是"音频AudioChannels 0:不录制,1:录制",建议通过grabber获取 
        // 地址格式为 rtmp:rtmp://{ip}:{nginx端口}/{该name为传过来的任意值}
        final FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("rtmp://127.0.0.1:8012/hls/"+linkName, captureWidth, captureHeight, grabber.getAudioChannels());
        recorder.setInterleaved(true);
        // 降低编码延时
        recorder.setVideoOption("tune", "zerolatency");
        // 提升编码速度
        recorder.setVideoOption("preset", "ultrafast");
        // 视频质量参数(详见 https://trac.ffmpeg.org/wiki/Encode/H.264)
        recorder.setVideoOption("crf", "28");
        // 分辨率
        recorder.setVideoBitrate(2000000);
        // 视频编码格式
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        // 视频格式
        recorder.setFormat("flv");
        // 视频帧率
        recorder.setFrameRate(15);
        recorder.setGopSize(60);
        recorder.setAudioOption("crf", "0");
        recorder.setAudioQuality(0);
        recorder.setAudioBitrate(192000);
        recorder.setSampleRate(44100);
        // 建议从grabber获取AudioChannels
        recorder.setAudioChannels(grabber.getAudioChannels());
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        recorder.start();

        // 解决音视频同步导致的延时问题
        Field field = recorder.getClass().getDeclaredField("oc");
        field.setAccessible(true);
        AVFormatContext oc = (AVFormatContext) field.get(recorder);
        oc.max_interleave_delta(100);

        // 用来测试的frame窗口  这个地方对应的注释释放开,可以进行代码测试
        // final CanvasFrame cFrame = new CanvasFrame("frame");
        Frame capturedFrame = null;

        // 有些时候,程序执行回报下列错误,添加一行代码解决此问题
        // av_interleaved_write_frame() error -22 while writing interleaved video packet.
        // grabber.flush();

        while (grabber.grab() != null) {
            capturedFrame = grabber.grab();
            // if (cFrame.isVisible()) {
            // 设置图像
            // cFrame.showImage(capturedFrame);
            // } else {
            // 获取每帧的编号 -- 时间戳
            System.out.println(grabber.getFrameNumber() + "--" + capturedFrame.timestamp);
            recorder.setTimestamp(capturedFrame.timestamp);
            recorder.record(capturedFrame);
            // }
        }
        // cFrame.dispose();
        recorder.close();
        grabber.close();
        return CommSuccessNullResp.create();
    }

maven地址

		<!--javaCV-->
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv-platform</artifactId>
            <version>1.5.1</version>
        </dependency>

Nginx配置文件

worker_processes  1;
 
error_log  logs/error.log  notice;
 
events {
    worker_connections  1024;
}
 
rtmp {  
    server {
        listen 8012;
        application myapp {
            live on;  
       }  
        application hls {  
            live on;  
            hls on;  
            hls_path E:\RTMP\hls;   #看这里用了绝对路径 可改为服务器地址 记得要与下面对应
            hls_fragment 1s;
            hls_playlist_length 3s;  #m3u8和ts在hls文件夹下的保存时间
       }  
    } 
}
 
http {
    server {
        listen 8011;
        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
		location /hls {  #这个hls和推流命令对应
			types {
				application/vnd.apple.mpegurl m3u8; 
				video/mp2t ts;
			}
			alias E:\RTMP\hls;  #还有这里
			expires -1;
		}
	}
}

Nginx下载可在网上搜索 nginx-1.7.11.3-Gryphon该版本进行下载,因为这个版本中自带的有rtmp模块
链接:https://pan.baidu.com/s/1-E8t8uegcL3HFG4IBbJafA
提取码:asdf

启动命令: nginx.exe -c conf\nginx-win-rtmp.conf

rtsp测试地址 : rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov

rtmp地址格式 : rtmp://{本机ip或服务器ip}:{nginx端口}/{为代码中设置的值}
通过上面的rtmp格式可在VLC播放器中查看推流视频信息

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值