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

发布于:2025-03-09 ⋅ 阅读:(41) ⋅ 点赞:(0)

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

步骤一:把rtsp流转化为hls流,用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层 如何调用


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流视频



<%@ 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
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到