2.2 Windows MSYS2编译FFmpeg 4.4.1

一、安装编译工具

# 更换pacman源
sed -i "s#mirror.msys2.org/#mirrors.ustc.edu.cn/msys2/#g" /etc/pacman.d/mirrorlist*
pacman -Sy# 安装依赖
pacman -S --needed base-devel mingw-w64-x86_64-toolchain
pacman -S mingw-w64-x86_64-nasm mingw-w64-x86_64-yasm
pacman -S git pkg-config

说明:

  • base-devel:提供编译和开发软件所需的基础工具集,包含 常用的工具如 make, patch, autoconf, automake, libtool, gettext, texinfo 等
  • mingw-w64-x86_64-toolchain :MinGW-w64 的完整工具链,用于在 Windows 上编译 64 位应用程序,包含 编译器(如 gcc, g++)、链接器、调试器(gdb)以及相关的开发库和头文件。
  • mingw-w64-x86_64-nasm:NASM(Netwide Assembler)是一个开源的 x86 和 x86-64 汇编器。
  • mingw-w64-x86_64-yasm:YASM 是一个模块化的汇编器,支持 x86 和 x86-64 架构,兼容 NASM 语法。
  • git:用于从 Git 仓库下载源码(如 git clone)。
  • pkg-config:用于检索已安装库的编译和链接信息。

二、通过pacman安装依赖

2.1 常见依赖库

查询包名 网址:packages.msys2.org/queue

分类库名称用途FFmpeg 配置选项pacman 安装命令
视频编码libx264H.264 视频编码(高效、广泛使用的视频编码标准)--enable-libx264pacman -S mingw-w64-x86_64-x264
libx265H.265/HEVC 视频编码(高压缩率,适用于 4K/8K 视频)--enable-libx265pacman -S mingw-w64-x86_64-x265
libvpxVP8/VP9 视频编码(WebM 格式,适用于网络视频)--enable-libvpxpacman -S mingw-w64-x86_64-libvpx
libtheoraTheora 视频编码(开源视频格式)--enable-libtheorapacman -S mingw-w64-x86_64-libtheora
libwebpWebP 图像和视频编码(高效图像压缩格式)--enable-libwebppacman -S mingw-w64-x86_64-libwebp
libaomAV1 视频编码(下一代开源视频编码,高效压缩)--enable-libaompacman -S mingw-w64-x86_64-libaom
libdav1dAV1 视频解码(高性能 AV1 解码器,适合播放)--enable-libdav1dpacman -S mingw-w64-x86_64-dav1d
libxvidMPEG-4 视频编码(老式但仍使用的视频编码标准)--enable-libxvidpacman -S mingw-w64-x86_64-xvidcore
音频编码libfdk-aacAAC 音频编码(高质量音频编码,支持 HE-AAC)--enable-libfdk-aacpacman -S mingw-w64-x86_64-fdk-aac
libmp3lameMP3 音频编码(广泛使用的音频格式)--enable-libmp3lamepacman -S mingw-w64-x86_64-lame
libopusOpus 音频编码(低延迟、高质量,适合网络传输)--enable-libopuspacman -S mingw-w64-x86_64-opus
libvorbisVorbis 音频编码(开源音频格式,常用于 Ogg 容器)--enable-libvorbispacman -S mingw-w64-x86_64-libvorbis
libspeexSpeex 音频编码(针对语音优化的压缩格式)--enable-libspeexpacman -S mingw-w64-x86_64-speex
libflacFLAC 音频编码(无损音频压缩格式)--enable-libflacpacman -S mingw-w64-x86_64-flac
其他常用功能libass字幕渲染(支持 ASS/SSA 字幕格式)--enable-libasspacman -S mingw-w64-x86_64-libass
zlib数据压缩(用于压缩和解压文件或流)--enable-zlibpacman -S mingw-w64-x86_64-zlib
freetype字体渲染(用于字幕和文本绘制)--enable-libfreetypepacman -S mingw-w64-x86_64-freetype
fontconfig字体管理(优化字体选择和配置)--enable-fontconfigpacman -S mingw-w64-x86_64-fontconfig
openal音频处理(支持 3D 音频和空间音效)--enable-openalpacman -S mingw-w64-x86_64-openal
libsdl2多媒体交互(用于 ffplay 的图形界面和音频输出)--enable-sdl2pacman -S mingw-w64-x86_64-libsdl2
openssl支持 HTTPS 和其他加密协议(如 RTMPS)--enable-opensslpacman -S mingw-w64-x86_64-openssl
librtmpRTMP 流媒体协议支持(用于直播推流/拉流)--enable-librtmppacman -S mingw-w64-x86_64-librtmp
libpngPNG 图像支持(用于图像处理和帧提取)--enable-libpngpacman -S mingw-w64-x86_64-libpng
libjpeg-turboJPEG 图像支持(加速 JPEG 编码/解码)--enable-libjpegpacman -S mingw-w64-x86_64-libjpeg-turbo

2.2 ffmpeg编译安装

最小化配置:x264、x265、fdk-aac 和 lame

安装依赖

pacman -S mingw-w64-x86_64-x264 mingw-w64-x86_64-x265 mingw-w64-x86_64-fdk-aac mingw-w64-x86_64-lame

ffmpeg 4.4.1 编译:

wget https://ffmpeg.org/releases/ffmpeg-4.4.1.tar.xz
tar xf ffmpeg-4.4.1.tar.xz && cd ffmpeg-4.4.1./configure \
--prefix=$(pwd)/../ffmpeg_build \
--disable-everything \
--disable-doc \
--enable-shared \
--enable-muxer=mp4,flv,mp3,wav \
--enable-demuxer=mp4,mov,mp3,aac \
--enable-encoder=libx264,libx265,libfdk_aac,libmp3lame \
--enable-decoder=aac,h264,hevc,mp3 \
--enable-protocol=file,http \
--enable-filter=aresample \
--enable-bsf=aac_adtstoasc \
--enable-gpl \
--enable-nonfree \
--enable-libx264 \
--enable-libx265 \
--enable-libfdk-aac \
--enable-libmp3lame \
--extra-cflags="-I$(pwd)/../3rdparty_mingw64/include" \
--extra-ldflags="-L$(pwd)/../3rdparty_mingw64/lib"# 可能报shr错误,修改完再编译。
make -j$(nproc) && make install

编译错误:“Error: operand type mismatch for shr” 是由于汇编代码中存在类型不匹配的错误,导致无法通过汇编阶段编译。
在这里插入图片描述

解决办法:修改libavcodec/x86/mathops.h代码

  • ci改为c
  • ic改为c
#define MULL MULL
static av_always_inline av_const int MULL(int a, int b, unsigned shift)
{int rt, dummy;__asm__ ("imull %3               \n\t""shrdl %4, %%edx, %%eax \n\t":"=a"(rt), "=d"(dummy)//:"a"(a), "rm"(b), "ci"((uint8_t)shift):"a"(a), "rm"(b), "c"((uint8_t)shift));return rt;
}
#define NEG_SSR32 NEG_SSR32
static inline  int32_t NEG_SSR32( int32_t a, int8_t s){__asm__ ("sarl %1, %0\n\t": "+r" (a)//: "ic" ((uint8_t)(-s)): "c" ((uint8_t)(-s)));return a;
}#define NEG_USR32 NEG_USR32
static inline uint32_t NEG_USR32(uint32_t a, int8_t s){__asm__ ("shrl %1, %0\n\t": "+r" (a)//: "ic" ((uint8_t)(-s)): "c" ((uint8_t)(-s)));return a;
}

参考:https://blog.csdn.net/qq_47733361/article/details/132901423

这是编译后的库文件:

./
├── bin  # dll动态库、x.lib动态库导入库
│   ├── avcodec-58.dll
│   ├── avcodec.lib
│   ├── ...
│   └── swscale.lib
├── include
│   ├── ....
│   └── libswscale
├── lib                    # .def库的函数导出文件,.dll.a 是动态库导入库
│   ├── avcodec-58.def
│   ├── libavcodec.dll.a
│   ├── .....
│   └── swscale-5.def
└── share└── ffmpeg

三、ffmpeg依赖库(手动编译安装)

库类型:依赖库为动态库+ffmpeg为动态库

3.1 编译依赖库

设置终端代理(仅当前会话有效):

export http_proxy="http://127.0.0.1:11819"
export https_proxy="http://127.0.0.1:11819"

(1)编译x264

# 下载源码
git clone https://code.videolan.org/videolan/x264.git# 配置
./configure \
--prefix=$(pwd)/../3rdparty_mingw64 \
--enable-shared \
--disable-cli# 编译安装
make -j$(nproc) && make install

(2)编译x265

注意: 不要使用pacman安装的cmake,因为无法生成指定构建系统文件。

# 如果已安装,则重命名cmake
mv /usr/bin/cmake /usr/bin/cmake_bak# 设置环境变量,系统安装的cmake路径是:D:\Program\Program Files\CMake\bin
export PATH="/d/Program/Program Files/CMake/bin:$PATH"
# 下载源码
git clone https://bitbucket.org/multicoreware/x265_git.git# 配置(只编译静态库,而且设定运行时库为静态库)
mkdir tmp && cd tmp# 不能使用cmake -G "MinGW Makefiles" 会卡死
cmake -G "MSYS Makefiles" \
-DCMAKE_INSTALL_PREFIX=$(pwd)/../../3rdparty_mingw64 \
-DENABLE_SHARED=ON \
-DENABLE_CLI=OFF \
../source# 编译安装
make -j$(nproc) && make install

(3)编译fdk-aac

# 下载源码
wget https://sourceforge.net/projects/opencore-amr/files/fdk-aac/fdk-aac-2.0.1.tar.gz
tar -xf fdk-aac-2.0.1.tar.gz && cd fdk-aac-2.0.1/# 生成configure脚本(可选)
./autogen.sh# 配置
./configure \
--prefix=$(pwd)/../3rdparty_mingw64 \
--enable-shared=yes \
--enable-static=no# 编译安装
make -j$(nproc) && make install

(4)编译lame

# 下载源码
wget https://sourceforge.net/projects/lame/files/lame/3.100/lame-3.100.tar.gz# 配置
./configure \
--prefix=$(pwd)/../3rdparty_mingw64 \
--enable-shared=yes \
--enable-static=no \
--disable-frontend# 编译安装
make -j$(nproc) && make install

编译问题:无法导出lame_init_old函数
在这里插入图片描述
解决办法:在include/libmp3lame.sym文件删除lame_init_old函数。

3.2 编译ffmpeg

# 下载源码
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg-4.4.1
cd ffmpeg-4.4.1
git checkout n4.4.1# 设置.pc文件搜索路径
export PKG_CONFIG_PATH=$(pwd)/../3rdparty_mingw64/lib/pkgconfig:$PKG_CONFIG_PATH# 配置
./configure \
--prefix=$(pwd)/../ffmpeg_build \
--disable-everything \
--disable-doc \
--enable-shared \
--enable-muxer=mp4,flv,mp3,wav \
--enable-demuxer=mp4,mov,mp3,aac \
--enable-encoder=libx264,libx265,libfdk_aac,libmp3lame \
--enable-decoder=aac,h264,hevc,mp3 \
--enable-protocol=file,http \
--enable-filter=aresample \
--enable-bsf=aac_adtstoasc \
--enable-gpl \
--enable-nonfree \
--enable-libx264 \
--enable-libx265 \
--enable-libfdk-aac \
--enable-libmp3lame \
--extra-cflags="-I$(pwd)/../3rdparty_mingw64/include" \
--extra-ldflags="-L$(pwd)/../3rdparty_mingw64/lib"# 编译安装
make -j$(nproc) && make install

四、vscode使用ffmpeg库

项目目录结构:

./
├── 3rd               # 第三方依赖库
│   └── ffmpeg_4.4.1 
│       ├── include   # 头文件
│       ├── lib       # 静态库库
│       └── share
├── build			  # 编译目录
├── CMakeLists.txt    # cmake配置文件
├── set_env.ps1       # msys2配置脚本(使我们能在powershell上使用msys2)
└── src               # 源码目录└── main.c

CMakeLists.txt文件内容:

cmake_minimum_required(VERSION 3.10)
project(ffmpeg_test VERSION 1.0)set(CXX_STANDARD 11)
set(CXX_STANDARD_REQUIRED True)# 设置可执行文件输出目录为 bin  
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/bin)# 配置FFmpeg(avcodec.lib时动态库的导入库)
set(FFMPEG_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/ffmpeg-4.4.1)
include_directories(${FFMPEG_DIR}/include)
set(FFMPEG_LIBS
${FFMPEG_DIR}/bin/avdevice.lib
${FFMPEG_DIR}/bin/avfilter.lib
${FFMPEG_DIR}/bin/avformat.lib
${FFMPEG_DIR}/bin/avcodec.lib
${FFMPEG_DIR}/bin/swscale.lib
${FFMPEG_DIR}/bin/swresample.lib
${FFMPEG_DIR}/bin/avutil.lib
)# 编译和链接依赖库
add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${PROJECT_NAME} PRIVATE ${FFMPEG_LIBS} )# 使用file(GLOB)获取所有DLL文件
file(GLOB FFMPEG_DLLS "${FFMPEG_DIR}/bin/*.dll")# 添加自定义命令,在构建后复制DLL文件到输出目录
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILDCOMMAND ${CMAKE_COMMAND} -E copy_if_different${FFMPEG_DLLS}"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
)

set_env.ps1脚本内容:

# =============================================================================
#                          MSYS2 配置参数(可修改)
# =============================================================================
# MSYS2安装路径
$MSYS2_DIR = "D:\Program\msys64"# 选择MSYS2子系统: MINGW64, MINGW32, MSYS, CLANG64
$MSYSTEM = "MINGW64"# 是否继承当前环境变量PATH (yes=继承, no=不继承)
$MSYS2_PATH_TYPE = "inherit"
# =============================================================================
#                          以下内容请勿修改
# =============================================================================
# 设置输出编码为 UTF-8
$OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8# 检查 MSYS2 目录是否存在
if (-not (Test-Path $MSYS2_DIR)) {Write-Error "Error: MSYS2 directory not found at $MSYS2_DIR"Write-Error "Please update MSYS2_DIR in this script to your MSYS2 installation path."exit 1
}# 设置基本环境变量
$env:MSYS = "winsymlinks:nativestrict"
$env:MSYS2_ARG_CONV_EXCL = "*"
$env:MSYSTEM = $MSYSTEM
$env:MSYS2_PATH_TYPE = $MSYS2_PATH_TYPE# 更新 PATH 环境变量
$env:Path = "$MSYS2_DIR\$MSYSTEM\bin;$MSYS2_DIR\usr\bin;$env:Path"Write-Host "MSYS2 $MSYSTEM environment loaded successfully."
Write-Host ""# 验证环境
$bashPath = "$MSYS2_DIR\usr\bin\bash.exe"
if (Test-Path $bashPath) {Write-Host ""Write-Host "MSYS2 Environment Information:"Write-Host "----------------------------"try {$unameOutput = & $bashPath -c "uname -a"if ($LASTEXITCODE -eq 0) {Write-Host $unameOutput} else {Write-Warning "Failed to execute uname command"exit 1}} catch {Write-Warning "Failed to execute uname command"exit 1}Write-Host "----------------------------"Write-Host "MSYS2 environment loaded successfully."Write-Host ""
} else {Write-Error "Error: bash.exe not found at $bashPath"exit 1
}# 查看 系统上所有环境变量
# Get-ChildItem Env:# 查看powershell配置文件内容
# notepad $PROFILE

main.c文件内容:

#include <stdio.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>int main() {// 待检查的编解码器列表const char *codecs[] = {"libx264",    // H.264 编码器"libx265",    // HEVC 编码器"libfdk_aac", // AAC 编码器"libmp3lame", // MP3 编码器NULL          // 结束标记};printf("FFmpeg 集成编解码器状态检查:\n");printf("===========================\n");// 遍历并检查每个编解码器for (int i = 0; codecs[i] != NULL; i++) {const AVCodec *codec = avcodec_find_encoder_by_name(codecs[i]);if (!codec) {// 若编码器未找到,尝试查找解码器codec = avcodec_find_decoder_by_name(codecs[i]);}if (codec) {printf("[✅] %-12s : 已启用 (类型: %s)\n", codecs[i], codec->type == AVMEDIA_TYPE_VIDEO ? "视频" : "音频");} else {printf("[❌] %-12s : 未启用或未编译\n", codecs[i]);}}return 0;
}

构建命令

# 在vscode的powershell 执行set_env.ps1脚本,配置msys2
.\set_env.ps1# 生成构建系统(在项目根目录下执行)
cmake .. -G "MinGW Makefiles" -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++# 编译(在build目录下执行)
cmake --build . --config Release

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

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

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

相关文章

驱动开发,队列,环形缓冲区:以GD32 CAN 消息处理为例

对环形缓冲区进行进一步的优化和功能扩展&#xff0c;以应对更复杂的实际应用场景&#xff0c;特别是针对 CAN 总线消息处理的场景。 一、优化点 1&#xff1a;动态配置环形缓冲区大小在原始实现中&#xff0c;我们固定了缓冲区大小为 RINGBUFF_LEN 64。这种方式虽然简单&am…

SQL基础知识,MySQL学习(长期更新)

1、基本操作&#xff0c;增删查改 INSERT INTO 表名 (字段1, 字段2, ...) VALUES (值1, 值2, ...); DELETE FROM 表名 WHERE 条件 SELECT * FROM 表名 WHERE 条件 UPDATE 表名 SET 字段1 值, 字段2 值, ... WHERE 条件; SELECT * INTO 新表 FROM 旧表 WHERE… INSERT INTO 语…

Git(一):初识Git

文章目录 Git(一)&#xff1a;初识GitGit简介核心功能分布式特性结构与操作优势与适用场景 创建本地仓库git init配置name与email--global 工作区、暂存区与版本库git addgit commitcommit后.git的变化 Git(一)&#xff1a;初识Git Git简介 Git 是一个分布式版本控制系统&…

第19天:初级数据库学习笔记3

分组函数&#xff08;多行处理函数&#xff09; 即多个输入对应一个输出。前面讲的数据处理函数是单行处理函数。&#xff08;在公司中常说单&#xff0c;多行处理函数&#xff09; 分组函数包括五个&#xff1a; max&#xff1a;最大值min&#xff1a;最小值avg&#xff1a…

Windows11下搭建Raspberry Pi Pico编译环境

1. 系统与工具要求 PC平台&#xff1a; Windows 11 专业版 Windows GCC: gcc-15.1.0-64.exe GNU Make: 4.3 Git: 2.49.0 cmake: 4.0.2 python:3.12.11 Arm GNU Toolchain Downloads – Arm Developer 2. 工具安装与验证 2.1 工具安装 winget安装依赖工具&#xff08;Windows …

【C语言极简自学笔记】重讲运算符

一、算术操作符 算术操作符描述把两个操作数相加-第一个操作数减去第二个操作数*把两个操作数相乘/分子除以分母%取模运算符&#xff0c;整除后的余数 注意&#xff1a;1.除号的两端都是整数的时候执行的是整数的除法&#xff0c;两端只要有一个浮点数&#xff0c;就执行浮点…

持续集成 CI/CD-Jenkins持续集成GitLab项目打包docker镜像推送k8s集群并部署至rancher

Jenkins持续集成GitLab项目 GitLab提交分支后触发Jenkis任务 之前是通过jar包在shell服务器上进行手动部署&#xff0c;麻烦且耗时。现通过Jenkins进行持续集成实现CI/CD。以test分支为例 提交即部署。 由于是根据自己实际使用过程 具体使用到了 gitlabjenkinsdockerharborra…

Apache Iceberg与Hive集成:非分区表篇

引言 在大数据处理领域&#xff0c;Apache Iceberg凭借其先进的表格式设计&#xff0c;为大规模数据分析带来了新的可能。当Iceberg与Hive集成时&#xff0c;这种强强联合为数据管理与分析流程提供了更高的灵活性和效率。本文将聚焦于Iceberg与Hive集成中的非分区表场景&#…

webpack 如何区分开发环境和生产环境

第一种方法: 方法出处&#xff1a;命令行接口&#xff08;CLI&#xff09; | webpack 中文文档 1.利用webpack.config.js 返回的是个函数&#xff0c;利用函数的参数&#xff0c;来区分环境 具体步骤 1&#xff09; package.json文件&#xff1a;在npm scripts 命令后面追加 …

React组件通信——context(提供者/消费者)

Context 是 React 提供的一种组件间通信方式&#xff0c;主要用于解决跨层级组件 props 传递的问题。它允许数据在组件树中"跨级"传递&#xff0c;无需显式地通过每一层 props 向下传递。 一、Context 核心概念 1. 基本组成 React.createContext&#xff1a;创建 C…

“微信短剧小程序开发指南:从架构设计到上线“

1. 引言&#xff1a;短剧市场的机遇与挑战 近年来&#xff0c;短视频和微短剧市场呈现爆发式增长&#xff0c;用户碎片化娱乐需求激增。短剧小程序凭借轻量化、社交传播快、变现能力强等特点&#xff0c;成为内容创业的新风口。然而&#xff0c;开发一个稳定、流畅且具备商业价…

RPC与RESTful对比:两种API设计风格的核心差异与实践选择

# RPC与RESTful对比&#xff1a;两种API设计风格的核心差异与实践选择 ## 一、架构哲学与设计目标差异 1. **RPC&#xff08;Remote Procedure Call&#xff09;** - **核心思想**&#xff1a;将远程服务调用伪装成本地方法调用&#xff08;方法导向&#xff09; - 典型行为…

【pytest进阶】pytest之钩子函数

什么是 hook (钩子)函数 经常会听到钩子函数(hook function)这个概念,最近在看目标检测开源框架mmdetection,里面也出现大量Hook的编程方式,那到底什么是hook?hook的作用是什么? what is hook ?钩子hook,顾名思义,可以理解是一个挂钩,作用是有需要的时候挂一个东西…

深度学习计算——动手学深度学习5

环境&#xff1a;PyCharm python3.8 1. 层和块 块&#xff08;block&#xff09;可以描述 单个层、由多个层组成的组件或整个模型本身。 使用块进行抽象的好处&#xff1a; 可将块组合成更大的组件(这一过程通常是递归) 如 图5.1.1所示。通过定义代码来按需生成任意复杂度…

NodeJS的fs模块的readFile和createReadStream区别以及常见方法

Node.js 本身没有像 Java 那样严格区分字符流和字节流&#xff0c;区别主要靠编码&#xff08;encoding&#xff09;来控制数据是以 Buffer&#xff08;二进制字节&#xff09;形式还是字符串&#xff08;字符&#xff09;形式处理。 详细解释&#xff1a; 方面JavaNode.js字节…

基于二进制XOR运算的机器人运动轨迹与对称图像自动生成算法

原创&#xff1a;项道德&#xff08;daode3056,daode1212&#xff09; 新的算法出现&#xff0c;往往能给某些行业与产业带来革命与突破。为探索机器人运动轨迹与对称图像自动生成算法&#xff0c;本人已经通过18种算法的测试&#xff0c;最终&#xff0c;以二进制的XOR运算为…

Spring AI 项目实战(七):Spring Boot + Spring AI Tools + DeepSeek 智能工具平台(附完整源码)

系列文章 序号文章名称1Spring AI 项目实战(一):Spring AI 核心模块入门2Spring AI 项目实战(二):Spring Boot + AI + DeepSeek 深度实战(附完整源码)3Spring AI 项目实战(三):Spring Boot + AI + DeepSeek 打造智能客服系统(附完整源码)4Spring AI 项目实战(四…

spring-webmvc @RequestHeader 典型用法

典型用法 基础用法&#xff1a;获取指定请求头值 GetMapping("/info") public String getInfo(RequestHeader("User-Agent") String userAgent) {return "User-Agent: " userAgent; }如果请求中包含 User-Agent 请求头&#xff0c;则其值将被…

Ubuntu:20.04中安装docker

是的&#xff0c;您列出的命令是完整的安装步骤&#xff0c;但为了确保100%可靠性和处理可能的问题&#xff0c;我建议进行以下优化和补充&#xff1a; 完整优化的安装脚本&#xff08;包含错误处理和验证&#xff09; #!/bin/bash# 1. 彻底清理旧版本和配置 sudo apt remove…

大数据实时风控引擎:Spark Streaming、Kafka、Flink与Doris的融合实践

大数据实时风控引擎&#xff1a;Spark Streaming、Kafka、Flink与Doris的融合实践 在数字金融、电商交易与在线服务的核心战场&#xff0c;风险控制能力已成为业务的生命线。传统批量风控模式在应对瞬息万变的欺诈攻击、信用风险时捉襟见肘。本文将深入探讨如何利用**Spark St…