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

相关推荐
夏天的味道٥3 小时前
使用 Java 执行 SQL 语句和存储过程
java·开发语言·sql
Fantasywt3 小时前
THREEJS 片元着色器实现更自然的呼吸灯效果
前端·javascript·着色器
IT、木易4 小时前
大白话JavaScript实现一个函数,将字符串中的每个单词首字母大写。
开发语言·前端·javascript·ecmascript
冰糖码奇朵4 小时前
大数据表高效导入导出解决方案,mysql数据库LOAD DATA命令和INTO OUTFILE命令详解
java·数据库·sql·mysql
好教员好4 小时前
【Spring】整合【SpringMVC】
java·spring
浪九天5 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
堕落年代6 小时前
Maven匹配机制和仓库库设置
java·maven
功德+n6 小时前
Maven 使用指南:基础 + 进阶 + 高级用法
java·开发语言·maven
张拭心6 小时前
2024 总结,我的停滞与觉醒
android·前端
念九_ysl6 小时前
深入解析Vue3单文件组件:原理、场景与实战
前端·javascript·vue.js