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

序言:书接上文,我们继续
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
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

测试用大模型组词

已经把hanzi-writer的js的调用、hanzi-writer调用的数千个汉字的json文件&#xff0c;全都放在本地了。虽然用的办法还是比较笨的。我注意到 大模型也可以部署本地&#xff0c;虽然使用频率低的情况下不划算。 尝试直接通过html的javascript通过api key调用大语言模型&#x…

AI革命先锋:DeepSeek与蓝耘通义万相2.1的无缝融合引领行业智能化变革

云边有个稻草人-CSDN博客 目录 引言 一、什么是DeepSeek&#xff1f; 1.1 DeepSeek平台概述 1.2 DeepSeek的核心功能与技术 二、蓝耘通义万相2.1概述 2.1 蓝耘科技简介 2.2 蓝耘通义万相2.1的功能与优势 1. 全链条智能化解决方案 2. 强大的数据处理能力 3. 高效的模型…

Unity Shader 学习15:可交互式雪地流程

本质是 利用顶点变换实现的&#xff1a; 通过一个俯视整个场地的正交摄像机&#xff0c;根据绑定在移动物体身上的粒子系统&#xff0c;来获取物体移动过的位置&#xff0c;记录到一张RenderTexture上作为轨迹图&#xff0c;再通过这张图来对雪地做顶点变换。 1. 由于顶点变换需…

结合rpart包的决策树介绍

决策树与CART算法 决策树是一种基于树状结构的监督学习算法。它通过从根节点开始递归地对特征进行划分&#xff0c;构建出一棵树来进行决策。决策树的构建过程需要解决的重要问题有三个&#xff1a;如何选择自变量、如何选择分割点、确定停止划分的条件。解决这些问题是希望随…

DeepSolution:比o1推理模型还强的RAG方案

一、为什么需要 DeepSolution&#xff1f; 1.1 复杂工程设计的挑战 在现代工程领域&#xff0c;设计一个满足多重复杂约束的解决方案是至关重要的。举个例子&#xff0c;假设我们需要设计一个在年降雨量 3000 毫米、膨胀土条件和频繁地震活动区域的安全高效医院建设方案。这种…

SpringBoot - 用责任链模式实现业务编排

文章目录 前因责任链&#xff1a;像工作台一样组织代码CodeSEQ3.1 定义处理器规范3.2 实现具体处理器3.3 共享上下文3.4 组装责任链 适用场景优势 前因 2000多行的业务逻辑里&#xff0c;各种校验规则、促销计算、库存操作像意大利面条一样缠绕在一起。最要命的是这样的代码结…

从家用显卡到AI文生视频——Wan2.1本地部署教程与一键包分享

今天要聊一聊AI文生视频的最新进展。一直以来&#xff0c;AI生成视频对硬件的要求都让人望而却步&#xff0c;尤其是家用显卡&#xff0c;总是感觉“心有余而力不足”。 AI文生视频以前 基本需要的显存大概几十上百G 但最近&#xff0c;阿里开源的 Wan2.1 彻底改变了这一局面…

Facebook营销自动化—— Python脚本 + 代理IP实现内容高效分发

目录 1. 引言&#xff1a;内容分发与Facebook营销的现状与痛点 2. 环境搭建与前期准备 2.1 开发环境与工具选择 2.2 获取代理IP 2.3 Facebook账号与开发者平台配置 3. Facebook内容分发的基本流程与策略 3.1 内容规划与策略制定 3.2 内容分发方式选择 3.3 风控与风险防…

TypeError: JSON.stringify cannot serialize cyclic structures

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 &#x1f35a; 蓝桥云课签约作者、…

Manus邀请码申请与获取全攻略

大家好&#xff0c;我是吾鳴。 之前吾鳴给大家分享过一篇Manus的介绍文章——《全网疯抢邀请码的Manus到底是个啥&#xff1f;看完这篇你就懂了&#xff01;》&#xff0c;介绍了Manus是什么、与DeepSeek有些什么区别、生活中的应用场景以及工作中的应用场景。 今天吾鳴给大家分…

c++实现最大公因数和最小公倍数

最大公因数和最小公倍数的介绍 读这篇文章&#xff0c;请你先对最大公因数以及最小公倍数进行了解&#xff1a; 最大公因数&#xff08;英文名&#xff1a;gcd&#xff09; 定义&#xff1a;最大公因数&#xff0c;也称最大公约数&#xff0c;指两个或多个整数共有约数&…

Jetpack Compose — 入门实践

一、项目中使用 Jetpack Compose 从此节开始,为方便起见,如无特殊说明,Compose 均指代 Jetpack Compose。 开发工具: Android Studio 1.1 创建支持 Compose 新应用 新版 Android Studio 默认创建新项目即为 Compose 项目。 注意:在 Language 下拉菜单中,Kotlin 是唯一可…

PAM4信号技术

概述 PAM4(4-Level Pulse Amplitude Modulation)是一种四电平脉冲幅度调制技术,广泛应用于高速数据传输,特别是在100Gbps及以上的通信系统中。与传统的NRZ(Non-Return-to-Zero)相比,PAM4通过在每个符号周期内传输2个比特的信息,显著提升了数据传输效率。随着5G网络的发…

Visual Studio 2022新建c语言项目的详细步骤

步骤1&#xff1a;点击创建新项目 步骤2&#xff1a;到了项目模板 --> 选择“控制台应用” (在window终端运行代码。默认打印"Hello World") --> 点击 “下一步” 步骤3&#xff1a;到了配置新项目模块 --> 输入“项目名称” --> 更改“位置”路径&…

【UCB CS 61B SP24】 Lecture 25 26 - Minimum Spanning Trees 学习笔记

本文介绍了图论中的另一个经典问题&#xff1a;最小生成树&#xff08;MST&#xff09;&#xff0c;讲解并用 Java 实现了用于求解 MST 的两个经典算法 Prim 与 Kruskal。 1. 最小生成树介绍 最小生成树&#xff08;Minimum Spanning Tree&#xff0c;MST&#xff09;是图论中…

“此电脑”中删除WPS云盘方法(百度网盘通用)

&#x1f4e3;此方法适用于卸载WPS云盘后&#xff0c;WPS云盘图标依然在此电脑中显示的问题。 原理&#xff1a;通过注册来进行删除 步骤&#xff1a; WIN键R,打开运行窗口&#xff0c;输入regedit命令&#xff0c;来打开【注册表编辑器】&#xff1b; 从左侧&#xff0c;依…

鸿蒙跨平台框架ArkUI-X

01 引言 目前&#xff0c;移动端主流跨平台方案有Flutter、React Native、uni-app等等&#xff0c;还有刚推出不久的Compose-Multiplatform&#xff0c;真所谓是百花齐放。这些框架各有特点&#xff0c;技术实现各有差异&#xff0c;比如Flutter通过Dart编写的UI描述对接Flutte…

关于更新字段为空值——MybatisPlus框架

背景&#xff1a;我们在项目开发过程中&#xff0c;可能会经常遇到这样的问题&#xff0c;某个前端的字段&#xff0c;用户把原本有值的改为空值了&#xff0c;用户的意愿肯定是要去更新的&#xff0c;前端此时会把这个字段传"null"或空字符串&#xff0c;但我们后端…

CherryStudio调用DeepSeek API实现AI对话

目录 一、CherryStudio是什么&#xff1f;二、下载安装CherryStudio三、调用DeepSeek API&#xff08;以华为云为例&#xff09;1.新建服务模型2.获取API Key和API 地址3.添加模型检查连接 四、体验刚建立成功的deepseek五、总结 一、CherryStudio是什么&#xff1f; CherrySt…

夜莺监控 v8.0 新版通知规则 | 对接钉钉告警

对新版本通知规则还不太了解的用户可以阅读文章&#xff1a;《夜莺监控巨大革新&#xff1a;抽象出通知规则&#xff0c;增强告警通知的灵活性》。下面我们将以钉钉通知为例&#xff0c;介绍如何使用新版通知规则来对接钉钉通知。 上图是通知规则对接钉钉通知的示意逻辑图。 在…