SpringBoot+vue 实现监控视频rtsp播放(java+Nginx+ffmpeg+flv.js)

news2024/11/26 10:46:16

其实原理就是: 将监控通过FFMPEG,推送给Nginx,前端通过Nginx地址拉取视频,就可以播放了。

1:安装FFMPEG.
2:下载并且配置nginx.
3:使用java代码实现调用cmd或者linux窗口,并且运行操作FFMPEG的命令,进行监控视频rtsp格式的推送,推送给nginx.
4:前端写一个video标签就可以,Src写nginx的固定地址就可以。

windows: url: 【在上面3:中提到的,通过ffmeg推送给nginx的命令如下】

ffmpeg -rtsp_transport tcp -i 你的rtsp地址 -c:v libx264 -c:a aac -f flv -an rtmp://你的nginx地址:nginx配置的拉取端口号/myapp/room

linux:url:

ffmpeg -f rtsp -rtsp_transport tcp -i ' 你的rtsp地址监控视频' -codec copy -f flv -an 'rtmp://你的nginx地址:nginx配置的拉取端口号/myapp/room'

环境

  • 本地系统 win10
  • centos7:Nginx
  • 开源程序:ffmpeg
  • 前端:Vue
  • 后端SpringBoot

一、下载所需要的FFMPEG安装包

  • windows下载FFmpeg FFMpeg windows版本
    -https://www.gyan.dev/ffmpeg/builds/
    ffmpeg官网截图
    下载后长这样
    将此文件解压到你喜欢的的文件夹【比如这样】
    在这里插入图片描述
    接着配置环境变量
    进入到解压后的目录找到bin 、复制bin目录路径----然后配置系统环境变量【下图所示】
    配置环境变量
    cmd查看一下是否成功
ffmpeg 

检测是否安装成功
至此这个这个玩意就安装完成了

安装nginx

依照你喜欢的方式安装nginx 可以使用docker、yum、安装包 等等方式都可以
我使用直接解压的方式
可以去nginx官网下载喜欢的nginx版本 ,上传到服务器
在这里插入图片描述
解压然后编译(这个应该不难,可以使用 make make install )
安装完成之后长这样
在这里插入图片描述
可以看到我这个截图上多了一个 nginx-http-flv-module 这个目录,这个是必要安装的一个模块
否则无法实现正常的监控视频播放

给Nginx安装 nginx-http-flv-module模块

建议直接下载到nginx的目录下、我安装到了 /user/loacl/nginx/ 文件夹下了
下载地址:https://github.com/winshining/nginx-http-flv-module
安装依赖项

yum -y install unzip
yum -y install gcc-c++ 
yum -y install pcre pcre-devel  
yum -y install zlib zlib-devel 
yum -y install openssl openssl-devel

将nginx-http-flv-module模板添加到nginx中,生成make文件 并安装nginx

./configure --prefix=/usr/local/nginx  --add-module=/usr/local/nginx/nginx-http-flv-module
make && make install

检查是否安装成功

nginx -V

在这里插入图片描述
出现这个就是代表安装成功了
安装基本已经成形---------接下来配置nginx的配置文件

nginx配置文件

## 编辑nginx配置文件
vim conf/nginx.conf

在这里插入图片描述
nginx的配置文件大概就是这样的(完成的nginx配置文件 我也会在下面附上,可以直接复制* 嗷对 需要修改成你的ip 或者域名)
在这里插入图片描述

在这里插入图片描述
下面是完整的ngin配置文件

worker_processes  10; #should be 1 for Windows, for it doesn't support Unix domain socket
#worker_processes  auto; #from versions 1.3.8 and 1.2.5

#worker_cpu_affinity  0001 0010 0100 1000; #only available on FreeBSD and Linux
#worker_cpu_affinity  auto; #from version 1.9.10

error_log logs/error.log error;

#if the module is compiled as a dynamic module and features relevant
#to RTMP are needed, the command below MUST be specified and MUST be
#located before events directive, otherwise the module won't be loaded
#or will be loaded unsuccessfully when NGINX is started

#load_module modules/ngx_http_flv_live_module.so;

events {
    worker_connections  10240;
}

http {
    	include       mime.types;
    	default_type  application/octet-stream;
    	sendfile        on;
   	keepalive_timeout  65;
    	server {
        	listen       9000; #http-flv的拉流端口
        	server_name  【这个地方写你的ip、或者说是域名都是可以的--】; #http-flv的拉流ip
        	location / {
            	root   html;
            	index  index.html index.htm;
       		}
            #http-flv的相关配置
        	location /live{
                flv_live on; #打开HTTP播放FLV直播流功能
                chunked_transfer_encoding  on;
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Credentials' 'true';
        	}
        	location /hls{
                types {
                	application/vnd.apple.mpegurl m3u8;
			video/mp2t ts;
                 }
                 root /usr/local/nginx/html/hls;
                 add_header 'Cache-Control' 'no-cache';
        	}
         	location /dash {
            	root /usr/local/nginx/html/dash;
            	add_header 'Cache-Control' 'no-cache';
        	}
 
         	location /stat {
            	#configuration of push & pull status
              	rtmp_stat all;
              	rtmp_stat_stylesheet stat.xsl;
         	}
        	location /stat.xsl {
          		root /usr/local/nginx/nginx-http-flv-module;
        	}
 
         	location /control {
            	rtmp_control all; #configuration of control module of rtmp
			}
 
        	error_page   500 502 503 504  /50x.html;
        	location = /50x.html {
            	root   html;
        	}
    	}
 
}

rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp;


rtmp{
        out_queue 4096;
        out_cork 8;
        max_streams 128;
        timeout 15s;
        drop_idle_publisher 15s;
        log_interval 5s;
        log_size 1m;
        server{
            #推流端口
        	listen 1935;
            #推流应用名称
         	application myapp{
                 live on;
	 	 record off;
                 gop_cache on;
          	}
         	application hls{
          		live on;
          		hls on;
          		hls_path /usr/local/nginx/html/hls;
          		hls_fragment 1s;
                        hls_playlist_length 3s;
        	}
         	application dash{
           		live on;
           		dash on;
           		dash_path /usr/local/nginx/html/dash;
         	}
 
        }
}

测试一下是否可以使用:准备一个可播放的rtsp地址例如:海康、大华、。。。。。都可以试试
打开cmd 开始调用 ffmpeg

ffmpeg -rtsp_transport tcp -i rtsp://user:pwd@ip:31554/h264/ch1/main/av_stream -c:v libx264 -c:a aac -f flv -an rtmp://nginx的ip:nginx所配的端口/myapp/room

如果出现如下,有速度就代表可以成功
在这里插入图片描述
可以使用地址本地测试一下有没有画面

'http://nginx的ip:nginx访问的端口9000/live?port=1935&app=myapp&stream=room'

打开VLC media player
在这里插入图片描述
在这里插入图片描述

前端 (vue)

引入Flv.js
在这里插入图片描述
然后接下来就这么写【如下图】会附上全代码
在这里插入图片描述
在这里插入图片描述

<template>
  <a-modal
    :title="title"
    :width="510"
    :visible="visible"
    switchFullscreen
    @ok="handleOk"
    @cancel="handleCancel"
    cancelText="关闭"
  >
    <a-spin :spinning="confirmLoading">
      <j-form-container>
        <a-form :form="form" slot="detail">
          <a-row>
            <video autoplay controls width="100%" height="270" id="videoElement"></video>
          </a-row>
        </a-form>
      </j-form-container>
    </a-spin>
  </a-modal>
</template>
  
<script>
import flvjs from 'flv.js'
import JFormContainer from '@/components/jeecg/JFormContainer'
import { getAction } from '../../../api/manage'
export default {
  name: 'VidoModule',
  components: {
    JFormContainer,
    flvjs,
  },
  data() {
    return {
      flvPlayer:1,
      title: '监控',
      //源视频地址
      videoPath:'',
      videoStream: '',
      confirmLoading: false,
      visible: false,
      form: this.$form.createForm(this),

      url: {
      	//开启视频  
        list: '自己的请求地址',
        //关闭视频输出
        list1:'。。。'
      },
    }
  },
  mounted() {
  },

  methods: {
    // 开启页面
    show(record) {
      this.visible = true
      this.videoPath = record.videoPath
      this.VideoData(this.videoPath);
      this.createVideo()
    },

    VideoData(videoPath){
      getAction(this.url.list,{videoPath:videoPath}).then((res) => {

      })
    },
    
    //传输视频地址
    createVideo() {
      if (flvjs.isSupported()) {
        let videoElement = document.getElementById('videoElement')
        let flvPlayer = flvjs.createPlayer({
          type: 'flv',
          isLive: true,
          fluid: true,
          stashInitialSize: 128,// 减少首桢显示等待时长
          url: 'http://xxx.xxx.xxx.xxx:9000/live?port=1935&app=myapp&stream=room', //url地址

        })
        //console.log(videoUrl+'      videoUrl')
        flvPlayer.attachMediaElement(videoElement)
        flvPlayer.load()
        flvPlayer.play()
      }
    },
    close() {
      this.$emit('close')
      this.visible = false
      this.closeFfmpeg()
    },
    //  关闭视频的输出
    closeFfmpeg(){
      getAction(this.url.list1).then((res) => {

      })
    },
    handleOk() {
      this.submitForm()
    },
    submitCallback() {
      this.$emit('ok')
      this.visible = false
    },
    handleCancel() {
      this.close()
    },
  },
}
</script>
<style lang="less" scoped>
</style>

后端 SpringBoot

后端其实就是通过java 去调用本地或者服务器上的FFMPEG,使用cmd 或者 shell的方式都可以
其实就是执行一下命令而已
CommandUtil.java

package common.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @Description: 调用命令 【windows&Linux】 @Author: cq @Date: 2022/12/20 @Version: V1.0
 * 用于启动ffmpeg 随之将rtsp 转化为rtmp 返回给Flv.js使用
 */

public class CommandUtil {

  /** 调用linux命令* */
  public String linuxExec(String cmd) {
    System.out.println("执行命令[ " + cmd + "]");
    Runtime run = Runtime.getRuntime();
    try {
      Process process = run.exec(cmd);
      String line;
      BufferedReader stdoutReader =
          new BufferedReader(new InputStreamReader(process.getInputStream()));
      StringBuffer out = new StringBuffer();
      while ((line = stdoutReader.readLine()) != null) {
        out.append(line);
      }
      try {
        process.waitFor();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      process.destroy();
      return out.toString();
    } catch (IOException e) {
      e.printStackTrace();
    }
    return null;
  }
  /** 调用windwos命令* */
  public String winExec(String cmd) {
    Runtime runtime = Runtime.getRuntime();
    String command =cmd;
    try {
      Process process = runtime.exec(command);
      new InputStreamReader(process.getInputStream());
      return "成功";
    } catch (IOException e) {
      e.printStackTrace();
      return "请检查摄像头地址";
    }
  }
}
package org.ept.modules.solidwaste.controller;

import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ept.common.api.vo.Result;
import org.ept.common.util.CommandUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * @Description: 视频输出 @Author: cq @Date: 2022/11/30 @Version: V1.0
 */
@Api(tags = "视频格式转换---windows-->cmd---linux")
@RestController
@RequestMapping("/video/videos")
@AllArgsConstructor
@Slf4j
public class videoTestController {
  /** Windows系统* */
  private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase().contains("win");
  /** Linux系统* */
  private static final boolean IS_LINUX = System.getProperty("os.name").toLowerCase().contains("Linux");


  /** 视频播放指令执行 rtsp地址【源播放地址】通过ffmpeg程序进行转化成rtmp,将地址传给flv.js进行播放 */
  @GetMapping("/videoStart")
  public void videoPreview(@RequestParam(name = "videoPath", required = false) String videoPath) {
    CommandUtil commandUtil = new CommandUtil();
    /*如果是winodws系统**/
    if (IS_WINDOWS) {
      String cmd ="cmd /k start ffmpeg -rtsp_transport tcp -i"
                      + " "
                      + videoPath
                      + " "
                      + "-c:v libx264 -c:a aac -f flv -an rtmp://xxx.xxx.xxx.xxx:1935/myapp/room";
      commandUtil.winExec(cmd);
    }
    /*如果是Linux系统**/
    if (IS_LINUX){
      System.out.println("linux");
      String cmd = "ffmpeg -f rtsp -rtsp_transport tcp -i '"
              + ""
              + videoPath
              + "'"
              + ""
              + " -codec copy -f flv -an 'rtmp://xxx.xxx.xxx.xxx:1935/myapp/room'";
      commandUtil.linuxExec(cmd);
    }
  }

  /** 关闭ffmpeg.exe程序 */
  @GetMapping("/videoClose")
  public Result<?> close() {
    closeHistoryProgram("ffmpeg.exe");
    return Result.ok("已成功停止");
  }

  public void closeHistoryProgram(String processName) {
    String cmd = "taskkill /f /t /im " + processName;
    try {
      // exec执行cmd命令
      Process process = Runtime.getRuntime().exec(cmd);
      // 获取CMD命令结果的输出流
      InputStream fis = process.getInputStream();
      InputStreamReader isr = new InputStreamReader(fis, "GBK");
      // 使用缓冲器读取
      BufferedReader br = new BufferedReader(isr);
      String line = null;
      // 全部读取完成为止,一行一行读取
      while ((line = br.readLine()) != null) {
        // 输出读取的内容
        System.out.println(line);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

}

大概就是这么个意思
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/621488.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

模板方法设计模式的学习和使用

1、模板方法设计模式的学习 当涉及到一系列具有相似行为的算法或操作时,模板方法设计模式是一种有效的设计模式。它允许你定义一个算法的骨架,同时将某些步骤的实现细节交给子类来实现。   模板方法模式基于以下两个核心原则&#xff1a; 抽象类定义模板方法骨架&#xff1a…

chatgpt赋能python:Python将一张图片分割成多张:从理论到实践

Python将一张图片分割成多张&#xff1a;从理论到实践 简介 随着Internet的爆炸式增长&#xff0c;图片已经成为了我们生活中不可或缺的一部分。具有高质量、高清晰度的图片可以提升网站的美观程度&#xff0c;帮助网站吸引更多的用户。但是&#xff0c;有时候大型的图片并不…

chatgpt赋能python:Python并不是一门简单的编程语言

Python 并不是一门简单的编程语言 Python 是一门直观且易学的编程语言&#xff0c;这一点没有错&#xff0c;但是要说它是简单的&#xff0c;那其实是不准确的。Python 有着广泛的应用领域&#xff0c;包括人工智能、大数据分析、Web开发、自动化测试等。尽管初学者可以迅速上…

MySQL中BETWEEN AND(范围查询)

0 写在前面 MySQL 提供了 BETWEEN AND 关键字&#xff0c;用来判断字段的数值是否在指定范围内。 BETWEEN AND 需要两个参数&#xff0c;即范围的起始值和终止值。如果字段值在指定的范围内&#xff0c;则这些记录被返回。如果不在指定范围内&#xff0c;则不会被返回。 最近…

JS 装饰器

JS 装饰器 JavaScript 装饰器是一种以 符号开头的特殊语法&#xff0c;放在目标代码的前面用于包装或扩展代码功能。JavaScript 的装饰器语法目前仍处于提案阶段&#xff0c;现阶段使用的话需要通过 bable 等方式进行编译之后&#xff0c;才能在浏览器正常运行。装饰器分为两…

chatgpt赋能python:Python将空值替换成0

Python 将空值替换成 0 在数据分析和处理过程中&#xff0c;清洗数据往往是非常重要的一个环节。而在清洗数据过程中&#xff0c;经常会遇到空值&#xff08;Missing Values&#xff09;的问题。空值是指在数据集中出现的缺失值&#xff0c;它可能是由于数据输入错误、数据采集…

chatgpt赋能python:Python定义数据框:介绍和基础操作

Python定义数据框&#xff1a;介绍和基础操作 数据框是一种非常方便的数据结构&#xff0c;用于在Python中存储和处理表格数据。数据框可以看作是围绕Series对象构建的2D数据结构&#xff0c;Series是一种存储单个列的一维标记数组。在本文中&#xff0c;我们将介绍如何使用Py…

基于树莓派4B的车牌号识别

目录 0. 前言1. Raspbian系统烧录2. 更换清华源1. 查看树莓派系统版本2. 更换清华国内源3. Raspi镜像修改4. 系统源更新5. 错误排查 3. opencv安装4. 安装 hyperlprpip安装编译安装 5. 验证项目可行性 0. 前言 基于树莓派4B的车牌号识别系统 操作系统&#xff1a;Raspbian PC…

QT实例2(QTableWidget表格中增删数据)

案例介绍 本案例仅简单介绍QTableWidget部分使用方法&#xff0c;如在表格中插入或删除一行数据以及清空表格数据等。在添加数据时&#xff0c;设置了条件判断如正则表达式&#xff0c;若用户输入的数据不合法&#xff0c;则添加失败并提示用户错误的地方&#xff0c;便于用户…

IPsec的NAT穿越详解

问题场景 左边的支部&#xff0c;它的防火墙上联路由器&#xff0c;由于防火墙内部的接口使用的是私网地址&#xff0c;这就导致其无无法在公网上与对端防火墙进行IPsec的隧道建立 。所以必须在AR5上面不是NAT地址转换&#xff0c;由于一般使用的是NAPT&#xff0c;isakmp协议因…

ChatGPT评测

总结&#xff1a;ChatGPT很强大&#xff0c;用作学术方面的问答或者软件行业的辅助工具是有一定的作用&#xff0c;但是有些回答设置了限制&#xff0c;并且中文回答方面总是回答一半&#xff0c;需要一直让他继续说&#xff0c;篇幅不是很长&#xff0c;但是往往能说道精髓&am…

最新加装ChatGPT的New Bing申请流程(含出错解决办法)

两天获得New Bing测试资格流程记录 前言一、Microsoft Edge Dev浏览器下载二、Microsoft账号注册与登陆三、浏览器插件下载与添加四、加入候补名单五、写封信给Bing团队 前言 2023.03.08&#xff0c;下午收到了Microsoft Bing公司的邮件&#xff0c;提示测试资格申请成功&…

Qt Xlsx的基本使用

前言 在很多时候 &#xff0c;我们需要将数据导出&#xff0c;之前我是将数据表导出为CSV格式&#xff0c;CSV文件虽然可以用Excel打开&#xff0c;但相对于真正的Xlsx文件&#xff0c;还是有许多不足的。偶然之间&#xff0c;发现了QtXlsx这个第三方库。 1、QtXlsx官网对QtX…

makefile工具的使用,编写一个或多个文件!(简单易上手)

一、make 和 makefile 是什么 1. make 是一个 命令。 2. makefile 是一个 文件&#xff0c;可以自动化的构建项目。 3. 编写 makefile 需要&#xff1a; &#xff08;1&#xff09;依赖关系 &#xff08;2&#xff09;依赖方法 二、什么是依赖关系、什么是依赖方法 下面我简单…

【Java】Java核心要点总结:60

文章目录 1. 乐观锁一定就是好的吗2. Synchronized和ReentrantLock有什么异同3. ReentrantLock是如何实现可重入性的4. 和Synchronized相比&#xff0c;可以重入锁ReentrantLock实现原理有什么不同5. AQS框架 1. 乐观锁一定就是好的吗 乐观锁并不一定好&#xff0c;它有自己的适…

chatgpt赋能python:Python实现将一张图片贴到另一张图片上

Python实现将一张图片贴到另一张图片上 在图像处理中&#xff0c;往往需要将多张图片合成一张图片。这里介绍使用Python实现将一张图片贴到另一张图片上的方法。 准备工作 在实现之前&#xff0c;我们需要安装Python的图像处理库Pillow和numpy。 可以通过pip进行安装&#…

创建一个SpringBoot项目

Spring的诞生是为了简化JAVA程序的开发的 快速开发Spring而诞生的 SpringBoot为了快速开发Spring而诞生的一个框架 1)什么是SpringBoot&#xff1f;为什么要学它?(重要) Spring是包含了众多工具方法的IOC容器 SpringBoot就是Spring框架的脚手架&#xff0c;它的存在就是为了快…

软考A计划-系统架构师-官方考试指定教程-(2/15)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

chatgpt赋能python:Python屏幕输入介绍:了解命令行输入的基本知识

Python屏幕输入介绍&#xff1a;了解命令行输入的基本知识 Python是一种使用广泛的编程语言&#xff0c;用于编写各种类型的应用程序&#xff0c;包括图形用户界面应用程序和基于命令行的应用程序。对于基于命令行的应用程序来说&#xff0c;屏幕输入非常重要。本文将介绍Pyth…

Object.assign用法

Object.assign用法 Object.assign是什么&#xff1f; 首先了解下Object.assign()是什么。我们先看看ES6官方文档是怎么介绍的&#xff1f; Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。简单来说&#xff0c;就是Obj…