多个海康摄像头的rtsp读取,放在web中预览;
使用javacv实现rtsp转stmp,网上找了好多方法但都不符合业务,于是自己封装了一个。
功能依赖nginx-rtmp服务器,不搞什么上传资源了,评论获取。
代码:
package com.app.rtmp;
import java.util.HashMap;
import java.util.Map;
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
public class Rtsp2RtmpPacket {
/**
* 此处应用场景为多个摄像头rtsp流的读取
*/
public static Map<String, Rtsp2RtmpPacket> PACKETS = new HashMap<>();
public boolean exit = false;
private FFmpegFrameGrabber grabber;
private FFmpegFrameRecorder recorder;
public static void getStart(String sessionId, String rtspUrl, String rtmpUrl) {
getStop(sessionId);
Rtsp2RtmpPacket packet = new Rtsp2RtmpPacket();
PACKETS.put(sessionId, packet);
new Thread(new Runnable() {
@Override
public void run() {
packet.push(rtspUrl, rtmpUrl);
}
}).start();
}
public static void getStop(String sessionId) {
try {
Rtsp2RtmpPacket rtmpPacket = PACKETS.get(sessionId);
if (rtmpPacket != null) {
rtmpPacket.setExit(true);
PACKETS.remove(sessionId);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void push(String rtspUrl, String rtmpUrl) {
try {
int width = 1600, height = 900;
grabber = FFmpegFrameGrabber.createDefault(rtspUrl);
grabber.setOption("rtsp_transport", "tcp"); // tcp方式防止丢包
grabber.setImageWidth(width);
grabber.setImageHeight(height);
grabber.start();
recorder = new FFmpegFrameRecorder(rtmpUrl, width, height, grabber.getAudioChannels());
recorder.setInterleaved(true);
recorder.setVideoOption("tune", "zerolatency"); // 降低编码延时
recorder.setVideoOption("preset", "ultrafast"); // 提升编码速度
recorder.setVideoOption("crf", "28"); // 视频质量参数(详见 https://trac.ffmpeg.org/wiki/Encode/H.264)
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setFormat("flv"); // 封装格式flv rtmp使用
recorder.setVideoBitrate(2000000);
recorder.setFrameRate(25); // 视频帧率(保证视频质量的情况下最低25,低于25会出现闪屏)
recorder.setPixelFormat(0);
recorder.setAudioQuality(0);// 最高质量
recorder.setAudioBitrate(192000);// 音频比特率
recorder.setSampleRate(44100);// 音频采样率
recorder.setAudioChannels(grabber.getAudioChannels());// 双通道(立体声) 2(立体声);1(单声道);0(无音频)
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);// 音频编/解码器
recorder.start();
while (!exit) {
Frame frame = grabber.grabImage();
if (frame == null) {
grabber.start();
continue;
}
recorder.record(frame);
}
recorder.stop();
recorder.release();
grabber.stop();
grabber.release();
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean isExit() {
return exit;
}
public void setExit(boolean exit) {
this.exit = exit;
}
public static void main(String[] args) {
Rtsp2RtmpPacket.getStart("1001", "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov", "rtmp://127.0.0.1:6004/live/test");
}
}
存在问题:
出现[h264 @ 000000001d3dfe40] error while decoding MB 29 5, bytestrea,在网上找解决方法,无果,还好需求对视频完整性要求不高,就在获取失败时重新调用获取的start()方法;详见代码。
音频没有。。。
一知半解最可怕,还待深入了解,望大牛指导。
代码是在网上横飞的一段不知道出处的代码的基础上加以封装的,侵删。