设为首页 加入收藏

TOP

记录监控摄像头的接入过程及web端播放(一)
2023-07-25 21:36:53 】 浏览:103
Tags:程及 web

1.rtsp视频流网页播放概述

需求:当我们通过ONVIF协议,获取到了摄像头的rtsp流地址(长这样:rtsp://admin:123456789@192.168.9.16:554/cam/realmonitor?channel=1&subtype=1&unicast=true&proto=Onvif)后,通过vlc播放器,我们可以查看监控视频内容,可是,我们应该如何在网页上查看视频内容呢?因为现在的浏览器都不支持rtsp流,因此我所选用的解决方案便是推流 + 转码

(1)转码推流工具ffmpeg(安装教程详见:https://www.cnblogs.com/h2285409/p/16982120.html),安装好之后,便可使用命令 ffmpeg -re -rtsp_transport tcp -i rtsp://admin:123456789@192.168.9.16:554/cam/realmonitor?channel=1&subtype=1&unicast=true&proto=Onvif -c:v copy -c:a copy -f flv rtmp://127.0.0.1/live/16 将我们的rtsp视频流转码并推至流媒体服务器上,在这个命令中含有两个URL,前面的是我们的rtsp流地址,而后面的URL便是我们流媒体服务器的地址,以及一个-f参数,指定了我们视频流转码后的格式为flv

(2)流媒体服务器,主要调研了2款,一是整合了Rtmp模块的Nginx,二是SRS视频服务器,而我所选用的是SRS(官方文档:http://ossrs.net/lts/zh-cn/),在使用ffmpeg推流上SRS后,便可直接从SRS获得webRTC流地址(如本例:webrtc://192.168.4.23/live/16 ),为什么选用webRTC呢,因为它的延迟很低(也可以根据自己的需求选择其他的如http-flv或hls),然后,前端再通过webRTC播放器便可直接在页面上播放该直播流

SRS与ffmpeg参考:https://blog.csdn.net/diyangxia/article/details/120172920

ffmpeg进阶参考:https://segmentfault.com/a/1190000039782685

webRTC参考:https://www.cnblogs.com/ziyue7575/p/13927894.html

2.rtsp推流转码以及关闭推流相关代码实现

@Service
@Slf4j
public class MonitorServiceImpl {

    //ffmpeg安装路径
    @Value("${ffmpegPath}")
    private String ffmpegPathPrefix;

    //srs视频服务器地址
    @Value("${srsAddress}")
    private String srsAddress;

    //srs-http-api端口,默认为1985
    @Value("${srsHttpApiPort}")
    private String srsHttpApiPort;

    @Resource
    private MonitorMapper monitorMapper;

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    private ConcurrentMap<String, TranscodeModel> transcodeMap = new ConcurrentHashMap<>();

    private CopyOnWriteArrayList<ProcessOutputModel> processOutputList = new CopyOnWriteArrayList<>();

    /**
     * 进行推流转码
     */
    public String transcode(String id) {
        boolean success = false;
        try {
            if(transcodeMap.putIfAbsent(id, new TranscodeModel()) == null) {
                Ipc ipc = monitorMapper.getIpcInfoById(id);
                if(ipc == null) {
                    throw new RuntimeException("id为" + id + "的ipc不存在");
                }
                String rtspUrls = ipc.getRtspUrls();
                if(!StringUtils.hasText(rtspUrls)) {
                    try {
                        //如果流地址不存在,则输入ipc的ip地址,端口号,帐号,密码以及传输协议进行获取
                        rtspUrls = OnvifUtil.getRTSPUrl(ipc.getIp(), ipc.getPort(), ipc.getAccount(), ipc.getPassword(), TransportProtocol.TCP);
                    } catch (Exception e) {
                        throw new RuntimeException("获取id为 " + id +  " 的ipc的rtsp流地址失败,请检查该ipc是否开启或其配置信息是否正确");
                    }
                }
                if (!StringUtils.hasText(rtspUrls)) {
                    throw new RuntimeException("获取id为 " + id + "的ipc的rtsp流地址失败,请检查该摄像机是否开启或其配置信息是否正确");
                }
                //一般情况下获取到的ipc的rtsp流地址存在多个(主码流,辅码流或第三方码流等),我这里用了#号将它们进行分隔
                String[] allRtspUrl = rtspUrls.split("#");
                for (String rtspUrl : allRtspUrl) {
                    //使用ffprobe来获取流的一些信息,比如该流当前是否可用(在线),它的编码格式,分辨率以及fps等基本信息   将ffmpeg与ffprobe置于同一目录下
                    String requestStreamInfoCommand = String.format("%sffprobe %s", this.ffmpegPathPrefix,  rtspUrl);
                    //用于判断该ipc是否在线
                    boolean online = true;
                    //用于判断该获取流信息的进程是否应该结束
                    long lastReadTime = System.currentTimeMillis();
                    log.info("准备请求流 {} 的信息,其命令为 {}", rtspUrl, requestStreamInfoCommand);
                    Process requestStreamInfoProcess
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 1/8/8
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Java入门_一维数组_第一题_升序数.. 下一篇如何通过Java代码在Word中创建可..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目