当前位置: 首页 > news >正文

使用spring boot vue 上传mp4转码为dash并播放

1.前端实现

<template><div class="video-upload"><el-uploadclass="upload-demo"action="/api/upload":before-upload="beforeUpload":on-success="handleSuccess":on-error="handleError":show-file-list="false":data="uploadData":headers="headers"><i class="el-icon-upload"></i><div class="el-upload__text">将视频文件拖到此处,或<em>点击上传</em></div></el-upload><div class="video-preview"><video :src="videoUrl" id="video" ref="videoPlayer"  controls class="w-full"></video></div><div v-if="progress > 0" class="progress-container">转码进度:<el-progress :percentage="progress" :status="progressStatus"></el-progress><p>{{ progressMessage }}</p></div></div>
</template><script>
import axios from 'axios';
import * as dashjs from 'dashjs';
import '../../node_modules/dashjs/dist/modern/esm/dash.mss.min.js';export default {name: 'HelloWorld',data() {return {timerId: null,id: null,uploadData: {title: '',description: ''},headers: {},videoUrl: '',progress: 0,progressStatus: '',progressMessage: '',playerOptions: {autoplay: false,controls: true,sources: []}};},methods: {beforeUpload(file) {const isVideo = /\.(mp4|avi|mov|mkv|flv|wmv)$/i.test(file.name);if (!isVideo) {this.$message.error('只能上传视频文件!');return false;}// 初始化上传状态this.progress = 0;this.progressStatus = '';this.progressMessage = '准备上传...';return true;},async handleSuccess(response, file) {console.log("file",file);if (response.success) {this.progress = 100;this.progressStatus = 'success';this.progressMessage = '上传成功! 转码处理中...';// 开始轮询转码状态await this.pollTranscodingStatus(response.data.taskId);} else {this.handleError(response.message);}},handleError(err) {this.progressStatus = 'exception';this.progressMessage = `上传失败: ${err.message || err}`;console.error('上传错误:', err);},async pollTranscodingStatus(taskId) {try {const res = await axios.get(`/api/transcode/status/${taskId}`);if (res.data.data.status === 'COMPLETED') {this.progressMessage = '转码完成!';          this.id = res.data.data.fileName;this.playVideo(res.data.data.fileName)} else if (res.data.data.status === 'FAILED') {this.progressStatus = 'exception';this.progressMessage = `转码失败: ${res.data.data.message}`;} else {this.progressMessage = `转码进度: ${res.data.data.progress || 0}%`;this.timerId = setTimeout(() => this.pollTranscodingStatus(taskId), 1000);}} catch (err) {this.timerId = setTimeout(() => this.pollTranscodingStatus(taskId), 1000);console.error('获取转码状态失败:', err);}},async playVideo(fileName){const videoId = fileName.substring(0,fileName.lastIndexOf('.'));this.videoUrl = "http://localhost:3000/dashVideo/dash/"+videoId+"/manifest.mpd"const player = dashjs.MediaPlayer().create();player.initialize(document.querySelector('#video'), this.videoUrl, true);}}
};
</script><style scoped>
.video-upload {padding: 20px;
}
.upload-demo {margin-bottom: 20px;
}
.video-preview {margin-top: 20px;
}
.progress-container {margin-top: 20px;
}
</style>

2前端依赖

  "dependencies": {"core-js": "^3.8.3","axios": "^0.18.0","element-ui": "^2.15.14","dashjs": "^5.0.1","vue": "^2.5.2"},

3后端实现

3.1接收文件

    @PostMapping("/upload")public ResponseEntity<?> uploadVideo(@RequestParam("file") MultipartFile file) {try {// 生成唯一文件名String originalFilename = file.getOriginalFilename(); //客户端上传时的完整文件名String extension = originalFilename.substring(originalFilename.lastIndexOf('.'));String filename = UUID.randomUUID().toString() + extension;// 上传原始文件storageService.upload(file, filename);// 创建转码任务String taskId = UUID.randomUUID().toString();TranscodeTask task = new TranscodeTask();task.setOriginalFile(filename);task.setStatus("UPLOADED");transcodeTasks.put(taskId, task);// 异步开始转码transcodeService.transcodeToDash(filename, filename.substring(0, filename.lastIndexOf('.'))).thenAccept(result -> {task.setStatus(result.isSuccess() ? "COMPLETED" : "FAILED");task.setPlayUrl(result.getPlaylistUrl());task.setMessage(result.getMessage());});Map<String,String> taskIdMap = new HashMap<>();taskIdMap.put("taskId", taskId);return ResponseEntity.ok().body(new ApiResponse(true, "上传成功dfgdf", taskIdMap));} catch (Exception e) {return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(new ApiResponse(false, "上传失败: " + e.getMessage(), null));}}

3.2文件转码

@Service
public class VideoTranscodeService {@Value("${video.transcode.ffmpeg-path}")private String ffmpegPath;@Value("${video.transcode.hls-time}")private int hlsTime;@Value("${video.storage.local.path}")private String uploadLocation;@Autowiredprivate StorageService storageService;private Map<String, Double> transcodeprogress = new ConcurrentHashMap<>();// 将本地视频转码为DASH分片(多码率)@Async("asyncTranscodeExecutor")public CompletableFuture<TranscodeResult> transcodeToDash(String filename, String outputBasePath) throws Exception {String outputDir = "../dash/"+outputBasePath + "_dash";Path outputPath = Paths.get(outputDir);Files.createDirectories(outputPath);FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(uploadLocation+"/"+filename);grabber.start();int totalFrames = grabber.getLengthInFrames();System.out.println("totalFrames:"+totalFrames);String outputInitPattern = "init_$RepresentationID$.m4s";String playsegmentPath = "segment_$RepresentationID$_$Number$.m4s";String playmanifestPath = outputDir + "/manifest.mpd";List<String> commands = new ArrayList<>();commands.add(ffmpegPath);commands.add("-i");commands.add(uploadLocation+"/"+filename);commands.add("-map");commands.add("0:v");commands.add("-map");commands.add("0:a");commands.add("-c:v");commands.add("libx264");commands.add("-crf");commands.add("22");commands.add("-profile:v");commands.add("high");commands.add("-level");commands.add("4.2");commands.add("-keyint_min");commands.add("60");commands.add("-g");commands.add("60");commands.add("-sc_threshold");commands.add("0");commands.add("-b:v:0");commands.add("1000k");commands.add("-s:v:0");commands.add("1280x720");commands.add("-b:v:1");commands.add("5000k");commands.add("-s:v:1");commands.add("1920x1080");commands.add("-c:a");commands.add("aac");commands.add("-b:a");commands.add("128k");commands.add("-f");commands.add("dash");commands.add("-seg_duration");commands.add("4");commands.add("-init_seg_name");commands.add(outputInitPattern);commands.add("-media_seg_name");commands.add(playsegmentPath);commands.add(playmanifestPath);ProcessBuilder builder = new ProcessBuilder(commands);builder.redirectErrorStream(true);Process process = builder.start();// 读取输出流try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {String line;while ((line = reader.readLine()) != null) {
//                System.out.println(line); // 可以记录日志或解析进度if (line.contains("frame=")) {// 提取当前帧数int currentFrame = extractFrame(line);System.out.println("currentFrame:"+currentFrame);double progress1 = ((double) currentFrame/totalFrames) * 100;System.out.println("adasdasdasd:"+progress1);transcodeprogress.put(filename, progress1);}}}process.waitFor(); // 等待转码完成int exitCode = process.waitFor();if (exitCode != 0) {throw new RuntimeException("FFmpeg转码失败,退出码: " + exitCode);}return CompletableFuture.completedFuture(new TranscodeResult(true, "转码成功"));}//转码进度计算public double getProgress(String filename) {Double progress = transcodeprogress.get(filename);System.out.println("progress:"+progress);return progress;}private int extractFrame(String logLine) {// 正则匹配 frame= 后的数字(兼容空格和不同分隔符)Pattern pattern = Pattern.compile("frame=\\s*(\\d+)"); // 匹配示例:frame= 123 或 frame=456Matcher matcher = pattern.matcher(logLine);if (matcher.find()) {try {return Integer.parseInt(matcher.group(1)); // 提取捕获组中的数字} catch (NumberFormatException e) {throw new IllegalStateException("帧数解析失败:" + logLine);}}return 0; // 未匹配时返回默认值或抛异常}@Data@AllArgsConstructorpublic static class TranscodeResult {private boolean success;private String message;}
}

3.3转码进度查询

@GetMapping("/transcode/status/{taskId}")public ResponseEntity<?> getTranscodeStatus(@PathVariable String taskId) {TranscodeTask task = transcodeTasks.get(taskId);if (task == null) {return ResponseEntity.notFound().build();}double progres = transcodeService.getProgress(task.getOriginalFile());Map<String, Object> data = new HashMap<>();data.put("status", task.getStatus());data.put("fileName", task.getOriginalFile());data.put("message", task.getMessage());data.put("progress", progres);return ResponseEntity.ok().body(new ApiResponse(true, "查询成功", data));}

3.4视频播放

@RestController
@RequestMapping("/dashVideo")
public class DashController {@Value("${video.storage.local.path}")private String storagePath;@GetMapping("/dash/{videoId}/manifest.mpd")public ResponseEntity<Resource> getDashManifest(@PathVariable String videoId) {String pathStr = "../dash/" + videoId+"_dash/manifest.mpd";Path mpdPath = Paths.get(pathStr);Resource resource = new FileSystemResource(mpdPath);return ResponseEntity.ok().header("Content-Type", "application/dash+xml").body(resource);}@GetMapping("/dash/{videoId}/{segment}")public ResponseEntity<Resource> getSegment(@PathVariable String videoId,@PathVariable String segment) {Path segmentPath = Paths.get("../dash/"+videoId+"_dash/"+segment);Resource resource = new FileSystemResource(segmentPath);return ResponseEntity.ok().header("Content-Type", "video/mp4").body(resource);}}

3.5上传完成后未转码文件位置

在这里插入图片描述
3.6转码后文件位置
在这里插入图片描述
播放的是转码分片后的文件

相关文章:

使用spring boot vue 上传mp4转码为dash并播放

1.前端实现 <template><div class"video-upload"><el-uploadclass"upload-demo"action"/api/upload":before-upload"beforeUpload":on-success"handleSuccess":on-error"handleError":show-file-…...

C++智能指针概念理解的面试题

C智能指针概念理解的面试题 第一部分&#xff1a;基础概念 解释std::unique_ptr和std::shared_ptr在以下方面的区别&#xff1a; 所有权语义性能开销自定义删除器的存储方式是否支持数组类型 答案&#xff1a; 所有权语义&#xff1a; unique_ptr&#xff1a;独占所有权&#…...

52.[前端开发-JS实战框架应用]Day03-AJAX-插件开发-备课项目实战-Lodash

常用JavaScript库 1 认识前端工具库 前端工具类库 2 Lodash vs underscore underscore库 VS Lodash库 Lodash库 的安装 Lodash库字符串、数组 Lodash库对象、集合、函数 3 Day.js vs Mement Moment.js库 VS Day.js库 Day.js库安装 Day.js获取、设置、操作时间 Day.js解析、…...

【论文阅读】平滑量化:对大型语言模型进行准确高效的训练后量化

论文题目&#xff1a;SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models 论文地址&#xff1a;[2211.10438] SmoothQuant: Accurate and Efficient Post-Training Quantization for Large Language Models 代码地址&#xff1a;http…...

mysql游标分页详解:让分页又快又稳的终极方案

一、什么是游标分页&#xff1f; 游标分页是一种更高效的分页方式&#xff0c;它通过"记住当前位置"而不是"数页码"来实现分页。就像看书时夹书签一样&#xff0c;游标分页会记住你看到哪里了&#xff0c;下次直接从那里继续。 传统分页 vs 游标分页 传…...

图论---染色法(判断是否为二分图)

O(nm) 二分图&#xff1a;可以把所有的点划分到两边&#xff0c;使得边只在集合之间&#xff0c;集合内部没有边。 二分图当且仅当图中不含奇数环&#xff08;边数为奇数条&#xff09; #include <iostream> #include <vector> #include <cstring> using …...

算法 | 基于SSA-CNN-LSTM(麻雀算法优化卷积长短期记忆神经网络)的股票价格预测(附完整matlab代码,公式,原理,可用于毕业论文设计)

以下是一个基于SSA-CNN-LSTM(麻雀算法优化卷积长短期记忆神经网络)的股票价格预测MATLAB项目实例,包含完整代码和详细注释。代码分为数据预处理、模型构建、优化算法、训练预测四个部分。 🚜🚜🚜🚜🚜🚜🚜🚜🚜🚜🚜🚜🚜 1. 数据预处理 %% 数据加…...

在html中如何创建vue自定义组件(以自定义文件上传组件为例,vue2+elementUI)

1、先上代码&#xff1a;vueUpload.js var dom <div class"upload-file"><el-upload :action"uploadFileUrl" :before-upload"handleBeforeUpload" :file-list"fileList" :limit"limit":on-error"handleUpl…...

Asp.Net Core 基于(asp.net core 2.2) 创建asp .net core空项目

文章目录 ASP.NET Core 应用程序的标准入口点,用于配置和启动一个 Web 主机(WebHost)。`InProcess` 代码分析解决 HTTP Error 500.31 - Failed to load ASP.NET Core runtime 的完整方案**`launchSettings.json` 配置文件分析**ASP.NET Core 中的配置源详解ASP.NET Core 应用…...

AiFlutter 低代码平台介绍

产品概述 AiFlutter 低代码平台是一款基于拖拽组件和配置流程图的可视化开发工具&#xff0c;旨在简化移动应用开发过程。无需编写代码&#xff0c;用户即可通过拖拽组件快速搭建应用界面&#xff0c;并通过配置流程图设计页面逻辑。平台支持硬件通信功能&#xff0c;用户可直…...

Flutter Dart 集合类型List Set Map详解军 以及循环语句 forEaclh map where any every

List基础用法 var list1 ["西瓜", "苹果", "香蕉", true, 0];var list2 <String>["西瓜", "苹果", "香蕉"];List list3 ["西瓜", "苹果", "香蕉"];list3.add("草莓&…...

aws(学习笔记第三十九课) iot-msk-pipeline

文章目录 aws(学习笔记第三十九课) iot-msk-pipeline学习内容&#xff1a;1. 整体架构1.1 代码链接1.2 代码调整1.2 整体架构(概要)1.3 整体架构(详细) 2. 代码解析2.1 创建IotProducerDestination2.2 创建IotProducer2.3 创建MSK client的EC22.4 创建MSK cluster2.5 创建Main …...

2025上海车展:赛轮思AI携手行业领军企业展示xUI——混合式、智能体化的AI助理平台

用户将可首次全面体验集成多模态SLM (端侧大语言模型)的Cerence xUl&#xff0c;此次演示由长城汽车和TCL合作呈现 马萨诸塞州伯灵顿&#xff0c;2025年4月22日——Cerence Inc.&#xff08;NASDAQ: CRNC&#xff09;&#xff08;“赛轮思AI”&#xff09;&#xff0c;全球对话…...

聚合分销小程序系统开发方案:整合AI对话、网盘、淘客CPS/CPA、电影票团购与会员卡业务

一、系统架构设计 技术架构 分层设计&#xff1a;采用微服务架构&#xff0c;分为平台层&#xff08;分销管理、数据库、交易系统&#xff09;、管理体系层&#xff08;数据管理、权限控制&#xff09;和功能层&#xff08;AI对话、网盘、CPS/CPA拉新、电影票团购、会员卡&…...

设计模式-- 原型模式详解

原型模式&#xff08;prototype&#xff09; 原型模式&#xff1a;用一个已经创建的实例作为原型&#xff0c;通过复制该原型对象来创建一个和原型相同或相似的新对象&#xff0c;原型模式属于创造性模式&#xff0c;它同样提供了创建对象的最佳方式之一。&#xff08;效率很高…...

ARM服务器与X86服务器核心区别分析

ARM服务器与X86服务器核心区别分析 一、架构设计与指令集差异 指令集本质‌ ARM‌&#xff1a;基于RISC&#xff08;精简指令集&#xff09;&#xff0c;指令定长且简单&#xff0c;单周期执行效率高&#xff0c;硬件设计复杂度低&#xff0c;适合低功耗场景。 X86‌&#xf…...

嵌入式:ARM系列分类及主要应用场景

在嵌入式系统和移动计算领域&#xff0c;Arm Cortex 系列处理器凭借其多样化的架构和卓越的性能&#xff0c;成为了众多设备的核心 “大脑”。从高端智能手机到工业控制设备&#xff0c;从物联网终端到安全芯片&#xff0c;Cortex 系列处理器以不同的型号和特性&#xff0c;满足…...

Axure PR 9 中继器 标签

大家好&#xff0c;我是大明同学。 这期内容&#xff0c;我们来了解一下Axure中继器数据表标签交互设计。 预览地址&#xff1a;https://n05kfs.axshare.com 好的&#xff0c;这里就结束了。 我是大明同学。 下期见。...

Django【应用 01】django-plotly-dash安装及使用

django-plotly-dash 的使用文档&#xff1a;https://django-plotly-dash.readthedocs.io/en/stable/introduction.html 以下内容大部分保留原文档的内容&#xff0c;添加实际的步骤和必要的说明。 django-plotly-dash安装及使用 1.安装配置1.1 安装1.2 注册组件1.3 配置框架1.…...

【MFC】 VS2022打开低版本的MFC,双击.rc文件,DIalog加载失败,页面弹窗fatal error RC***:cannot open*****

打开以前的MFC示例报错&#xff0c;打开VS2019的实例以及更早VS版本的实例都一样,打不开&#xff0c;还报错&#xff1b; 错误 MSB8041 此项目需要 MFC 库。从 Visual Studio 安装程序(单个组件选项卡)为正在使用的任何工具集和体系结构安装它们。 GxCameraEvents_VS2015 C:\P…...

ClickHouse 中`MergeTree` 和 `ReplicatedMergeTree`表引擎区别

在 ClickHouse 中&#xff0c;MergeTree 和 ReplicatedMergeTree 都是用于存储和管理数据的表引擎&#xff0c;但它们的主要区别在于是否支持数据复制。下面详细解释两者的不同点及其适用场景。 MergeTree 定义&#xff1a; MergeTree 是 ClickHouse 中最基本的表引擎之一&a…...

PubMed PDF下载 cloudpmc-viewer-pow逆向

目标&#xff1a;https://pmc.ncbi.nlm.nih.gov/articles/ pdf的下载链接是直接存在的 但是第一次单击下载不会触发PDF下载&#xff0c;而是跳转到验证页面然后又跳回概览页面 再次点击下载按钮&#xff0c;PDF就能正常下载了。现在要分析下载PDF要验证什么&#xff0c;如cooki…...

C语言面试高频题——strcat、strncat、strcmp、strcpy 哪些函数会导致内存溢出?

1. 函数功能与内存溢出风险 (1) strcat 功能&#xff1a;将源字符串追加到目标字符串的末尾。 原型&#xff1a; char *strcat(char *dest, const char *src);内存溢出风险&#xff1a; strcat 不会检查目标缓冲区的大小&#xff0c;直接将源字符串追加到目标字符串后。如果目…...

Linux套接字+Sqlite实例:客户端-服务器应用程序教程

本文将详细介绍如何创建一个基于客户端-服务器架构的应用程序&#xff0c;实现用户注册、登录、单词查询以及历史记录查询。该应用通过TCP套接字进行客户端和服务器之间的通信&#xff0c;并通过SQLite数据库进行用户和查询记录的管理。教程会逐步解析客户端和服务器端的实现&a…...

用 Python 打造打篮球字符动画!控制台彩色炫酷输出,抖音搞怪视频灵感还原

一、引言&#xff1a;从抖音搞怪视频到 Python 字符动画的奇妙之旅 刷抖音时刷到一个神级操作 —— 博主用 01 数字矩阵还原了明星打篮球的经典画面&#xff0c;字符在控制台随动作节奏炫彩跳动&#xff0c;瞬间点燃了技术宅的 DNA&#xff01;作为 Python 图像处理爱好者&…...

入侵检测系统(IDS)与入侵防御系统(IPS):功能对比与部署实践

入侵检测系统&#xff08;IDS&#xff09;与入侵防御系统&#xff08;IPS&#xff09;&#xff1a;功能对比与部署实践 在网络安全防御体系中&#xff0c;入侵检测系统&#xff08;Intrusion Detection System, IDS&#xff09;与入侵防御系统&#xff08;Intrusion Preventio…...

力扣-hot100(找到字符串中的所有字母异位词)

438. 找到字符串中所有字母异位词 中等 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 示例 1: 输入: s "cbaebabacd", p "abc" 输出: [0,6] 解释: 起始索引等于 0…...

零信任架构:重塑网络安全的IT新范式

在信息技术&#xff08;IT&#xff09;的风云变幻中&#xff0c;网络安全领域正迎来一场深刻变革——零信任架构&#xff08;Zero Trust Architecture&#xff09;。2025年&#xff0c;随着远程办公的常态化、云服务的普及以及网络攻击的日益复杂化&#xff0c;传统的“城堡与护…...

大模型微调 - transformer架构

什么是Transformer Transformer 架构是由 Vaswani 等人在 2017 年提出的一种深度学习模型架构&#xff0c;首次发表于论文《Attention is All You Need》中 Transformer 的结构 Transformer 编码器&#xff08;Encoder&#xff09; 解码器&#xff08;Decoder&#xff09; …...

Python图形界面编程(二)

目录 六、控件属性和事件响应 1、基本的操控 2、示例 七、对话框 六、控件属性和事件响应 1、基本的操控 有的控件有对对应的函数&#xff0c;可以用来设置以及获取属性或者设置属性&#xff0c;或者以字典下标的形式来获取&#xff0c;设置对应的属性&#xff1a; 比如&…...

MongoDB 图片 URL 存储异常问题解决方案

项目场景&#xff1a; 在开发一个在线考试系统时&#xff0c;前端需要提交学生的答题截图到后端&#xff0c;后端使用 MinIO 存储图片并保存图片 URL 到 MongoDB 数据库。系统需要支持多次提交图片&#xff0c;并将所有图片 URL 以数组形式存储在 MongoDB 的 screenShot 字段中…...

run code执行ts配置

1、全局安装typescript npm install –g typescript 执行tsc –v&#xff0c;可输出版本号&#xff0c;代表安装成功 2、创建tsConfig文件 npx tsc –init 创建成功目录下会出现tsconfig.json文件 3、安装ts-node&#xff0c;支持执行运行ts文件 npm install –g ts-node 控制…...

Python 虚拟环境管理:venv 与 conda 的选择与配置

文章目录 前言一、虚拟环境的核心价值1.1 依赖冲突的典型场景1.2 隔离机制实现原理 二、venv 与 conda 的架构对比2.1 工具定位差异2.2 性能基准测试&#xff08;以创建环境 安装 numpy 为例&#xff09; 三、venv 的配置与最佳实践3.1 基础工作流3.2 多版本 Python 管理 四、…...

【前缀和计算和+哈希表查找次数】Leetcode 560. 和为 K 的子数组

题目要求 给定一个整数数组 nums 和一个整数 k&#xff0c;统计并返回该数组中和为 k 的子数组的个数。 子数组是数组中元素的连续非空序列。 示例 1 输入&#xff1a;nums [1, 1, 1], k 2 输出&#xff1a;2 示例 2 输入&#xff1a;nums [1, 2, 3], k 3 输出&#xf…...

[原创](现代Delphi 12指南):[macOS 64bit App开发]:如何使用CFStringRef类型字符串?

[作者] 常用网名: 猪头三 出生日期: 1981.XX.XX 企鹅交流: 643439947 个人网站: 80x86汇编小站 编程生涯: 2001年~至今[共24年] 职业生涯: 22年 开发语言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 开发工具: Visual Studio、Delphi、XCode、…...

89.WPF 中实现便捷的数字输入框:DecimalUpDown 控件的使用 WPF例子 C#例子.

在 WPF 开发中&#xff0c;经常会遇到需要用户输入数字的场景。为了提供更好的用户体验&#xff0c;我们可以使用一个功能强大的控件——DecimalUpDown&#xff0c;它来自第三方库 Extended WPF Toolkit。这个控件不仅支持用户通过键盘输入数字&#xff0c;还支持通过鼠标滚轮或…...

【时时三省】(C语言基础)循环程序举例

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 例题: 用公式4/π≈1-3/1+5/1-7/1+...求π的近似值,直到发现某一项的绝对值小于10的-6次方为止(该项不累加)。 解题思路: 这是求值的近似方法中的一种。求π值可以用不同的近似方法。如下面的表达式都可以…...

Linux常用中间件命令大全

1.nginx 执行命令之前需要先进入sbin目录查看nginx版本&#xff1a; ./nginx -v检查配置文件正确性&#xff1a; ./nginx -t启动nginx服务&#xff1a; ./nginx停止nginx服务&#xff1a; ./nginx -s stop启动完成后可以查看nginx进程&#xff1a; ps -ef|grep nginx可以通过绝…...

数图信息科技邀您共赴第二十五届中国零售业博览会

数图信息科技邀您共赴第二十五届中国零售业博览会 2025年5月8日至10日&#xff0c;数图信息科技将精彩亮相第二十五届中国零售业博览会&#xff08;CHINASHOP 2025&#xff09;&#xff0c;与行业伙伴共探零售数字化转型新机遇&#xff01; 数图展会新品抢先看 数图商品一…...

路由器的基础配置全解析:静态动态路由 + 华为 ENSP 命令大全

&#x1f680; 路由器的基础配置全解析&#xff1a;静态&动态路由 华为 ENSP 命令大全 &#x1f310; 路由器的基本概念&#x1f4cd; 静态路由配置&#x1f4e1; 动态路由协议&#xff1a;RIP、OSPF、BGP&#x1f5a5; 华为 ENSP 路由器命令大全&#x1f539; 路由器基本…...

「Java EE开发指南」如何使用MyEclipse的可视化JSF编辑器设计JSP?(一)

本教程介绍在MyEclipse中开发EJB 3无状态会话bean&#xff0c;由于JPA实体和EJB 3实体非常相似&#xff0c;因此本教程不涉及EJB 3实体Bean的开发。在本教程中&#xff0c;您将学习如何&#xff1a; Visual JSF Designer&#xff08;可视化JSF设计器&#xff09;的目标是使创建…...

【设计】接口幂等性设计

1. 幂等性定义 接口幂等性&#xff1a; 无论调用次数多少&#xff0c;对系统状态的影响与单次调用相同。 比如用户支付接口因网络延迟重复提交了三次。 导致原因&#xff1a; 用户不可靠&#xff08;手抖多点&#xff09;网络不可靠&#xff08;超时重传&#xff09;系统不可…...

深入理解机器学习:人工智能的核心驱动力

在当今数字化时代&#xff0c;机器学习作为人工智能领域的关键技术&#xff0c;正以前所未有的速度改变着我们的生活和工作方式。从智能语音助手到精准的医疗诊断&#xff0c;从个性化的推荐系统到自动驾驶汽车&#xff0c;机器学习的应用无处不在&#xff0c;其影响力深远而广…...

CI/CD自动化部署(持续集成和持续交付/部署)

持续集成&#xff1a;开发人员频繁地将代码集成到共享仓库&#xff0c;然后自动运行测试持续交付&#xff1a;自动准备好发布&#xff0c;但需要手动触发部署持续部署&#xff1a;完全自动化的&#xff0c;不需要人工干预 流程&#xff1a; 比如&#xff0c;当开发人员提交代…...

如何理解计算机网卡完成数据传输的串并转换

计算机网卡的串并转换(串行-并行转换)是网络通信中的一个关键硬件功能,主要涉及数据的传输形式转换。它的核心目的是解决计算机内部处理数据的方式(并行)与网络传输数据的方式(串行)之间的差异。以下是通俗易懂的解释: 1. 串行传输 vs. 并行传输 并行传输: 计算机内部…...

基于Axure的动态甘特图设计:实现任务增删改与时间拖拽交互

甘特图作为项目管理核心工具&#xff0c;其动态交互能力直接关系到团队协作效率。本文以Axure RP 9为载体&#xff0c;通过中继器&#xff08;Repeater&#xff09;与动态面板&#xff08;Dynamic Panel&#xff09;的深度结合&#xff0c;设计一款支持任务名称动态编辑、时间轴…...

XMOS空间音频——在任何设备上都能提供3D沉浸式空间音频且实现更安全地聆听

2025年3月&#xff0c;全球规模最大的嵌入式行业盛会——德国纽伦堡国际嵌入式展&#xff08;Embedded World 2025&#xff0c;EW 25&#xff09;圆满落幕。在这场汇聚全球 950 家展商、3 万余专业观众的科技盛宴中&#xff0c;XMOS 展位人头攒动&#xff0c;多款尖端产品和多…...

使用功能包组织C++节点的具体教程

在 ROS&#xff08;Robot Operating System&#xff09;中&#xff0c;使用功能包&#xff08;package&#xff09;来组织 C 节点是一种常见且有效的方式&#xff0c;它能让代码结构更清晰、便于管理和复用。 1. 环境准备 确保已经安装了 ROS&#xff0c;这里以 ROS 2 Humble…...

免费的车牌势识别系统

背景 就是想要一个车牌识别系统 直接上教程 需要首先安装python3 然后执行下面的命令 pip install hyperlpr3 lpr3 rest --port 9999 --host 0.0.0.0 --workers 1 访问地址地址 # 9999 与上述端口一致 http://你的ip:9999/api/v1/docs 测试效果 准备一张图片 lpr3 sa…...

微信小程序蓝牙连接打印机打印单据完整Demo【蓝牙小票打印】

文章目录 一、准备工作1. 硬件准备2. 开发环境 二、小程序配置1. 修改app.json 三、完整代码实现1. pages/index/index.wxml2. pages/index/index.wxss3. pages/index/index.js 四、ESC/POS指令说明五、测试流程六、常见问题解决七、进一步优化建议 下面我将提供一个完整的微信…...