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

FFmpeg推流

目录

一. 环境准备 

二. 安装FFmpeg

三. 给docker主机安装docker服务

四. 使用 FFmpeg 进行推流测试


FFmpeg是一个非常强大的多媒体处理工具,它可以用于视频和音频的录制、转换以及流处理。在流处理方面,FFmpeg可以用来推流,即将本地媒体文件或者实时数据推送到流媒体服务器上。

一. 环境准备 

关闭防火墙和selinux,进行时间同步。

主机名IP系统软件版本配置信息
ffmpeg192.168.226.31Rocky_linux9.4

FFmpeg-n5.0.1

nasm-2.16.03

2核4G
galera2192.168.226.32Rocky_linux9.4mysql-wsrep-8.0

galera-26.4.14-1

2核4G

FFmpeg下载地址:https://github.com/FFmpeg/FFmpeg/tags

nasm下载地址nasm-2.16.03.tar.gz:Index of /pub/nasm/releasebuilds/2.16.03

二. 安装FFmpeg

下载并上传压缩包,这里我已经传好了。

[root@ffmpeg ~]# ll
total 15748
-rw-r--r--  1 root root 14428012 Aug  5 17:48 FFmpeg-n5.1.6.tar.gz
-rw-------. 1 root root      815 Jun  6 14:00 anaconda-ks.cfg
-rw-r--r--  1 root root  1688160 Aug  5 19:40 nasm-2.16.03.tar.gz

 首先安装编译 FFmpeg 所需的依赖项:

[root@ffmpeg ~]# yum install -y epel-release
[root@ffmpeg ~]# yum install -y autoconf automake bzip2 bzip2-devel cmake freetype-devel gcc gcc-c++ git libtool make mercurial pkgconfig zlib-devel

安装 NASM

NASM 是一个汇编器,FFmpeg 需要它来编译

[root@ffmpeg ~]# tar -xf nasm-2.16.03.tar.gz
[root@ffmpeg ~]# cd nasm-2.16.03
[root@ffmpeg nasm-2.16.03]# ./configure
[root@ffmpeg nasm-2.16.03]# make && make install
[root@ffmpeg nasm-2.16.03]# nasm -v
NASM version 2.16.03 compiled on Aug  5 2024

安装x264

[root@ffmpeg ~]# git clone https://code.videolan.org/videolan/x264.git
[root@ffmpeg ~]# cd x264/#--enable-static 使得构建过程中生成静态库。
#--enable-shared 使得构建过程中生成共享库。
[root@ffmpeg x264]# ./configure --enable-static --enable-shared
[root@ffmpeg x264]# make && make install && cd ~
[root@ffmpeg ~]# export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:$PKG_CONFIG_PATH
[root@ffmpeg ~]# pkg-config --cflags --libs x264

获取 FFmpeg 源代码

[root@ffmpeg ~]# tar -xf FFmpeg-n5.1.6.tar.gz
[root@ffmpeg ~]# cd FFmpeg-n5.1.6
[root@ffmpeg FFmpeg-n5.1.6]# ./configure --enable-shared --enable-libx264 --enable-gpl --prefix=/usr/local/ffmpeg --extra-cflags="-fPIC"
[root@ffmpeg FFmpeg-n5.1.6]# make && make install 
[root@ffmpeg FFmpeg-n5.1.6]# echo $LD_LIBRARY_PATH
[root@ffmpeg FFmpeg-n5.1.6]# ls -l /usr/local/ffmpeg/lib/libavdevice.so.59
[root@ffmpeg FFmpeg-n5.1.6]# ls -l /usr/local/ffmpeg/lib/libavdevice.so.59.7.100
[root@ffmpeg FFmpeg-n5.1.6]# export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
[root@ffmpeg ~]# export PATH=/usr/local/ffmpeg/bin:$PATH
[root@ffmpeg ~]# source ~/.bashrc[root@ffmpeg ~]# ffmpeg -version
ffmpeg version 5.1.6 Copyright (c) 2000-2024 the FFmpeg developers
built with gcc 11 (GCC)
configuration: --enable-shared --enable-libx264 --enable-gpl --prefix=/usr/local/ffmpeg --extra-cflags=-fPIC
libavutil      57. 28.100 / 57. 28.100
libavcodec     59. 37.100 / 59. 37.100
libavformat    59. 27.100 / 59. 27.100
libavdevice    59.  7.100 / 59.  7.100
libavfilter     8. 44.100 /  8. 44.100
libswscale      6.  7.100 /  6.  7.100
libswresample   4.  7.100 /  4.  7.100
libpostproc    56.  6.100 / 56.  6.100

三. 给docker主机安装docker服务

安装 

# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# Step 2: 添加软件源信息
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# Step 3
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo
# Step 4: 更新并安装Docker-CE
sudo yum makecache
sudo yum -y install docker-ce
# Step 4: 开启Docker服务
sudo service docker start

配置加速器

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://docker.rainbond.cc"],"exec-opts": ["native.cgroupdriver=systemd"],"log-driver": "json-file","log-opts": {"max-size": "100m"},"storage-driver": "overlay2"
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

拉取nginx镜像

tiangolo/nginx-rtmp 是一个 Docker 镜像,用于提供 Nginx 和 RTMP(Real-Time Messaging Protocol)服务器的功能。这个镜像由 Tiangolo 维护,主要用于视频流媒体的处理和转发。

[root@docker ~]# docker pull tiangolo/nginx-rtmp:latest

 创建nginx配置文件

[root@docker ~]# vim nginx.conf
worker_processes auto;  # 自动根据可用的 CPU 核心数量设置 worker 进程数
rtmp_auto_push on;events {worker_connections 1024;  # 增加 worker 可以处理的连接数
}http {sendfile on;              # 启用高效文件传输tcp_nopush on;            # 发送响应时优化 TCP 包tcp_nodelay on;           # 减少网络延迟keepalive_timeout 5 5;    # 长连接超时设置client_body_buffer_size 128k;  # 客户端请求体缓冲区大小client_max_body_size 10m;      # 允许客户端请求的最大单文件字节数client_body_timeout 10;        # 客户端请求体超时client_header_timeout 10;      # 客户端请求头超时send_timeout 10;               # 响应发送超时server {listen 8080;  # 监听 8080 端口# HLS 配置location /hls {types {application/vnd.apple.mpegurl m3u8;  # 设置 MIME 类型}root /mnt/;  # HLS 文件根目录add_header Cache-Control no-cache;  # 禁用缓存add_header Access-Control-Allow-Origin *;  # 跨域支持}}
}rtmp {server {listen 1935;           # 监听 1935 端口,用于 RTMP 流listen [::]:1935 ipv6only=on;  # 同时支持 IPv6application live {live on;  # 启用直播record off;  # 关闭录制# HLS 配置hls on;  # 启用 HLShls_path /mnt/hls/;  # HLS 文件存储路径hls_fragment 3s;  # HLS 片段长度hls_playlist_length 30s;  # HLS 播放列表长度}}
}

运行并查看端口

[root@docker ~]# docker run -d -p 1935:1935 -p 8080:8080 -v ./nginx.conf:/etc/nginx/nginx.conf --name nginx-rtmp tiangolo/nginx-rtmp[root@docker ~]# docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                                                                                  NAMES
2c8eb664354a   tiangolo/nginx-rtmp   "nginx -g 'daemon of…"   18 seconds ago   Up 17 seconds   0.0.0.0:1935->1935/tcp, :::1935->1935/tcp, 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   nginx-rtmp[root@docker ~]# ss -tnlp
State               Recv-Q              Send-Q                           Local Address:Port                           Peer Address:Port             Process                                              
LISTEN              0                   128                                    0.0.0.0:22                                  0.0.0.0:*                 users:(("sshd",pid=832,fd=3))                       
LISTEN              0                   4096                                   0.0.0.0:1935                                0.0.0.0:*                 users:(("docker-proxy",pid=16089,fd=4))             
LISTEN              0                   4096                                   0.0.0.0:8080                                0.0.0.0:*                 users:(("docker-proxy",pid=16104,fd=4))             
LISTEN              0                   128                                       [::]:22                                     [::]:*                 users:(("sshd",pid=832,fd=4))                       
LISTEN              0                   4096                                      [::]:1935                                   [::]:*                 users:(("docker-proxy",pid=16094,fd=4))             
LISTEN              0                   4096                                      [::]:8080                                   [::]:*                 users:(("docker-proxy",pid=16127,fd=4))  

  

四. 使用 FFmpeg 进行推流测试

准备一个视频文件、摄像头输入或其他任何 FFmpeg 支持的媒体源。

例如我在这个网站下载一个MP4的格式视频,大约五分钟的大小。

哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

https://www.kedou.life/

 上传到ffmpeg主机,视频名为shipin.mp4

[root@ffmpeg ~]# ll
total 76580
drwxrwxr-x  17 root root     4096 Aug  5 20:43 FFmpeg-n5.1.6
-rw-r--r--   1 root root 14428012 Aug  5 17:48 FFmpeg-n5.1.6.tar.gz
-rw-------.  1 root root      815 Jun  6 14:00 anaconda-ks.cfg
drwxrwsr-x  24  802  900     4096 Aug  5 19:43 nasm-2.16.03
-rw-r--r--   1 root root  1688160 Aug  5 19:40 nasm-2.16.03.tar.gz
-rw-r--r--   1 root root 62278099 Aug  5 21:00 shipin.mp4
drwxr-xr-x  11 root root     4096 Aug  5 20:31 x264

 推流测试

[root@ffmpeg ~]# ffmpeg -re -i shipin.mp4 -c:v libx264 -preset ultrafast -maxrate 1500k -bufsize 3000k -pix_fmt yuv420p -g 50 -s 1280x720 -c:a aac -b:a 128k -ar 44100 -f flv rtmp://192.168.226.32:1935/live/stream

这个时候,切换到docker容器里查看

[root@docker ~]# docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                                                                                  NAMES
2c8eb664354a   tiangolo/nginx-rtmp   "nginx -g 'daemon of…"   12 minutes ago   Up 12 minutes   0.0.0.0:1935->1935/tcp, :::1935->1935/tcp, 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   nginx-rtmp[root@docker ~]# docker exec -it nginx-rtmp /bin/bash
root@2c8eb664354a:/# cd /mnt/hls/  root@2c8eb664354a:/mnt/hls# ls
stream-0.ts  stream-1.ts  stream-2.ts  stream-26.ts  stream-27.ts  stream-28.ts  stream-29.ts  stream.m3u8

然后桌面新建一个.html结尾的文件,注意代码里你需要修改的是对应的IP地址

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>HLS Stream with Video.js</title><link href="https://vjs.zencdn.net/7.14.3/video-js.css" rel="stylesheet" /><style>/* 自定义 Video.js 播放器样式 */.vjs-default-skin {font-family: "Arial", sans-serif;font-size: 16px;color: #FFF;background-color: #333;border: 2px solid #555;border-radius: 10px;overflow: hidden;}.vjs-control-bar {background: rgba(0, 0, 0, 0.7);}.vjs-big-play-button {background: rgba(255, 255, 255, 0.3);border: none;border-radius: 50%;}.vjs-progress-holder {background: rgba(255, 255, 255, 0.2);}.vjs-play-progress {background: #FFCC00; /* 进度条前景色 */}.vjs-load-progress {background: #666; /* 加载进度条色 */}.vjs-seek-to-live-control {display: none;}.video-js {width: 720px;  /* 固定宽度 */height: 405px; /* 固定高度,宽高比为16:9 */margin: 0 auto;  /* 水平居中 */box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.5);display: block;  /* 确保播放器为块级元素 */}body {background-color: #333;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;}</style>
</head>
<body><video id="my-video" class="video-js vjs-default-skin" controls preload="auto"data-setup='{"fluid": false}'>// 修改此处的IP为你的IP即可<source src="http://192.168.226.32:8080/hls/stream.m3u8" type="application/x-mpegURL"></video><script src="https://vjs.zencdn.net/7.14.3/video.min.js"></script><script>var player = videojs('my-video', {controls: true,autoplay: false,preload: 'auto'});// 示例: 监听播放进度事件player.on('timeupdate', function() {var currentTime = player.currentTime();var duration = player.duration();console.log('当前播放时间:', currentTime, '总时长:', duration);});</script>
</body>
</html>

在推流的同时,打开网页播放即可

相关文章:

FFmpeg推流

目录 一. 环境准备 二. 安装FFmpeg 三. 给docker主机安装docker服务 四. 使用 FFmpeg 进行推流测试 FFmpeg是一个非常强大的多媒体处理工具&#xff0c;它可以用于视频和音频的录制、转换以及流处理。在流处理方面&#xff0c;FFmpeg可以用来推流&#xff0c;即将本地媒体…...

【Rust光年纪】简化文件操作流程:深度剖析多款文件系统操作库

文件系统操作利器&#xff1a;介绍常用的文件操作库 前言 在现代软件开发中&#xff0c;文件系统操作是一个十分常见的需求。为了更加高效地进行文件系统操作&#xff0c;开发人员经常会使用各种文件系统操作库来简化开发流程、提高代码可维护性。本文将介绍几个常用的文件系…...

FFmpeg实现文件夹多视频合并

使用FFmpeg合并文件夹中的多个视频文件&#xff0c;可以通过多种方式来实现&#xff0c;具体取决于你希望如何合并这些视频文件。下面介绍两种常见的方法&#xff1a; 按顺序拼接多个视频文件&#xff1a; 适用于希望将多个视频文件按顺序合并成一个视频文件的情况。 将多个视…...

[设备] 关于手机设备中几种传感器的研究

一、手机设备中三位坐标系概念 X轴的方向&#xff1a;沿着屏幕水平方向从左到右&#xff0c;如果手机如果不是是正方形的话&#xff0c;较短的边需要水平 放置&#xff0c;较长的边需要垂直放置。Y轴的方向&#xff1a;从屏幕的左下角开始沿着屏幕的的垂直方向指向屏幕的顶端Z轴…...

C#通过Modbus读取温度和湿度

使用 C# 通过 RS-485 接口读取温湿度数据并在电脑上显示&#xff0c;需要使用串口通信。假设你的温湿度传感器使用 Modbus RTU 协议&#xff0c;这里提供一个示例代码&#xff0c;使用 System.IO.Ports 命名空间进行串口通信&#xff0c;并使用 Modbus 协议库 NModbus 进行通信…...

海量数据处理商用短链接生成器平台 - 9

第二十六章 短链服务-冗余双写架构删除和更新消费者开发实战 第1集 冗余双写架构-更新短链消费者开发实战 简介&#xff1a; 短链服务-更新短链-消费者开发实战 具体步骤见代码 第2集 冗余双写架构-更新短链消费者链路测试 简介&#xff1a; 冗余双写架构-更新短链消费者链…...

从困境到突破,EasyMR 集群迁移助力大数据底座信创国产化

在大数据时代&#xff0c;企业对数据的依赖程度越来越高。然而&#xff0c;随着业务的不断发展和技术的快速迭代&#xff0c;大数据平台的集群迁移已成为企业数据中台发展途中无法回避的需求。在大数据平台发展初期&#xff0c;国内数据中台市场主要以国外开源 CDH、商业化 CDP…...

【Mysql】第十二章 视图特性(概念+使用)

文章目录 一、概念二、使用1.创建视图2.修改视图会影响基表3.修改基表会影响视图4.删除视图 一、概念 视图不能添加索引&#xff0c;也不能有关联的触发器或者默认值。由于视图和基表用的本质是同一份数据&#xff0c;因此对视图的修改会影响到基表&#xff0c;对基表的修改也…...

【颠覆数据处理的利器】全面解读Apache Flink实时大数据处理的引擎-上篇

什么是 Apache Flink&#xff1f; Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于对无界和有界数据流进行有状态计算。Flink 被设计为在所有常见的集群环境中运行&#xff0c;以内存速度和任何规模执行计算。 如何理解无界和有界数据&#xff1f; 无界数据&#…...

【C++】C++11(可变参数模板、lambda表达式、包装器)

文章目录 1. 可变参数模板1.1 介绍1.2 emplace系列接口实现 2. lambda表达式2.1 语法介绍2.2 原理 3. 包装器4. bind 1. 可变参数模板 1.1 介绍 可变参数我们在C语言阶段已经了解过了&#xff0c;C语言中叫做可变参数列表&#xff0c;其中使用 ... 代表可变参数。 C语言中的可…...

矩阵获客时代,云微客让你一个人成就一支队伍

短视频利用大家碎片化的时间让自身得到广泛的应用和发展&#xff0c;因此很多公司纷纷布局短视频赛道。但是一个账号的曝光量有限&#xff0c;并且能够出的爆款视频更是少之又少&#xff0c;这个时候就需要增加账号的数量&#xff0c;布局形成账号矩阵。 做账号矩阵&#xff0c…...

浅谈基础的图算法——Tarjan求强联通分量算法(c++)

文章目录 强联通分量SCC概念例子有向图的DFS树代码例题讲解[POI2008] BLO-Blockade题面翻译题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 思路AC代码 【模板】割点&#xff08;割顶&#xff09;题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示…...

【Godot4自学手册】第四十四节用着色器(shader)实现溶解效果

本小节&#xff0c;我将自学用用着色器&#xff08;shader&#xff09;实现溶解效果&#xff0c;最终效果如下&#xff1a; 一、进行shader初始设置 首先我们进入Player场景&#xff0c;选择AnimatedSprite2D节点&#xff0c;在检查器中找到CanvasItem属性&#xff0c;并在M…...

【画流程图工具】

画流程图工具 draw.io draw.io&#xff08;现称为 diagrams.net&#xff09;是一款在线图表绘制工具&#xff0c;可以用于创建各种类型的图表&#xff0c;如流程图、网络图、组织结构图、UML图、思维导图等。以下是关于它的一些优点、应用场景及使用方法&#xff1a; 优点&a…...

Revit二次开发选择过滤器,SelectionFilter

过滤器分为选择过滤器与规则过滤器 规则过滤器可以看我之前写的这一篇文章: Revit二次开发在项目中给链接模型附加过滤器 选择过滤器顾名思义就是可以将选择的构件ID集合传入并加入到视图过滤器中,有一些场景需要对某些构件进行过滤选择,但是没有共同的逻辑规则进行筛选的情况…...

【Linux】进程概念—环境变量

目录 一、冯诺依曼体系结构 二、操作系统(Operator System) 1 .概念 2 .设计OS的目的 3 . 定位 4 . 系统调用和库函数概念 三、进程 1 .基本概念 2 .描述进程-PCB&#xff08;process control block&#xff09;进程控制块 3 . 组织进程 4 . 查看进程 5 .通过系统调用获取进程…...

第十二章 Spring MVC 框架扩展和SSM框架整合(2023版本IDEA)

学习目标 12.1 Spring MVC 框架处理JSON数据12.1.1 JSON数据的传递处理12.1.2 JSON数据传递过程中的中文乱码和日期问题12.1.3 多视图解析器 12.2 Spring MVC 框架中的数据格式转换12.2.1 Spring MVC 框架数据转换流程12.2.2 编写自定义转换器12.2.3 使用InitBinder装配自定义编…...

js中的全局函数有这些

js中的全局函数有这些,记忆规则 6个编译 escape、‌‌unescape、decodeURI、decodeURIComponent、encodeURI、encodeURIComponent 2个数据处理 Number()、String() 4个数字处理 ‌isFinite、isNaN、‌parseFloat、parseInt 1个特殊情况 eval()...

Android SurfaceFlinger——重绘闪烁处理(四十六)

在帧数据准备完成后,下一步是调用 devOptRepaintFlash() 函数处理显示输出设备的可选重绘闪烁问题,这里我们就来看一下重绘闪屏问题的处理方案。 1.更新输出设备的色彩配置文件2.更新与合成相关的状态3.计划合成帧图层4.写入合成状态5.设置颜色矩阵6.开始帧7.准备帧数据以进行…...

罗马数字转整数 C++

罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#x…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...