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

news2025/2/23 3:42:53

学习链接

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代码,这2个能正常处理mp4和avi格式的视频)

效果图

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: 500MB
      max-request-size: 500MB

WebConfig

@Configuration
public class WebConfig implements WebMvcConfigurer {


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/test/**").addResourceLocations("file:" + System.getProperty("user.dir") + "/test/");
        registry.addResourceHandler("/tmp/**").addResourceLocations("file:" + System.getProperty("user.dir") + "/tmp/");
    }

    @Override
    public 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 {
            // 生成IV
            ProcessBuilder 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>
        // 另一种方式,使用 customType
        const 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文件
在这里插入图片描述
播放效果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MVTEC数据集笔记

前言 网上的博客只有从论文里摘出的介绍&#xff0c;没有数据集文件详细的样子&#xff0c;下载数据集之后&#xff0c;对数据集具体的构成做一个补充的笔记。 下载链接&#xff1a;https://ai-studio-online.bj.bcebos.com/v1/7d4a3cf558254bbaaf4778ea336cb14ed8bbb96a7f2a…

[数据结构]红黑树,详细图解插入

目录 一、红黑树的概念 二、红黑树的性质 三、红黑树节点的定义 四、红黑树的插入&#xff08;步骤&#xff09; 1.为什么新插入的节点必须给红色&#xff1f; 2、插入红色节点后&#xff0c;判定红黑树性质是否被破坏 五、插入出现连续红节点情况分析图解&#xff08;看…

国家地理信息公共服务平台的天地图

文章目录 一、国家地理信息公共服务平台的天地图二、地图转换1.GIS数据格式坐标转换&#xff08;地球坐标WGS84、GCJ-02、火星坐标、百度坐标BD-09、国家大地坐标系CGCS2000&#xff09;2.读入数据 总结 一、国家地理信息公共服务平台的天地图 三大地图付费后&#xff0c;仍可…

JavaScript中字符串的常用方法

JavaScript中字符串的常用方法 1.查询类2.拼接3.截取4.大小写5.去掉空格6.重复7.填充8.分隔9.模版匹配方法 可以通过查看String对象的原型来看有哪些方法: console.dir(String.prototype)1.查询类 charAt(index):返回指定位字符 console.log("abc".charAt(1));//b…

基于fastadmin快速搭建导航站和API接口站点系统源码

源码介绍 基于fastadmin快速搭建导航站和API接口站点系统源码 上传源码 设置运行目录为/public 导入 数据库.sql到数据库 设置配置文件application/database.php 后台admin.php 可以自己随意修改本文件名称为后台地址 推荐越复杂越好 账号admin 密码 123456 效果预览

【Vue3】Vue 3 中列表排序的优化技巧

本文将深入探讨 Vue 3 中列表排序的优化技巧&#xff0c;帮助提升应用的性能和响应速度。 1. 避免不必要的排序 按需排序 在实际应用中&#xff0c;并非每次数据更新都需要进行排序。例如&#xff0c;当列表数据仅在特定条件下需要排序时&#xff0c;可通过条件判断来避免不…

使用html css js 来实现一个服装行业的企业站源码-静态网站模板

最近在练习 前端基础&#xff0c;html css 和js 为了加强 代码的 熟悉程序&#xff0c;就使用 前端 写了一个个服装行业的企业站。把使用的技术 和 页面效果分享给大家。 应用场景 该制衣服装工厂官网前端静态网站模板主要用于前端练习和编程练习&#xff0c;适合初学者进行 HT…

数控机床设备分布式健康监测与智能维护系统MTAgent

数控机床设备分布式健康监测与智能维护系统MTAgent-v1.1融合了目前各种先进的信号处理以及信息分析算法以算法工具箱的方式&#xff0c;采用了一种开发的、模块化的结构实现信号各种分析处理&#xff0c;采用Python编程语言&#xff0c;满足不同平台需求(包括Windows、Linux)。…

Java+SpringBoot+数据可视化的家庭记账小程序(程序+论文+安装+调试+售后等)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统介绍 在当下这个科技日新月异、经济蓬勃向上的时代&#xff0c;中国经济正以令人瞩目的速度迅…

前端JS接口加密攻防实操

前端JS接口加密攻防实操 背景 在爬虫过程中&#xff0c;对数据接口各类加密的经历总结&#xff0c;无头消耗资源效率不高&#xff0c;采用浏览器兜底解密协程并行 青铜版(混淆对称加密|签名nonce等&#xff09; 解&#xff1a;根据API 调用栈&#xff0c;断点找到request参…

百度搜索融合 DeepSeek 满血版,开启智能搜索新篇

百度搜索融合 DeepSeek 满血版&#xff0c;开启智能搜索新篇 &#x1f680; &#x1f539; 一、百度搜索全量接入 DeepSeek &#x1f539; 百度搜索迎来重要升级&#xff0c;DeepSeek 满血版全面上线&#xff01;&#x1f389; 用户在百度 APP 搜索后&#xff0c;点击「AI」即…

游戏引擎学习第103天

仓库:https://gitee.com/mrxiao_com/2d_game_2 回顾bug 接下来回顾一下这个bug的具体情况。当前是一个调试视图&#xff0c;我们并不是直接在调试视图下工作&#xff0c;而是在进行相关的调试。展示了地图&#xff0c;这里是环境贴图&#xff0c;上面是正在使用的环境贴图&am…

WPF快速创建DeepSeek本地自己的客户端-基础思路版本

开发工具&#xff1a;VS 2015 开发环境&#xff1a;.Net 4.0 使用技术&#xff1a;WPF 本篇文章内容&#xff1a; 本地部署DeepSeek以后一般使用网页工具&#xff08;如Chatbox&#xff09;或者DOS窗口与其对话。本篇文章使用WPF创建一个基础版的对话工具。 一、搭建本地DeepS…

spring cloud gateway限流常见算法

目录 一、网关限流 1、限流的作用 1. 保护后端服务 2. 保证服务质量 (QoS) 3. 避免滥用和恶意攻击 4. 减少资源浪费 5. 提高系统可扩展性和稳定性 6. 控制不同用户的访问频率 7. 提升用户体验 8. 避免API滥用和负载过高 9. 监控与分析 10. 避免系统崩溃 2、网关限…

网络安全的态势如何以及如何解决?

大家好,我是AI拉呱,一个专注于人工智领域与网络安全方面的博主,现任资深算法研究员一职,兼职硕士研究生导师;热爱机器学习和深度学习算法应用,深耕大语言模型微调、量化、私域部署。曾获多次获得AI竞赛大奖,拥有多项发明专利和学术论文。对于AI算法有自己独特见解和经验…

2026考研趋势深度解析:政策变化+高效工具指南

2026考研深度解析&#xff1a;趋势洞察高效工具指南&#xff0c;助你科学备战上岸 从政策变化到工具实战&#xff0c;这份千字攻略解决99%考生的核心焦虑 【热点引入&#xff1a;考研赛道进入“高难度模式”】 2025年全国硕士研究生报名人数突破520万&#xff0c;报录比预计扩…

AI工具篇:利用DeepSeek+Kimi 辅助生成综述汇报PPT

随着科研和学术报告需求的增加&#xff0c;如何高效地准备一份结构清晰、内容充实的PPT已成为许多研究者的挑战。 传统的PPT制作过程繁琐&#xff0c;需要大量文献收集、数据分析和设计工作&#xff0c;而AI工具能够帮助提升效率&#xff0c;减少重复劳动。 本文将介绍如何使用…

【Linux系统】—— 调试器 gdb/cgdb的使用

【Linux系统】—— 调试器 gdb/cgdb的使用 1 前置准备2 快速认识 gdb3 cgdb/gdb 的使用3.1 简单认识 cgdb3.2 打断点 / 删断点3.3 逐过程 / 逐语句3.4 查看变量3.5 快速跳转 4 cgdb/gdb 调试技巧4.1 watch4.2 「set var」确定问题原因4.3 条件断点 5 概念理解6 gdb/cgdb 指令一…

Wireshark 输出 数据包列表本身的值

在 Wireshark 中&#xff0c;如果你想输出数据包列表本身的值&#xff08;例如&#xff0c;将数据包的摘要信息、时间戳、源地址、目的地址等导出为文本格式&#xff09;&#xff0c;可以使用 导出为纯文本文件 的功能。以下是详细步骤&#xff1a; 步骤 1&#xff1a;打开 Wir…

docker部署单机版doris,完整无坑

文章目录 一、部署1、修改内核参数2、下载Docker 开发环境镜像3、下载安装包4、启动镜像5、配置fe6、配置be7、远程连接 二、运维命令参考资料 一、部署 1、修改内核参数 在启动doris的be时&#xff0c;需要将 Linux 操作系统的内核参数设置为2000000&#xff0c;这里是Doris…