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

javacv将mp4视频切分为m3u8视频并播放

学习链接

ffmpeg-demo 当前对应的 gitee代码

Spring boot视频播放(解决MP4大文件无法播放),整合ffmpeg,用m3u8切片播放。

springboot 通过javaCV 实现mp4转m3u8 上传oss

如何保护会员或付费视频?优酷是怎么做的? - HLS 流媒体加密

ffmpeg视频转切片m3u8并加密&videojs播放&hls.js播放&dplayer播放(弹幕效果)

video标签学习 & xgplayer视频播放器分段播放mp4

SpringBoot&FFmpeg实现上传视频到本地,使用M3U8切片转码后,下方使用hls.js播放(支持mp4&avi),SpringBoot + FFmpeg实现一个简单的M3U8切片转码系统

文章目录

  • 学习链接
  • 简介
  • 效果图
  • 代码
    • pom.xml
    • application.yml
    • WebConfig
    • TestController
    • FFmpegProcessor
    • App
  • nginx配置
  • player.html
  • 测试

简介

将上传的视频文件,使用javacv拆分成m3u8文件和ts文件,m3u8文件和ts文件通过nginx访问,而key文件则通过web服务来获取。使用dplayer播放视频。

也可以使用ffmpeg命令来做,可以参考上面链接。

(当前能把mp4这样处理,但是不能处理avi,处理avi会报错;处理avi的可以参考springboot-ffmpeg-m3u8-convertor - gitee代码,或者这个springboot-ffmpeg-demo - gitee代码)

效果图

m3u8文件和ts文件通过nginx访问,而key文件则通过web服务来获取
在这里插入图片描述
在这里插入图片描述

拿不到key文件是无法播放的
在这里插入图片描述

代码

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>ffmpeg-demo</artifactId><version>1.0-SNAPSHOT</version><properties><java.version>1.8</java.version><javacv.version>1.5.4</javacv.version><ffmpeg.version>4.3.1-1.5.4</ffmpeg.version></properties><dependencies><!--web 模块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><!--排除tomcat依赖 --><exclusion><artifactId>spring-boot-starter-tomcat</artifactId><groupId>org.springframework.boot</groupId></exclusion></exclusions></dependency><!--undertow容器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-undertow</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--      javacv 和 ffmpeg的依赖包      --><dependency><groupId>org.bytedeco</groupId><artifactId>javacv</artifactId><version>${javacv.version}</version><exclusions><exclusion><groupId>org.bytedeco</groupId><artifactId>*</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.bytedeco</groupId><artifactId>ffmpeg-platform</artifactId><version>${ffmpeg.version}</version></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.6.5</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>

application.yml

server:port: 8080
spring:servlet:multipart:max-file-size: 500MBmax-request-size: 500MB

WebConfig

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/test/**").addResourceLocations("file:" + System.getProperty("user.dir") + "/test/");registry.addResourceHandler("/tmp/**").addResourceLocations("file:" + System.getProperty("user.dir") + "/tmp/");}@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").maxAge(3600).allowCredentials(true).allowedOrigins("*").allowedMethods("*").allowedHeaders("*").exposedHeaders("token","Authorization");}
}

TestController

import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import com.zzhua.processor.FFmpegProcessor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;@RestController
public class TestController {/*** 目录路径,这个路径需要包含test.info文件,test.key文件和test.mp4文件*/private static final String PATH = "D:\\Projects\\practice\\ffmpeg-demo\\test\\";@RequestMapping("uploadToM3u8")public void uploadToM3u8() throws Exception {FileInputStream inputStream = new FileInputStream(PATH + "test.mp4");/* 这里原来的逻辑是1、m3u8Url是将生成的m3u8文件流写入的位置,可以填写接收该请求的接口路径2、infoUrl是获取keyinfo文件的路径,可以是接口路径3、上面2个都可以是本地路径*/// String m3u8Url = "http://localhost:8080/upload/test.m3u8";// String infoUrl = "http://localhost:8080/preview/test.keyinfo";String m3u8Url = "D:\\Projects\\practice\\ffmpeg-demo\\test\\test.m3u8";String infoUrl = "D:\\Projects\\practice\\ffmpeg-demo\\test\\test.keyinfo";String segmentPattern = "http://localhost:8080/upload/test-%d.ts";FFmpegProcessor.convertMediaToM3u8ByHttp(inputStream, m3u8Url, infoUrl, segmentPattern);}@RequestMapping("convertToM3u8")public void convertToM3u8(MultipartFile mfile) {FFmpegProcessor.convertMediaToM3u8(mfile);}@PostMapping("upload/{fileName}")public void upload(HttpServletRequest request, @PathVariable("fileName") String fileName) throws IOException {ServletInputStream inputStream = request.getInputStream();FileWriter writer = new FileWriter(PATH + fileName);writer.writeFromStream(inputStream);IoUtil.close(inputStream);}/*** 预览加密文件*/@PostMapping("preview/{fileName}")public void preview(@PathVariable("fileName") String fileName, HttpServletResponse response) throws IOException {FileReader fileReader = new FileReader(PATH + fileName);fileReader.writeToStream(response.getOutputStream());}/*** 预览加密文件*/@GetMapping("download/{fileName}")public void download(@PathVariable("fileName") String fileName, HttpServletResponse response) throws IOException {FileReader fileReader = new FileReader(PATH + fileName);fileReader.writeToStream(response.getOutputStream());}}

FFmpegProcessor

import org.bytedeco.ffmpeg.avcodec.AVPacket;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.ffmpeg.global.avutil;
import org.bytedeco.javacv.*;
import org.springframework.web.multipart.MultipartFile;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;public class FFmpegProcessor {/*** 这个方法的url地址都必须是一样的类型 同为post*/public static void convertMediaToM3u8ByHttp(InputStream inputStream, String m3u8Url, String infoUrl, String segmentPattern) throws IOException {avutil.av_log_set_level(avutil.AV_LOG_INFO);FFmpegLogCallback.set();FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputStream);grabber.start();FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(m3u8Url, grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());recorder.setFormat("hls");// 拆分时间片段长度recorder.setOption("hls_time", "60");recorder.setOption("hls_list_size", "0");recorder.setOption("hls_flags", "delete_segments");recorder.setOption("hls_delete_threshold", "1");recorder.setOption("hls_segment_type", "mpegts");/* 这里指定生成的ts文件保存位置,可以写接口路径, 该接口用于接收ts文件流*/// recorder.setOption("hls_segment_filename", "http://localhost:8080/upload/test-%d.ts");recorder.setOption("hls_segment_filename", segmentPattern);recorder.setOption("hls_key_info_file", infoUrl);// http属性recorder.setOption("method", "POST");recorder.setFrameRate(25);recorder.setGopSize(2 * 25);recorder.setVideoQuality(1.0);recorder.setVideoBitrate(10 * 1024);recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);/*// 只保存图像,而不保存声音recorder.start();Frame frame;while ((frame = grabber.grabImage()) != null) {try {recorder.record(frame);} catch (FrameRecorder.Exception e) {e.printStackTrace();}}recorder.setTimestamp(grabber.getTimestamp());recorder.close();grabber.close();*//* 图像 + 声音 */recorder.start(grabber.getFormatContext());AVPacket packet;while ((packet = grabber.grabPacket()) != null) {try {recorder.recordPacket(packet);} catch (FrameRecorder.Exception e) {e.printStackTrace();}}recorder.setTimestamp(grabber.getTimestamp());recorder.stop();recorder.release();grabber.stop();grabber.release();}private static final String BASE_PATH = System.getProperty("user.dir") + "\\tmp\\";public static void convertMediaToM3u8(MultipartFile mfile) {String origFileName = mfile.getOriginalFilename();String fileName = origFileName.substring(0, origFileName.lastIndexOf("."));String dirName = fileName;String fileDir = BASE_PATH + fileName;File dirFile = new File(fileDir);if (!dirFile.exists()) {dirFile.mkdirs();}try {File rawFile = new File(dirFile, origFileName);// 保存文件mfile.transferTo(rawFile);// 生成密钥文件String commonFileName = fileDir + "\\" + fileName;generateKeyFile(commonFileName + ".key");// 生成keyInfo文件generateKeyInfoFile(dirName, commonFileName + ".key", commonFileName + ".keyinfo");convertMediaToM3u8ByHttp(new FileInputStream(rawFile),commonFileName + ".m3u8",commonFileName + ".keyinfo",commonFileName + "-%d.ts");} catch (Exception e) {e.printStackTrace(System.err);}}/*** 生成keyInfo文件** @param keyFilePath     密钥文件路径* @param keyInfoFilePath keyInfo文件路径*/private static void generateKeyInfoFile(String dirName, String keyFilePath, String keyInfoFilePath) {try {// 生成IVProcessBuilder ivProcessBuilder = new ProcessBuilder("openssl", "rand", "-hex", "16");Process ivProcess = ivProcessBuilder.start();BufferedReader ivReader = new BufferedReader(new InputStreamReader(ivProcess.getInputStream()));String iv = ivReader.readLine();// 写入keyInfo文件String keyInfoContent ="http://127.0.0.1:8080/tmp/" + dirName + "/" + new File(keyFilePath).getName() + "\n"+ keyFilePath + "\n"+ iv;Files.write(Paths.get(keyInfoFilePath), keyInfoContent.getBytes());System.out.println("keyInfo文件已生成: " + keyInfoFilePath);} catch (IOException e) {e.printStackTrace();}}/*** 生成密钥文件** @param keyFilePath 密钥文件路径*/private static void generateKeyFile(String keyFilePath) {try {ProcessBuilder processBuilder = new ProcessBuilder("openssl", "rand", "16");processBuilder.redirectOutput(new File(keyFilePath));Process process = processBuilder.start();process.waitFor();System.out.println("密钥文件已生成: " + keyFilePath);} catch (IOException | InterruptedException e) {e.printStackTrace();}}
}

App

@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);}}

nginx配置


#user  nobody;
worker_processes  1;#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;#pid        logs/nginx.pid;events {worker_connections  1024;
}http {include       mime.types;default_type  application/octet-stream;server {listen 80;server_name localhost;add_header 'Access-Control-Allow-Origin' $http_origin always;add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization, X-Requested-With, token';add_header 'Access-Control-Allow-Credentials' 'true';location / {if ($request_method = 'OPTIONS') {return 204;}root D:/Projects/practice/ffmpeg-demo/tmp;}}}

player.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>body {margin: 0;}.dplayer-container {width: 800px;height: 500px;display: flex;align-items: center;justify-content: center;}#dplayer {width: 100%;height: 100%;object-fit: cover;}</style><script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script><script src="https://cdn.jsdelivr.net/npm/dplayer@1.27.1/dist/DPlayer.min.js"></script>
</head><body><div class="dplayer-container"><div id="dplayer"></div></div><hr /><script>// 另一种方式,使用 customTypeconst dp = new DPlayer({container: document.getElementById('dplayer'),autoplay: false, // 自动播放video: {url: 'http://127.0.0.1/zzhua/zzhua.m3u8',type: 'customHls',customType: {customHls: function (video, player) {const hls = new Hls();hls.loadSource(video.src);hls.attachMedia(video);},},},});Window.dp = dp;</script>
</body></html>

测试

上传1个301M的视频,耗时15s,
在这里插入图片描述
共188个文件,其中184个ts文件
在这里插入图片描述
播放效果

在这里插入图片描述

相关文章:

javacv将mp4视频切分为m3u8视频并播放

学习链接 ffmpeg-demo 当前对应的 gitee代码 Spring boot视频播放(解决MP4大文件无法播放)&#xff0c;整合ffmpeg,用m3u8切片播放。 springboot 通过javaCV 实现mp4转m3u8 上传oss 如何保护会员或付费视频&#xff1f;优酷是怎么做的&#xff1f; - HLS 流媒体加密 ffmpe…...

docker 进阶命令(基于Ubuntu)

数据卷 Volume: 目录映射, 目录挂载 匿名绑定: 匿名绑定的 volume 在容器删除的时候, 数据卷也会被删除, 匿名绑定是不能做到持久化的, 地址一般是 /var/lib/docker/volumes/xxxxx/_data 绑定卷时修改宿主机的目录或文件, 容器内的数据也会同步修改, 反之亦然 # 查看所有 vo…...

鸿蒙(HarmonyOS)开发学习路线指南:从零到实战

随着鸿蒙生态的快速发展&#xff0c;HarmonyOS 已成为物联网时代的重要开发平台。其分布式架构和“一次开发、多端部署”的理念吸引了大量开发者。本文将从零开始梳理鸿蒙开发的学习路径&#xff0c;帮助开发者高效掌握核心技能。 一、学习路线概览 总目标&#xff1a;掌握鸿蒙…...

小白win10安装并配置yt-dlp

需要yt-dlp和ffmpeg 注意存放路径最好都是全英文 win10安装并配置yt-dlp 一、下载1.下载yt-dlp2. fffmpeg下载 二、配置环境三、cmd操作四、yt-dlp下视频操作 一、下载 1.下载yt-dlp yt-dlp地址 找到win的压缩包点下载&#xff0c;并解压 2. fffmpeg下载 ffmpeg官方下载 …...

CUBEAI详细使用教程(STM32运行神经网络)---以手写识别为例

系列文章目录 文章目录 系列文章目录前言一、CUBEMX配置步骤二、模型结构及模型存储方式三、常用API函数1.ai_(name)_create()2.ai_(name)_init3.ai_(name)_create_and_init()3.ai_(name)_run()官方提供的示例代码 四、如何获取官方开发文档五、手写识别案例 前言 实验效果&am…...

[NOIP 1998 提高组] 拼数

https://www.luogu.com.cn/problem/P1012 将每个数用字符串的形式读进来&#xff0c;对于任意两个数 x x x, y y y&#xff0c;如果 x y > y x xy>yx xy>yx&#xff0c;对最后的答案来说&#xff0c; x x x一定排在 y y y的前面。 简单证明&#xff1a;假设最后的…...

PHP Web 开发基础

PHP 学习资料 PHP 学习资料 PHP 学习资料 在 PHP Web 开发领域&#xff0c;掌握一些基础概念和技术是构建功能强大、用户体验良好的 Web 应用的基石。接下来&#xff0c;我们将深入探讨 HTTP 协议、表单处理、Cookie 和 Session 的管理、URL 处理等关键内容。 一、HTTP 协议…...

MME-CoT:专为评估大型多模态模型CoT推理能力的基准测试。涵盖了数学、科学、OCR、逻辑、时空和一般场景6个领域。

2025-02-09 &#xff0c;由CUHK MMLab、CUHK MulLab、字节跳动、、东北大学等机构联合发布MME-CoT数据集&#xff0c;该数据集目的评估大型多模态模型&#xff08;LMMs&#xff09;中的思维链&#xff08;CoT&#xff09;推理能力&#xff0c;涵盖数学、科学、OCR、逻辑、时空和…...

HDFS应用-后端存储cephfs-java-API

HDFS(Hadoop Distribute FileSystem)是一个适合运行在通用硬件之上,具备高度容错特性,支持高吞吐量数据访问的分布式文件系统,非常适合大规模数据集应用。 HDFS适用于如下场景: • 处理海量数据(TB或PB级别以上) • 需要很高的吞吐量 • 需要高可靠性 • 需要很好的可扩…...

A与B组件自动对齐与组装,无映射直接补偿。

网上针对组装的从视觉到控制动作,要不就是收费,要不就是简单介绍。这么详细的比较难找~ 手下留情,不喜勿喷! Show time~ 分步解决方案: 标定阶段(Calibration) 9点张氏标定(每个位置A1、A2、B1、B2): 使用机械手在相机视野内沿Z字形路径移动,覆盖9个点(XY方…...

SQL知识体系

SQL复习 MySQL SQL介绍 SQL SQL的全拼是什么&#xff1f; SQL全拼&#xff1a;Structured Query Language&#xff0c;也叫结构化查询语言。 SQL92和SQL99有什么区别呢&#xff1f; SQL92和SQL99分别代表了92年和99年颁布的SQL标准。 在 SQL92 中采用&#xff08;&#xff…...

编译安装php

前置准备 这里的可能不全&#xff0c;每个人安装的模块不一致&#xff0c;依赖也不不相同&#xff0c;按实际情况调整 yum install libxml2 -y yum install libxml2-devel -y yum install openssl-devel -y yum install sqlite-devel -y yum install libcurl-devel -yyum ins…...

【分果果——DP(困难)】

题目 分析 分果果题解参考&#xff0c;下面是补充https://blog.csdn.net/AC__dream/article/details/129431299 关于状态 设f[i][j][k]表示第i个人取到的最后一个糖果编号是j&#xff0c;第i-1个人取到的最后一个糖果编号小于等于k时的最大重量的最小值 关于转移方程 关于 j …...

利用ffplay播放udp组播视频流

ffplay -fs -fflags nobuffer -flags low_delay -analyzeduration 0 -probesize 32 -framedrop -sync ext -strict experimental udp://224.1.1.1:5001 -fs : 全屏显示 -fflags nobuffer &#xff1a; 禁用输入缓冲&#xff08;减少100-200ms缓冲延迟&#xff09; -an…...

C++中变量与容器的默认初始化:0的奥秘

在C编程的世界里&#xff0c;初始化是一个至关重要的概念。它决定了变量或容器在程序开始执行时的初始状态。然而&#xff0c;对于不同的数据类型和容器&#xff0c;C标准对于默认初始化的行为有着不同的规定。本文将深入探讨C中变量与容器的默认初始化规则&#xff0c;特别是关…...

VScode内接入deepseek包过程(本地部署版包会)

目录 1. 首先得有vscode软件 2. 在我们的电脑本地已经部署了ollama&#xff0c;我将以qwen作为实验例子 3. 在vscode上的扩展商店下载continue 4. 下载完成后&#xff0c;依次点击添加模型 5. 在这里可以添加&#xff0c;各种各样的模型&#xff0c;选择我们的ollama 6. 选…...

spark

阶段性 阶段一&#xff1a; 单机时代 阶段二: 大数据时代-分布式处理 阶段三: 实时大数据时代 hadoop慢因为她的计算结果保存在磁盘 处理在spark中可解决属于内存 Hadoop特点&#xff1a; 高可靠性 高拓展性 高效性 高容错性...

蓝桥杯---排序数组(leetcode第912题)

文章目录 1.题目重述2.思路分析3.代码解释 1.题目重述 题目的要求是不使用库函数或者是其他的内置的函数&#xff08;就是已经实现好的函数&#xff09;&#xff0c;也就是这个排序的逻辑需要我们自己进行实现&#xff1b; 2.思路分析 其实这个例子也是很容易理解的&#xff…...

【Javascript Day18】

目录 标签事件绑定的属性参数 阻止默认行为 dialog的实现及组织冒泡&#xff08;捕获&#xff09;传递 基于冒泡的事件委托 键盘事件的事件源对象信息 JS的自动触发操作 标签事件绑定的属性参数 <!-- 标签上的事件绑定&#xff0c;事件源对象通过 关键字event传递 --…...

轻量级C通用库Klib解读 —— kalloc

前言 Klib是一个独立的轻量级c通用库&#xff0c;里面大多数组件除了C标准库外不包含外部库&#xff0c;想用对应组件直接拷贝对应文件即可使用。 该库致力于高效和较小的内存占用&#xff0c;其中部分组件&#xff08;如khash、kbtree、ksort、kvec&#xff09;&#xff0c;无…...

认识HTML的标签结构

一、HTML的基本概念 1.什么是HTML&#xff1f; ①HTML是描述网页的一种标记语言&#xff0c;也被称为超文本标记语言【并不是一种编程语言】 ②HTML包含了HTML标签和文本内容 ③HTML文档也称为web页面 2.HTML的标签 HTML的标签通常成对出现&#xff0c;HTML文档由标签和受…...

C语言 实现一个比较两个整型的函数 / qsort的使用 /qsort排序结构体

一、qsort的一般使用方法 int cmp_int(const void* e1, const void* e2) {return *(int*)e1 - *(int*)e2; } // //使用qsort对数组进行排序&#xff0c;升序 void test1() {int arr[] { 9,8,7,6,5,4,3,2,1,0 };int sz sizeof(arr) / sizeof(arr[0]);//bubble_sort(arr, sz);…...

Arcmap python环境安装sklearn

Arcmap自带的环境为Python2.7&#xff0c;默认安装目录为C:\Python27\ArcGIS10.7 直接安装sklearn会发生兼容性问题&#xff0c;且默认环境不包括pip&#xff0c;因此需要先安装pip 下载 get-pip.py 访问 https://bootstrap.pypa.io/pip/2.7/get-pip.py 并下载 get-pip.py。运…...

FastAdmin后端列表导入表格数据

后台添加数据的时候增加通过表格导入功能 如下图index.html页面增加导入和模板下载按钮代码如下 <div class"panel panel-default panel-intro">{:build_heading()}<div class"panel-body"><div id"myTabContent" class"ta…...

R语言用逻辑回归贝叶斯层次对本垒打数据与心脏移植数据后验预测检验模拟推断及先验影响分析|附数据代码...

全文链接&#xff1a;https://tecdat.cn/?p40152 在统计学领域中&#xff0c;层次建模是一种极为强大且实用的工具。它能够巧妙地处理复杂的数据结构&#xff0c;通过分层的方式对数据进行建模。在贝叶斯统计的框架内&#xff0c;层次建模优势尽显&#xff0c;其可以有效地融合…...

Python基于自然语言处理技术的新闻文本分类系统【附源码、文档说明】

博主介绍&#xff1a;✌Java老徐、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…...

mybatis存储过程返回list

在MyBatis中调用存储过程并返回列表&#xff08;List&#xff09;通常涉及以下几个步骤&#xff1a; 定义存储过程&#xff1a;首先&#xff0c;在数据库中定义存储过程&#xff0c;并确保它返回结果集。配置MyBatis映射文件&#xff1a;在MyBatis的映射文件中配置调用存储过程…...

Unity项目实战-订阅者发布者模式

实战订阅者发布者模式详解 下面实例是一个射击类游戏&#xff0c;玩家可以切换枪支&#xff0c;最初的设计如下 public class Player:MonoBehaviour {//......省略代码逻辑//我们以及配置好了Scroll的输入&#xff0c;并配置了Scroll的输入事件&#xff0c;当玩家滚动鼠标滚轮…...

长文档处理痛点:GPT-4 Turbo引文提取优化策略与替代方案讨论

引言 随着GPT-4 Turbo的发布&#xff0c;其支持的128K上下文窗口&#xff08;约300页文本&#xff09;被视为处理长文本的突破性升级。然而&#xff0c;实际应用中&#xff0c;用户发现模型在提取长文档中的引文时存在显著缺陷&#xff1a;文档前三分之一的引文数量远多于中间…...

Deepseek 万能提问公式:高效获取精准答案

### **Deepseek 万能提问公式&#xff1a;高效获取精准答案** 在使用 Deepseek 或其他 AI 工具时&#xff0c;提问的质量直接决定了答案的精准度和实用性。以下是一个万能的提问公式回答&#xff1a; --- ### **1. 明确背景&#xff08;Context&#xff09;** - **作用**…...

Ubuntu中离线安装Docker

Ubuntu中离线安装Docker 前言 本教程将详细介绍如何在 Ubuntu 22.04 系统上&#xff0c;通过 .deb 包离线安装 Docker CE、Docker CE CLI 和 Docker Compose。 适用于无法访问互联网的环境。 准备工作 下载 .deb 包 在可以访问互联网的机器上&#xff0c;下载 Docker CE、…...

Linux配置SSH公钥认证与Jenkins远程登录进行自动发布

问题描述&#xff1a;在使用jenkins进行自动化部署时&#xff0c;其中一步是使用jenkins向目标服务器推送文件时&#xff0c;需要先在jenkins的系统配置中进行配置&#xff08;事先安装好对应插件&#xff09;&#xff0c;配置远程服务器时&#xff0c;报错&#xff1a; 检查以…...

【故障处理】- 11g数据泵到19c导致的job不自动执行

【故障处理】- 11g数据泵到19c导致的job不自动执行 一、概述二、报错原因三、解决方法 一、概述 业务正常上线以后&#xff0c;客户反馈大量的job到时间了也不正常运行。 二、报错原因 该报错匹配bug 32249704&#xff0c;导致了迁移之后job的log_user从业务用户变成了sys。JOB…...

WPF8-常用控件

目录 写在前面&#xff1a;1. 按钮控件1.1. Button 按钮1.2. RepeatButton:长按按钮1.3. RadioButton:单选按钮 2. 数据显示控件2.1. TextBlock&#xff1a;只读文本控件2.2. Lable&#xff1a;标签 显示文本控件2.3. ListBox&#xff1a;显示可选择项的列表2.4. DataGrid&…...

电商小程序(源码+文档+部署+讲解)

引言 随着移动互联网的快速发展&#xff0c;电商小程序成为连接消费者与商家的重要桥梁。电商小程序通过数字化手段&#xff0c;为消费者提供了一个便捷、高效的购物平台&#xff0c;从而提升购物体验和满意度。 系统概述 电商小程序采用前后端分离的架构设计&#xff0c;服…...

关于C#的一些基础知识点汇总

1.C#结构体可以继承接口吗&#xff1f;会不会产生GC&#xff1f; 在 C# 中&#xff0c;结构体不能继承类&#xff0c;但可以实现接口。 代码&#xff1a; interface IMyInterface {void MyMethod(); }struct MyStruct : IMyInterface {public void MyMethod(){Console.Write…...

七、敏捷开发工具:持续集成与部署工具

一、敏捷开发工具——持续集成与部署工具 持续集成(CI)与持续部署(CD)是现代敏捷开发中不可或缺的关键实践。通过自动化构建、测试和部署流程,团队可以快速反馈、提高代码质量,并加速产品交付。为此,持续集成与部署工具应运而生,它们能够帮助开发团队在整个开发周期内…...

【工具类】 Hutool 中用于生成随机数的工具类

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

vue3和vue2的组件开发有什么区别

Vue3和Vue2在组件开发上存在不少差异&#xff0c;下面从多个方面详细介绍&#xff1a; 响应式原理 Vue2&#xff1a;用Object.defineProperty()方法来实现响应式。打个比方&#xff0c;它就像给对象的每个属性都安排了一个“小管家”&#xff0c;属性被访问或修改时&#xff0…...

防御保护选路练习

拓扑 配置 IP的基本配置 r2 [R2]int g0/0/0 [R2-GigabitEthernet0/0/0]ip add 12.0.0.2 255.255.255.0 [R2]int g0/0/2 [R2-GigabitEthernet0/0/2]ip add 210.1.1.254 255.255.255.0 [R2-GigabitEthernet0/0/2]int g0/0/1 [R2-GigabitEthernet0/0/1]ip add 200.1.1.254 255.…...

SQL Server 运算符优先级

在 SQL Server 中&#xff0c;运算符的优先级决定了在没有使用括号明确指定计算顺序时&#xff0c;运算符的执行顺序。 运算符优先级列表 括号 () 一元运算符 &#xff08;正号&#xff09;-&#xff08;负号&#xff09;~&#xff08;按位取反&#xff09; 乘法、除法和取模…...

【RK3588嵌入式图形编程】-SDL2-构建模块化UI

构建模块化UI 文章目录 构建模块化UI1、概述2、创建UI管理器3、嵌套组件4、继承5、多态子组件6、总结在本文中,将介绍如何使用C++和SDL创建一个灵活且可扩展的UI系统,重点关注组件层次结构和多态性。 1、概述 在前面的文章中,我们介绍了应用程序循环和事件循环,这为我们的…...

用STC-ISP写延时函数

若想写出自己可以定义时长的延时函数&#xff0c;需要重新生成一个1ms的延时函数并稍加修改。 STC-ISP生成的1ms的延时函数代码如下&#xff1a; void Delay1ms(void) //12.000MHz {unsigned char data i, j;i 2;j 239;do{while (--j);} while (--i); }将上述代码改为可自定…...

DeepSeek企业级部署实战指南:从服务器选型到Dify私有化落地

对于个人开发者或尝鲜者而言&#xff0c;本地想要部署 DeepSeek 有很多种方案&#xff0c;但是一旦涉及到企业级部署&#xff0c;则步骤将会繁琐很多。 比如我们的第一步就需要先根据实际业务场景评估出我们到底需要部署什么规格的模型&#xff0c;以及我们所要部署的模型&…...

使用 Docker 部署 Apache Spark 集群教程

简介 Apache Spark 是一个强大的统一分析引擎&#xff0c;用于大规模数据处理。本文将详细介绍如何使用 Docker 和 Docker Compose 快速部署一个包含一个 Master 节点和两个 Worker 节点的 Spark 集群。这种方法不仅简化了集群的搭建过程&#xff0c;还提供了资源隔离、易于扩…...

基于暗通道先验的图像去雾算法解析与实现

一、算法背景 何凯明团队于2009年提出的暗通道先验去雾算法《single image haze removal using dark channel prior》&#xff0c;通过统计发现&#xff1a;在无雾图像的局部区域中&#xff0c;至少存在一个颜色通道的像素值趋近于零。这一发现为图像去雾提供了重要的理论依据…...

深入内存调试:Valgrind工具的终极指南(转)

在软件开发的世界里&#xff0c;代码质量就是生命线&#xff0c;而内存管理又是这条生命线中最脆弱的一环。内存泄漏&#xff0c;哪怕只是微小的一处&#xff0c;日积月累&#xff0c;都可能对整个系统造成灾难性的打击&#xff0c;无论是大型企业级应用、实时性要求极高的嵌入…...

深入解析MediaPipe:强大的实时计算机视觉框架

深入解析MediaPipe&#xff1a;强大的实时计算机视觉框架 1. 引言 在计算机视觉应用的快速发展中&#xff0c;实时处理和低延迟成为了许多应用的关键需求。Google 开发的 MediaPipe 是一个强大的开源框架&#xff0c;它能够高效处理 手势识别、姿态估计、物体检测、语音处理 …...

DeepSeek 和 ChatGPT 在特定任务中的表现:逻辑推理与创意生成

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;Linux网络编程 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 ​ Linux网络编程笔记&#xff1a; https://blog.cs…...

大白话实战Sentinel

Sentinel是SpringCloudAlibaba提供的用来做服务保护的框架,而服务保护的常见手段就是限流和熔断降级。在大型分布式系统里面,由于微服务众多,所以服务之间的稳定性需要做特别关注,Sentinel的核心包就提供了从多个维度去保护服务稳定的策略,而且这些保护策略都可以连接上Se…...