SSM架构 +java后台 实现rtsp流转hls流,在前端html上实现视频播放

序言:书接上文,我们继续
SSM架构 +Nginx+FFmpeg实现rtsp流转hls流,在前端html上实现视频播放

步骤一:把rtsp流转化为hls流,用Java代码进行转换

java 复制代码
package com.tools;

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


public class RTSPtoHLS {

	public static void main(String[] args) {
		
		System.out.println("111111111111111111");
       
		String inputVideoPath="rtsp://admin:bfm100766@192.168.1.64:554/streaming/channels/101";
		String outputVideoPath ="D:/nginx/html/orb/test.m3u8";
		
		generateVideo( inputVideoPath,  outputVideoPath);
    }
	
	
	//视频拼接的接口
		 public static boolean generateVideo(String inputVideoPath, String outputVideoPath) {
		        try {
		            // 构建FFmpeg命令,这里假设是将输入视频与模板视频合成,并输出成片
		            // 命令示例: ffmpeg -i input.mp4 -i template.mp4 -filter_complex "your_complex_filter_graph" output.mp4
		            // "your_complex_filter_graph" 是你用来应用模板的复杂滤波图
		        	// ffmpeg -fflags +genpts -i rtsp://admin:bfm100766@192.168.1.64:554/streaming/channels/101 -c copy -f hls -hls_time 2.0 -hls_list_size 1  D:/nginx/html/hls/test.m3u8
		            String[] command = new String[]{
		                "ffmpeg",
		                "-fflags", "+genpts",
		                "-i", inputVideoPath,
		                "-c", "copy",
		                "-f", "hls",
		                "-hls_time","10",
		                "-hls_list_size","10",
		                outputVideoPath
		            };                                        
		            ProcessBuilder processBuilder = new ProcessBuilder(command);
		            Process process = processBuilder.start();
		            // 读取错误流并打印
		            BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
		            String line;
		            while ((line = errorReader.readLine()) != null) {
		                System.out.println(line);
		            }
		            // 等待进程结束 
		            process.waitFor();
		            System.out.println("Video generation completed!!!");
		            return true;
		        } catch (IOException | InterruptedException e) {
		            e.printStackTrace();
		            System.out.println("Error generating video.");
		        }
				return false;
		    }
	
	
	
}

步骤二:SSM 架构中Controller层 如何调用

java 复制代码
package com.controller;

import java.util.Calendar;
import java.util.Timer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.tools.FileCleanupTask;
import com.tools.RTSPtoHLS;

@Controller
@RequestMapping("/rh")
public class RtspHlsController {

	
	       //1跳转到前端首页面
			@RequestMapping("/rh_login.html")
			public String  getdrLogin(HttpServletRequest request,HttpSession session)
			{
				
				
				
			     return "rh_login";
				
			}
	
			//使用传递 参数改变全局变量的参数
			 @ResponseBody
			 @RequestMapping(value="/setHls")
				public String set_Entity(HttpServletRequest request)			
			{ 
				
				 JSONObject  jsonObject=new JSONObject();
					
				 //第一步先清空nginx中hls文件夹中的内容 
				    String directoryPath = "D:/nginx/html/hls/";
				    
			        long thresholdSize = 2000 * 1024; //  文件阈值大小,例如10KB
			        // 创建定时任务
			        FileCleanupTask cleanupTask = new FileCleanupTask(directoryPath, thresholdSize);
			        
			        // 创建定时器并设置初始延迟为0,之后每5分钟执行一次任务(5 * 60 * 1000毫秒)
			        Timer timer = new Timer();
			        timer.schedule(cleanupTask, 60*60*1000, 60 * 60 * 1000); // 初始延迟为1000毫秒,之后每5分钟执行一次(5分钟=5*60*1000毫秒)
			        
				 
				 
				 //第二步nginx中录入中hls文件夹中内容 
				    //rtsp视频流的访问路径
				    String inputVideoPath="rtsp://admin:bfm100766@192.168.1.64:554/streaming/channels/101";
					
					//nginx的路径 把hls视频流输入到nginx服务器 hls文件夹中下
					String outputVideoPath ="D:/nginx/html/hls/test.m3u8";
					
					RTSPtoHLS.generateVideo( inputVideoPath,  outputVideoPath);
					
					jsonObject.put("saveUrl", outputVideoPath);
				 
				 
				 return   jsonObject.toString();
			}
			 
			
			//使用传递 参数改变全局变量的参数
			 @ResponseBody
			 @RequestMapping(value="/setHls1")
				public String set_Entity1(HttpServletRequest request)			
			{ 
				
				 JSONObject  jsonObject=new JSONObject();
					
				 //第一步先清空nginx中hls文件夹中的内容 
				    String directoryPath = "D:/nginx/html/hls/";
				    
			        long thresholdSize = 5000 * 1024; //  文件阈值大小,例如5000KB==5M
			        // 创建定时任务
			        FileCleanupTask cleanupTask = new FileCleanupTask(directoryPath, thresholdSize);
			        
			        // 创建定时器并设置初始延迟为0,之后每5分钟执行一次任务(5 * 60 * 1000毫秒)
			        Timer timer = new Timer();
			        //timer.schedule(cleanupTask, 60*60*1000, 60 * 60 * 1000); // 初始延迟为1000毫秒,之后每5分钟执行一次(5分钟=5*60*1000毫秒)
			        
			        //********设置每天的12点,执行某一函数************
			        
			        // 计算下一个12点的时间
			        Calendar calendar = Calendar.getInstance();
			        calendar.set(Calendar.HOUR_OF_DAY, 16); // 设置小时为12
			        calendar.set(Calendar.MINUTE, 40); // 设置分钟为0
			        calendar.set(Calendar.SECOND, 0); // 设置秒为0
			        calendar.set(Calendar.MILLISECOND, 0); // 设置毫秒为0
			 
			        // 如果当前时间已超过今天的12点,则设置明天的12点
			        if (calendar.before(Calendar.getInstance())) {
			            calendar.add(Calendar.DATE, 1); // 明天的日期
			        }
			        
			        // 安排任务在计算出的时间执行
			        timer.schedule(cleanupTask, calendar.getTime());
			        
			        
				 
				 
				 //第二步nginx中录入中hls文件夹中内容 
				    //rtsp视频流的访问路径
				    String inputVideoPath="rtsp://admin:bfm100766@192.168.1.64:554/streaming/channels/101";
					
					//nginx的路径 把hls视频流输入到nginx服务器 hls文件夹中下
					String outputVideoPath ="D:/nginx/html/hls/test.m3u8";
					
					RTSPtoHLS.generateVideo( inputVideoPath,  outputVideoPath);
					
					jsonObject.put("saveUrl", outputVideoPath);
				 
				 
				 return   jsonObject.toString();
			}
			
	
	
}

步骤三:html播放hls流视频

java 复制代码
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>  
<!DOCTYPE html>
<html>
	
	 <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0" />
        <title>FLV-HLS 监控视频播放展示界面</title>
        <link rel="stylesheet" href="${pageContext.request.contextPath }/statics/common/commonCss/bootstrap.min.css" />
        <link rel="stylesheet" href="${pageContext.request.contextPath }/statics/common/demo.css" />
        <script type="text/javascript" src="${pageContext.request.contextPath }/statics/common/commonJs/jquery.min.js"></script>
        <script type="text/javascript" src="${pageContext.request.contextPath }/statics/common/commonJs/bootstrap.min.js"></script>
        <script type="text/javascript" src="${pageContext.request.contextPath }/statics/common/player/dhhls.min.js"></script>
        <script type="text/javascript" src="${pageContext.request.contextPath }/statics/common/player/dhflv.min.js"></script>
    </head>
	
	
	<style>
	
	.mgt20 {
		margin-top: 20px;
		margin-bottom: 20px;
	}
	
	</style>
	<%-- ${saveUrl} --%>
	<body>
        <div class="demo-box">
            <div class="title">HLS播放器Demo</div>
            <div class="content">
                <!-- 左侧导航栏 -->
<!--                 <div class="nav-box">
                    <ul class="nav nav-pills" role="tablist" id="mainTabs">
                        <li role="presentation" class="nav-link list-group-item active-item"><a href="#home" aria-controls="home" role="tab" data-toggle="tab">HLS 视频流播放</a></li>
                        <li role="presentation" class="nav-link list-group-item"><a href="#profile" aria-controls="profile" role="tab" data-toggle="tab">FLV 视频流播放</a></li>
                    </ul>
                </div> -->
                <!-- tab主要内容 -->
                <div class="tab-content content-box">
                    <!-- HLS 播放 -->
                    <div role="tabpanel" class="tab-pane active" id="home">
                        <!-- 步骤引导 -->
                        <!-- <div class="common-step play-step">
                            <div class="sec-title">HLS视频流播放步骤</div>
                            <div class="step-box">
                                <div class="step-item">1. 获取HLS实时流地址(如何获取流地址请查看<a href="https://open-icc.dahuatech.com/hlsplayer/#5">HLS详细说明</a>),获取HLS录像回放流地址(如何获取流地址请查看<a href="https://open-icc.dahuatech.com/#/home?url=%3Fnav%3Dwiki%2Fadmin%2Freplay.html&version=enterprisebase/5.0.15&blank=true">详细说明</a>)</div>
                                <div class="line-with-arrow"></div>
                                <div class="step-item">3. 播放配置输入流地址</div>
                                <div class="step-item">4. 开始播放</div>
                            </div>
                        </div> -->
                        <!-- 播放配置-->
                        <div class="common-step play-setting">
                            <div class="sec-title">播放配置</div>
                            <div id="oneInput" class="mgt20 mgl10">
                                <label style="display: none;">流地址:</label>
                                <input type="text" style="display: none;" class="stream-input" id="oneStartUrl" placeholder="请输入流地址" value="http://192.168.1.103:80/hls/test.m3u8">
                                <button class="common-btn" id="oneStartVideo">播放</button>
                                <button class="common-btn" style="display: none;" id="downloadVideo">录像下载</button><br><br>
                            </div>
                        </div>
                        <!-- 播放器 -->
                        <div>
                            <video class="video-box" id="myVideo" controls preload="auto" autoplay="autoplay"></video>
                        </div>
                       <!--  <div><strong>补充说明</strong>: hls H265视频编码播放仅Chrome104及以上版本支持</div> -->
                    </div>
                   
                </div>
            </div>
        </div>
		 	
		
		
	</body>
	
	
	    <script src="${pageContext.request.contextPath }/statics/common/player/dhflv.min.js"></script>
        <script src="${pageContext.request.contextPath }/statics/common/player/dhhls.min.js"></script>
        <script type="text/javascript">
        
           //异步请求处理,开始进行视频流输出
			        $.ajax({
						async:true,   
						type:"post",
						url:"${pageContext.request.contextPath }/rh/setHls1",
						dataType:"json",
						success:function(data){
							
							 console.log("nginx 输出视频流的绝对路径路径"+data.saveUrl);
				        	
						},
						error:function(){
							//layer.msg('出现异常');
						}
					});
        
        
        
        
                //菜单切换
                $('#mainTabs a').click(function (e) {
                    $(this).tab('show');
                    $(this).siblings().removeClass('active');
                    $(this).parent().siblings().removeClass('active-item active');
                    $(this).parent().addClass('active-item');
                })
                /**
                 * 第一部分
                 * HLS实时播放
                **/
                //检测浏览器是否支持HLS 播放器
                if (!Hls.isSupported()) {alert("浏览器不支持 HLS, 请升级!");}
                //视频流帧数据、用于下载
                let fmp4Data = {
                    audio: [],
                    video: [],
                };
                let url = "";
                let hlsplayer = null;
                $('#oneStartVideo').click(function(e) {
                    url = $('#oneStartUrl').val();
                    if(!url) {
                        alert("请输入流地址!");
                        return
                    }
                    //初始化录像配置
                    $('#downloadVideo')[0].innerText = "录像下载";
                    fmp4Data = {
                        audio: [],
                        video: [],
                    };
                    //开始播放
                    playHls('myVideo',url)
                })
				
				
				$(document).ready(function(e){
				     url = $('#oneStartUrl').val();
					
					//url ="http://127.0.0.1:80/hls/test.m3u8";
                    if(!url) {
                        alert("请输入流地址!");
                        return
                    }
                    //初始化录像配置
                    $('#downloadVideo')[0].innerText = "录像下载";
                    fmp4Data = {
                        audio: [],
                        video: [],
                    };
                    //开始播放
                   playHls('myVideo',url)
				  
				})
				
				
			//定时重新播放视频
			function refreshPageAfter() {
                	
                	//console.log("设定时间符合当前时间")
				  
				  url = $('#oneStartUrl').val();
					
					//url ="http://127.0.0.1:80/hls/test.m3u8";
                    if(!url) {
                        alert("请输入流地址!");
                        return
                    }
                    //初始化录像配置
                    $('#downloadVideo')[0].innerText = "录像下载";
                    fmp4Data = {
                        audio: [],
                        video: [],
                    };
                    //开始播放
                   playHls('myVideo',url)
				  
			 }

			//启动定时器
			//self.setInterval("refreshPageAfter()", 61 * 60 *1000);
		 
				
			
			//莫一时间定时器
			
		
		 
		function scheduleRefresh() {
		    var now = new Date();
		    var targetTime = new Date();
		    // 设置目标时间为今天的12点15分
		    targetTime.setHours(17, 36, 0, 0);
		    
		    // 如果当前时间已经超过12点15分,则将目标时间设置为明天的12点15分
		    if (now >= targetTime) {
		        targetTime.setDate(targetTime.getDate() + 1);
		    }
		    
		    // 计算从现在到目标时间的毫秒数
		    var delay = targetTime - now;
		    console.log("设定时间符合当前时间"+delay)
		    
		    // 设置延时,直到目标时间到达
		    setTimeout(refreshPageAfter, delay);
		    
		    console.log("设定时间符合当前时间")
		}
		 
		//初始化调用== 调用函数以设置定时刷新
		scheduleRefresh();
			
			
			
			
			
			
			
				
				
                //创建hls播放器
                function playHls(id, url) {
                    //先触发销毁
                    if(hlsplayer != null) {
                        hlsplayer.destroy();
                    }
                    //创建播放
                    let video = document.getElementById(id);
                    if(Hls.isSupported()) {
                        hlsplayer = new Hls();
                        hlsplayer.loadSource(url);
                        hlsplayer.attachMedia(video);
                        hlsplayer.on(Hls.Events.MANIFEST_PARSED, function() {
                            hlsplayer.play(); 
                        });
                    } else if(video.canPlayType('application/vnd.apple.mpegurl')) {
                        console.log("apple原生");
                        // 如果支持原生播放
                        video.src = url;
						video.play();
                    }
                   
                }
                //hls录像下载
                $('#downloadVideo').click(function(e) {
                    if(!hlsplayer) {
                        alert("请先触发播放");
                        return
                    }
                    let text = e.target.innerText;
                    if(text === "录像下载") {
                        $('#downloadVideo')[0].innerText = "录像中";
                        playHls('myVideo',url);
                        hlsplayer.on(Hls.Events.BUFFER_APPENDING, function (eventName, data) {
                            //录像数据缓存
                            fmp4Data[data.type].push(data.data);
                            console.log(fmp4Data)
                        });
                    } else {
                        $('#downloadVideo')[0].innerText = "录像下载";
                        //结束并下载录像
                        let type = "video";
                        if (fmp4Data[type].length) {
                            const blob = new Blob([arrayConcat(fmp4Data[type])], {
                                type: 'application/octet-stream',
                            });
                            const filename = type + '-' + new Date().toISOString() + '.mp4';
                            let aDom = document.createElement('a')
                            aDom.setAttribute("download",`hlsjs-` + filename);
                            aDom.setAttribute("href", self.URL.createObjectURL(blob));
                            aDom.style.display = 'none';
                            document.body.appendChild(aDom)
                            aDom.click()
                            document.body.removeChild(aDom);
                        }
                        //重置录像数据
                        fmp4Data = {
                            audio: [],
                            video: [],
                        };
                    }
                })
                //组合视频数据
                function arrayConcat(inputArray) {
                    const totalLength = inputArray.reduce(function (prev, cur) {
                        return prev + cur.length;
                    }, 0);
                    const result = new Uint8Array(totalLength);
                    let offset = 0;
                    inputArray.forEach(function (element) {
                        result.set(element, offset);
                        offset += element.length;
                    });
                    return result;
                } 
                /**
                 * 第二部分
                 * FLV实时播放
                **/
                //检测浏览器是否支持flv 播放器
                if ( !dhflvjs.isSupported() )
                {
                    alert("浏览器不支持 FLV, 请升级!");
                }
                let flvUrl = "";
                let flvPlayer = null;
                $('#oneStartVideoFlv').click(function(e) {
                    flvUrl = $('#oneStartUrlFlv').val();
                    if(!flvUrl) {
                        alert("请输入流地址!");
                        return
                    }
                    //开始播放
                    playflv('myVideoflV',flvUrl)
                })
                //创建flv播放器
                function playflv(id, url) {
                    if (typeof flvPlayer !== "undefined") {
                        if (flvPlayer != null) {
                            flvPlayer.unload();
                            flvPlayer.detachMediaElement();
                            flvPlayer.destroy();
                            flvPlayer = null;
                        }
                    }
                    const video = document.getElementById(id);
                    flvPlayer = dhflvjs.createPlayer({
                        type: 'flv',
                        url : flvUrl,
                    });
                    flvPlayer.attachMediaElement(video);
                    flvPlayer.load();
                    flvPlayer.play();
                }
                //录像下载
                $('#downloadVideoFlv').click(function(e) {
                    if(!flvPlayer) {
                        alert("请先触发播放");
                        return
                    }
                    let text = e.target.innerText;
                    if(text === "录像下载") {
                        $('#downloadVideoFlv')[0].innerText = "录像中";
                        //开始录像
                        downloadFLV(1);
                    } else {
                        $('#downloadVideoFlv')[0].innerText = "录像下载";
                        //结束录像
                        downloadFLV(0);
                    }
                })
                //下载录像
                function downloadFLV(startFlag) {
                    if( startFlag ) {
                        flvPlayer && flvPlayer.startRecord()
                    } else {
                        flvPlayer && flvPlayer.endRecord()
                    }
                }

        </script>
	
	
 <script type="text/javascript" src="${pageContext.request.contextPath }/statics/jquery-2.1.0.min.js"></script>
<%-- <script type="text/javascript" src="${pageContext.request.contextPath }/statics/js/sebeiqiehuan.js"></script> --%>
 
<script type="text/javascript" src="${pageContext.request.contextPath }/statics/video.min.js"></script>

 
 
</html>

步骤四:所需物料库

链接下载:SSM架构 +Nginx+FFmpeg实现rtsp流转hls流---物料包

地址为:https://download.csdn.net/download/qq_39951524/90465236

相关推荐
小码哥_常2 分钟前
Android新航标:Navigation 3为何成为变革先锋?
前端
SuperEugene2 分钟前
Vue状态管理扫盲篇:状态管理中的常见坑 | 循环依赖、状态污染与调试技巧
前端·vue.js·面试
骑着小黑马3 分钟前
从 Electron 到 Tauri 2:我用 3.5MB 做了个音乐播放器
前端·vue.js·typescript
aykon4 分钟前
DataSource详解以及优势
前端
Mintopia4 分钟前
戴了 30 天智能手环后,我才发现自己一直低估了“睡眠”
前端
leolee184 分钟前
react redux 简单使用
前端·react.js·redux
仰望星空的小猴子5 分钟前
常用的Hooks
前端
天才熊猫君5 分钟前
Vue Fragment 锚点机制
前端
米丘6 分钟前
Git 常用操作命令
前端
星_离9 分钟前
SSE—实时信息推送
前端