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

FFmpeg进阶: 采用音频滤镜对音频进行转码

文章目录

    • 采样位数
    • 采样率
    • 声道布局
    • 码率
    • 使用FFmpeg音频滤镜进行转码
    • 参考链接

很多时候为了让视频文件适应不同的播放领域,我们需要对音频文件进行转码操作,转码操作其实主要就是修改音频文件的各种参数包括:采样位数、采样率、音频布局、码率等等。下面分别介绍一下各个参数的意义和作用。

采样位数

采样位数也称为位深度、分辨率, 它是指声音的连续强度被数字表示后可以分为多少级。N-bit的意思声音的强度被均分为2^N级。16位的就是65535级。这是一个很大的数了,人可能也分辨不出1/65536的音强差别。也可以说是声卡的分辨率,它的数值越大,分辨率也就越高,所发出声音的能力越强。这里的采样倍数主要针对的是信号的强度特性,采样率针对的是信号的时间(频率)特性这是两个不一样的概念。

ffmpeg常用的采样位数对应的格式如下所示:

enum AVSampleFormat {AV_SAMPLE_FMT_NONE = -1,AV_SAMPLE_FMT_U8,          ///< unsigned 8 bitsAV_SAMPLE_FMT_S16,         ///< signed 16 bitsAV_SAMPLE_FMT_S32,         ///< signed 32 bitsAV_SAMPLE_FMT_FLT,         ///< floatAV_SAMPLE_FMT_DBL,         ///< doubleAV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planarAV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planarAV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planarAV_SAMPLE_FMT_FLTP,        ///< float, planarAV_SAMPLE_FMT_DBLP,        ///< double, planarAV_SAMPLE_FMT_S64,         ///< signed 64 bitsAV_SAMPLE_FMT_S64P,        ///< signed 64 bits, planarAV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
};

采样率

音频采样,是把声音从模拟信号转换为数字信号。采样率,就是每秒对声音进行采集的次数,同样也是所得的数字信号的每秒样本数。在对声音进行采样时,常用的采样率有:
8,000 Hz - 电话所用采样率, 对于人的说话已经足够
11,025 Hz - AM调幅广播所用采样率
22,050 Hz~24,000 Hz - FM调频广播所用采样率
32,000 Hz - miniDV 数码视频 camcorder、DAT (LP mode)所用采样率
44,100 Hz - 音频 CD, 也常用于 MPEG-1 音频(VCD, SVCD, MP3)所用采样率
47,250 Hz - 商用PCM录音机所用采样率
48,000 Hz - miniDV、数字电视、DVD、DAT、电影和专业音频所用的数字声音所用采样率
50,000 Hz - 商用数字录音机所用采样率
96,000 或者192,000 Hz - DVD-Audio、一些 LPCM DVD 音轨、BD-ROM(蓝光盘)音轨、和 HD-DVD (高清晰度 DVD)音轨所用所用采样率
2.8224 MHz - Direct Stream Digital 的 1 位 sigma-delta modulation 过程所用采样率。

采样越高,声音的还原就越真实越自然,人对频率的识别范围是20HZ - 20000HZ, 如果每秒钟能对声音做 20000 个采样, 回放时就足可以满足人耳的需求.所以 22050 的采样频率是常用的, 44100已是CD音质, 超过48000的采样对人耳已经没有意义。这和电影的每秒 24 帧图片的道理差不多。

声道布局

当人听到声音时,能对声源进行定位,那么通过在不同的位置设置声源,就可以造就出更好的听觉感受。常见的声道有:

  1. 单声道, mono
  2. 双声道, stereo, 最常见的类型,包含左声道以及右声道
  3. 2.1声道,在双声道基础上加入一个低音声道
  4. 5.1声道,包含一个正面声道、左前方声道、右前方声道、左环绕声道、右环绕声道、一个低音声道,最早应用于早期的电影院
  5. 7.1声道,在5.1声道的基础上,把左右的环绕声道拆分为左右环绕声道以及左右后置声道,主要应用于BD以及现代的电影院

码率

码率也就是每秒的传输速率(也叫比特率),压缩的音频文件常用倍速来表示,比如达到CD音质的MP3是128kbps/44100HZ。注意这里的单位是bit而不是Byte,一个Byte等于8个bit(位),bit是最小的单位,一般用于网络速度的描述和各种通信速度,Byte则用于计算硬盘,内存的大小。

使用FFmpeg音频滤镜进行转码

不同领域对音频的播放要求是不一样的,所以需要针对不同的领域对音频参数进行调整,这里介绍一下如何通过音频滤镜调整音频数据的相关参数,对应的实现如下:

#include "../audio_filter.h"extern "C" 
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
#include <libavfilter/avfilter.h>
#include <libswresample/swresample.h>
}#include <string>/**@brief 转换音频数据的格式
* @param[in]  output_filename 输出文件名称
* @param[in]  input_filename 输入文件名称
* @param[in]  sample_fmt 采样格式
* @param[in]  sample_rate 采样率
* @param[in]  channel_layout 通道布局
* @param[in]  bitrate 码率
* @return  函数执行结果
* - 0     成功
* - 其它  失败
*/
int transcode_audio(const char *output_filename, const char *input_filename, AVSampleFormat sample_fmt,int sample_rate, uint64_t channel_layout, uint64_t bitrate) 
{//输入输出格式AVFormatContext *inFmtCtx = nullptr;AVFormatContext *outFmtCtx = nullptr;//解码器和编码器AVCodecContext *aDecCtx = nullptr;AVCodecContext *aEncCtx = nullptr;//输出流AVStream *aOutStream = nullptr;int ret;// open input fileret = avformat_open_input(&inFmtCtx, input_filename, nullptr, nullptr);ret = avformat_find_stream_info(inFmtCtx, nullptr);// open output fileavformat_alloc_output_context2(&outFmtCtx, nullptr, nullptr, output_filename);for (int i = 0; i < inFmtCtx->nb_streams; ++i){AVStream *inStream = inFmtCtx->streams[i];if (inStream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO){//输入流的解码器AVCodec *decoder = avcodec_find_decoder(inStream->codecpar->codec_id);aDecCtx = avcodec_alloc_context3(decoder);ret = avcodec_parameters_to_context(aDecCtx, inStream->codecpar);ret = avcodec_open2(aDecCtx, decoder, nullptr);//输出流的编码器AVCodec *encoder = avcodec_find_encoder(outFmtCtx->oformat->audio_codec);aOutStream = avformat_new_stream(outFmtCtx, encoder);aOutStream->id = outFmtCtx->nb_streams - 1;aEncCtx = avcodec_alloc_context3(encoder);aEncCtx->codec_id = encoder->id;aEncCtx->sample_fmt = sample_fmt ? sample_fmt : aDecCtx->sample_fmt;aEncCtx->sample_rate = sample_rate ? sample_rate : aDecCtx->sample_rate;aEncCtx->channel_layout = channel_layout;aEncCtx->channels = av_get_channel_layout_nb_channels(channel_layout);aEncCtx->bit_rate = bitrate ? bitrate : aDecCtx->bit_rate;aEncCtx->time_base = { 1, aEncCtx->sample_rate };aOutStream->time_base = aEncCtx->time_base;if (outFmtCtx->oformat->flags & AVFMT_GLOBALHEADER)aEncCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;avcodec_open2(aEncCtx, encoder, nullptr);ret = avcodec_parameters_from_context(aOutStream->codecpar, aEncCtx);av_dict_copy(&aOutStream->metadata, inStream->metadata, 0);break;}}if (!(outFmtCtx->oformat->flags & AVFMT_NOFILE)) {ret = avio_open(&outFmtCtx->pb, output_filename, AVIO_FLAG_WRITE);if (ret < 0) {return -1;}}ret = avformat_write_header(outFmtCtx, nullptr);if (ret < 0) {return -1;}AVFrame *inAudioFrame = av_frame_alloc();AVFrame *outAudioFrame = av_frame_alloc();outAudioFrame->format = aEncCtx->sample_fmt;outAudioFrame->sample_rate = aEncCtx->sample_rate;outAudioFrame->channel_layout = aEncCtx->channel_layout;outAudioFrame->nb_samples = aEncCtx->frame_size;ret = av_frame_get_buffer(outAudioFrame, 0);int64_t audio_pts = 0;//修改音频数据包格式的滤镜AudioFilter filter;char description[512];AudioConfig inConfig(aDecCtx->sample_fmt, aDecCtx->sample_rate, aDecCtx->channel_layout, aDecCtx->time_base);AudioConfig outConfig(aEncCtx->sample_fmt, aEncCtx->sample_rate, aEncCtx->channel_layout, aEncCtx->time_base);char ch_layout[64];av_get_channel_layout_string(ch_layout, sizeof(ch_layout),av_get_channel_layout_nb_channels(aEncCtx->channel_layout), aEncCtx->channel_layout);snprintf(description, sizeof(description),"[in]aresample=sample_rate=%d[res];[res]aformat=sample_fmts=%s:sample_rates=%d:channel_layouts=%s[out]",aEncCtx->sample_rate,av_get_sample_fmt_name(aEncCtx->sample_fmt),aEncCtx->sample_rate,ch_layout);filter.create(description, &inConfig, &outConfig);filter.dumpGraph();while (true) {//解析音频帧并通过滤镜进行处理AVPacket inPacket{ nullptr };av_init_packet(&inPacket);ret = av_read_frame(inFmtCtx, &inPacket);if (ret == AVERROR_EOF) {break;}else if (ret < 0) {return -1;}if (inPacket.stream_index == aOutStream->index) {ret = avcodec_send_packet(aDecCtx, &inPacket);if (ret != 0) {printf("send packet error\n");}ret = avcodec_receive_frame(aDecCtx, inAudioFrame);if (ret == 0) {ret = filter.addInput1(inAudioFrame);av_frame_unref(inAudioFrame);if (ret < 0){printf("add filter input1 error\n");}do {outAudioFrame->nb_samples = aEncCtx->frame_size;ret = filter.getFrame(outAudioFrame);if (ret == 0) {outAudioFrame->pts = audio_pts;audio_pts += outAudioFrame->nb_samples;ret = avcodec_send_frame(aEncCtx, outAudioFrame);if (ret < 0) {printf("unable to send frame: %s\n");}}else {printf("unable to get filter audio frame: %s\n");break;}do {AVPacket outPacket{ nullptr };av_init_packet(&outPacket);ret = avcodec_receive_packet(aEncCtx, &outPacket);if (ret == 0) {av_packet_rescale_ts(&outPacket, aEncCtx->time_base, aOutStream->time_base);outPacket.stream_index = aOutStream->index;ret = av_interleaved_write_frame(outFmtCtx, &outPacket);if (ret < 0) {printf("unable to write packet\n");break;}}else {printf("unable to receive packet\n");break;}} while (true);} while (true);}else {printf("unable to receive frame\n");}}}//清理数据缓存int eof = 0;do {ret = filter.getFrame(outAudioFrame);if (ret == 0) {outAudioFrame->pts = audio_pts;audio_pts += outAudioFrame->nb_samples;}else {printf("filter queue finished\n");}ret = avcodec_send_frame(aEncCtx, ret == 0 ? outAudioFrame : nullptr);do {AVPacket outPacket{ nullptr };ret = avcodec_receive_packet(aEncCtx, &outPacket);if (ret == 0) {av_packet_rescale_ts(&outPacket, aEncCtx->time_base, aOutStream->time_base);outPacket.stream_index = aOutStream->index;ret = av_interleaved_write_frame(outFmtCtx, &outPacket);if (ret < 0) {eof = 1;break;}}else if (ret == AVERROR_EOF) {eof = 1;break;}else {break;}} while (true);} while (!eof);//释放对应的资源filter.destroy();av_write_trailer(outFmtCtx);avformat_close_input(&inFmtCtx);av_frame_free(&inAudioFrame);av_frame_free(&outAudioFrame);avcodec_free_context(&aDecCtx);avcodec_free_context(&aEncCtx);avformat_free_context(inFmtCtx);avformat_free_context(outFmtCtx);return 0;
}

这里我们将音频文件的采样格式修改为AV_SAMPLE_FMT_FLTP,同时我们将采样率降低为22050,码率修改为80kbps。

int main(int argc, char* argv[])
{if (argc != 3){printf("usage:%1 input filepath %2 outputfilepath");return -1;}//输入文件地址、输出文件地址std::string fileInput = std::string(argv[1]);std::string  fileOutput = std::string(argv[2]);transcode_audio(fileOutput.c_str(), fileInput.c_str(),(AVSampleFormat)AV_SAMPLE_FMT_FLTP,22050, AV_CH_LAYOUT_STEREO,80000);
}

参考链接

参考链接:https://www.cnblogs.com/yongdaimi/p/10722355.html

相关文章:

FFmpeg进阶: 采用音频滤镜对音频进行转码

文章目录采样位数采样率声道布局码率使用FFmpeg音频滤镜进行转码参考链接很多时候为了让视频文件适应不同的播放领域&#xff0c;我们需要对音频文件进行转码操作&#xff0c;转码操作其实主要就是修改音频文件的各种参数包括:采样位数、采样率、音频布局、码率等等。下面分别介…...

C++:AVL树

AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下&#xff0c;时间复杂度为O&#xff08;N&#xff09;&#xff1b; 两位俄罗斯的数学家G.M.Ade…...

Docker中安装Oracle-12c

前言 MySQL和Oracle是开发中常用到的两个关系型数据库管理系统&#xff0c;接上一期内容&#xff0c;这一期在Docker中完成oracle-12c的安装和配置。 安装oracle-12c 1、拉取oracle-12c镜像 启动Docker Desktop后在cmd窗口中执行docker search oracle命令&#xff0c;搜索O…...

教你如何用Python分析出选注双色球号码

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 又到了学Python时刻~ 数据集介绍 找从19年到现在的开奖历史数据&#xff0c;我们首先要把这个历史数据拿到&#xff0c; 拿到我们再进行做分析&#xff0c;分析每个号码出现的频率是多少&#xff0c; 哪个多&#x…...

elasticsearch映射及字段类型

查询映射关系类型上对字段的类型进行映射&#xff0c;我们前面知道可以通过get方法请求_mapping查询指定类型的映射关系&#xff1a;此语句可以查询get-together索引下的group类型的映射关系更新映射关系使用put方法可以更新类型的映射这里指定了new-events类型的字段映射关系&…...

1493围圈报数(队列)

题目描述 有&#xff4e;个人依次围成一圈&#xff0c;从第&#xff11;个人开始报数&#xff0c;数到第&#xff4d;个人出列&#xff0c;然后从出列的下一个人开始报数&#xff0c;数到第&#xff4d;个人又出列&#xff0c;…&#xff0c;如此反复到所有的人全部出列为止。…...

【ArcGIS Pro二次开发】(2):创建一个Add-in项目

Add-In即模块加载项&#xff0c;是一种能够快速扩展桌面应用程序功能的全新扩展方式。 一、创建新项目 1、打开VS2002&#xff0c;选择创建新项目。 2、在搜索框中输入“arcgis pro”&#xff0c;在搜索结果中选择【ArcGIS Pro 模块加载项】创建项目&#xff0c;注意选择语言应…...

浏览器缓存是如何提升网站访问速度的

提升速度&#xff0c;降低负载 浏览器访问一个页面时&#xff0c;会请求加载HTML、CSS和JS等静态资源&#xff0c;并把这些内容渲染到屏幕上。 对浏览器来说&#xff0c;如果页面没有更新&#xff0c;每次都去请求服务器是没有必要的。所以&#xff0c;把下载的资源缓存起来&…...

Linux中几个在终端中有趣的命令

uhh…最近我不知道该更新些什么&#xff0c;所以就更新Linux几个很有趣的命令 文章目录前言1.命令&#xff1a;sl安装 sl输出2. 命令&#xff1a;telnet命令&#xff1a;fortune安装fortune4.命令&#xff1a;rev&#xff08;反转&#xff09;安装rev5. 命令&#xff1a;factor…...

快来来试试SpringBoot3 中的新玩意~

你还在用OpenFeign嘛&#xff1f;快来试试 SpringBoot3 中的这个新玩意&#xff01;声明式HTTP调用 1、由来 Spring Boot3 去年底就已经正式发布&#xff0c;我也尝了一把鲜&#xff0c;最近有空会和小伙伴们慢慢聊聊 Spring Boot3 都给我们带来了哪些新东西。 今天我们就先…...

【寻人启事】达坦科技持续招人ing

​​​​​​​ ❤️一起来探索前沿科技&#xff0c;做有意思的事情~ 我们是谁 达坦科技&#xff08;DatenLord&#xff09;专注于打造新一代开源跨云存储平台。通过软硬件深度融合的方式打通云云壁垒&#xff0c;实现无限制跨云存储、跨云联通&#xff0c;建立海量异地、异构…...

【C/C++基础练习题】简单函数练习题

&#x1f349;内容专栏&#xff1a;【C/C要打好基础啊】 &#x1f349;本文内容&#xff1a;简单函数使用练习题&#xff08;复习之前写过的实验报告&#xff09; &#x1f349;本文作者&#xff1a;Melon西西 &#x1f349;发布时间 &#xff1a;2023.2.11 目录 1.给定某个年…...

【代码随想录训练营】【Day11】第五章|栈与队列|20. 有效的括号|1047. 删除字符串中的所有相邻重复项|150. 逆波兰表达式求值

20. 有效的括号 题目详细&#xff1a;LeetCode.20 由题可知&#xff0c;有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型的左括号。 那么&#xff0c;我们可以利用栈后进先出的特点&#x…...

基于云原生分布式存储ceph实现k8s数据持久化

文章目录1、初始化集群1.1 集群机器配置1.2 配置主机名1.3 配置hosts文件1.4、配置互信1.5、关闭防火墙1.6、关闭selinux1.7、配置Ceph安装源1.8、配置时间同步1.9、安装基础软件包2、安装ceph集群2.1 安装ceph-deploy2.2 创建monitor节点2.3 安装ceph-monitor2.4 部署osd服务2…...

SpringMVC获取请求参数

SpringMVC获取请求参数 通过ServletAPI获取 将HttpServletRequest作为控制器方法的形参&#xff0c;此时HttpServletRequest类型的参数表示封装了当前请求的报文对象。 RequestMapping("/testServletAPI") // request表示当前请求 public String testServletAPI(H…...

详解浏览器从输入URL到页面展示的过程

用户发出 URL 请求到页面开始解析的这个过程&#xff0c;就叫做导航。 1. 用户输入 当用户在地址栏中输入一个查询关键字时&#xff0c;地址栏会判断输入的关键字是搜索内容&#xff0c;还是请求的 URL。 当用户输入关键字并键入回车之后&#xff0c;这意味着当前页面即将要…...

【吉先生的Java全栈之路】

吉士先生Java全栈学习路线&#x1f9e1;第一阶段Java基础: 在第一阶段:我们要认真听讲,因为基础很重要!基础很重要!基础很重要!!! 重要的事情说三遍。在这里我们先学JavaSE路线&#xff1b;学完之后我们要去学第一个可视化组件编程《GUI》&#xff1b;然后写个《贪吃蛇》游戏耍…...

第二章 Opencv图像处理基本操作

目录1.读取图像1-1.imread()方法2.显示图像2-1.imshow()方法2-2.waitKey()方法2-3.destroyAllWindows()方法2-4.小总结3.保存图像3-1.imwrite()方法4.查看图像属性4-1.常见的三个图像属性1.读取图像 要对一幅图像进行处理&#xff0c;第一件事就是要读取这幅图像。 1-1.imread(…...

字节一面:在浏览器地址栏输入一个 URL 后回车,背后发生了什么?

近段时间&#xff0c;有小伙伴面试字节&#xff0c;说遇到一个面试题&#xff1a; 在浏览器地址栏输入一个 URL 后回车&#xff0c;背后发生了什么&#xff1f; 这里尼恩给大家做一下系统化、体系化的梳理&#xff0c;使得大家可以充分展示一下大家雄厚的 “技术肌肉”&#xf…...

推荐3dMax三维设计十大插件

3dMax是一款功能非常强大的三维设计软件&#xff0c;但无论它的功能多么强大&#xff0c;也不可能包含所有三维方面的功能&#xff0c;这时候&#xff0c;第三方插件可以很好的弥补和增强3dMax的基本功能&#xff0c;下面就给大家介绍十款非常不错的3dMax插件。 森林包&#xf…...

Arduino IDE 2.0.6中 ESP32开发环境搭建笔记

Arduino IDE 2.0.6中 ESP32开发环境搭建 Arduino IDE2.0 已上线一段时间&#xff0c;以后ESP32的学习转至新的IDE中 &#xff0c;需对开发环境进行。 Arduino IDE&#xff12;.&#xff10;与&#xff11;.&#xff10;有很大差异。原来环境搭建方法已完全不同。下文主要记录环…...

商品秒杀接口压测及优化

目录一、生成测试用户二、jmeter压测三、秒杀接口优化1、优化第一步&#xff1a;解决超卖2、优化第二步&#xff1a;Redis重复抢购3、优化第三步&#xff1a;Redis预减库存①商品初始化②预减库存一、生成测试用户 将UserUtils工具类导入到zmall-user模块中&#xff0c;运行生…...

NFC 项目前期准备工作

同学,别退出呀,我可是全网最牛逼的 WIFI/BT/GPS/NFC分析博主,我写了上百篇文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦。 了解项目信息,FAE联系方式,驱动源码等驱动合入内核配置DTS驱动设备节点验证Push nf…...

(C语言)数据的存储

问&#xff1a;1. 数据类型有哪五大类&#xff1f;2. 数据类型的作用是什么与什么&#xff1f;3. 整型又可以具体分为哪五个&#xff1f;为什么字符char也归属于整型&#xff1f;4. 浮点型又可以具体分为哪两类&#xff1f;5. 构造类型就是什么&#xff1f;具体分为哪四类&…...

C语言深度剖析之文件操作

&#x1f497; &#x1f497; 博客:小怡同学 &#x1f497; &#x1f497; 个人简介:编程小萌新 &#x1f497; &#x1f497; 如果博客对大家有用的话&#xff0c;请点赞关注加关注 &#x1f31e; 什么是文件 磁盘上的文件是文件。 但是在程序设计中&#xff0c;我们一般谈的文…...

RNN神经网络初探

目录1. 神经网络与未来智能2. 回顾数据维度和神经网络1. 神经网络与未来智能 2. 回顾数据维度和神经网络 循环神经网络&#xff0c;主要用来处理时序的数据&#xff0c;它对每个词的顺序是有要求的。 循环神经网络如何保存记忆功能&#xff1f; 当前样本只有 3 个特征&#x…...

【flinkx】【hdfs】【ing】Cannot obtain block length for LocatedBlock

一. 任务描述 使用flinkx去跑HDFS到HIVE的任务时&#xff0c;出现如下报错&#xff1a; CannotObtainBlockLengthException com.dtstack.flinkx.throwable.FlinkxRuntimeException: cant get file size from hdfs, file hdfs://xxx/.data/540240453caeb6fe4b3f118410a05315_2…...

【Day6】合并两个排序链表与合并k个已排序的链表,java代码实现

前言&#xff1a; 大家好&#xff0c;我是良辰丫&#x1f680;&#x1f680;&#x1f680;&#xff0c;今天与大家一起做两道牛客网的链表题&#xff0c;好久写关于链表题的博客了&#xff0c;这两道题可以帮大家巩固一下链表知识&#xff0c;我把两道题的链接放到下面&#xf…...

Swagger PHP

PHP使用Swagger生成好看的API文档不是不可能&#xff0c;而是非常简单。首先本人使用Laravel框架&#xff0c;所以在Laravel上安装swagger-php。一、安装swagger - phpcomposer require zircote/swagger-phpswagger-php提供了命令行工具&#xff0c;所以可以全局安装&#xff0…...

谷粒商城-品牌管理-JSR303数据校验

后端在处理前端传过来的数据时&#xff0c;尽管前端表单已经加了校验逻辑&#xff0c;但是作为严谨考虑&#xff0c;在后端对接口传输的数据做校验也必不可少。 开启校验&#xff1a; 实体类上增加校验注解&#xff0c;接口参数前增加Valid 开启校验 package com.xxh.product.…...

牡丹江网站制作/推广普通话的重要意义

性能监视 1.使用Tomcat自带的Manager监视 Free memory&#xff1a;剩余内存 Total memory&#xff1a;总内存 Max memory&#xff1a;最大内存 Max threads&#xff1a;最大线程数 Current thread count&#xff1a;当前线程数 Current thread busy&#xff1a;当前忙碌线程…...

爱心互助网站开发/南宁seo服务公司

RDBMS 12.2.0.1 在AWR中出现等待事件enq: RO - fast object reuse、enq: CR - block range reuse ckpt、log buffer space等。 分析这些等待事件&#xff0c;主要原因还是做了大量的drop 和truncate&#xff0c;引起了主要的等待事件enq: RO - fast object reuse&#xff0c;…...

wordpress 锚文点/贺贵江seo教程

题意&#xff1a;丑数就是质因子只有2&#xff0c;3&#xff0c;5 &#xff0c;7&#xff0c;的数&#xff0c;另外1也是丑数。求第n(1<n<5842)个丑数&#xff0c;n0&#xff0c;结束。 思路&#xff1a;根据丑数的定义&#xff0c;丑数应该是另一个丑数乘以2、3、5或者7…...

做网站首页图的规格/霸屏推广

我正在尝试找到进行n维表查找的最佳方法。在本例中&#xff0c;有一个dataframe&#xff0c;它包含一个人的状态和年份&#xff0c;我想通过在表(可以是数组、数据帧或字典)中查找相关税率来查找。首先&#xff0c;考虑通过一个数组来实现&#xff1a;nobs 4df DataFrame( { …...

wordpress实现选项卡/百度热词指数

主机发现 靶机 nmap扫描端口 扫描服务 -sT 说明用tcp协议&#xff08;三次握手&#xff09;扫描 -sV扫描版本 O扫描系统 UDP扫描 漏洞脚本扫描 web渗透 Squid代理分析 检索信息 可以判断是代理 3128端口与代理有关 对3128端口进行目录爆破 dirb爆破 goboster爆破 没法扫…...

php网站后台入口/凡科网站建设

为什么用 与平台无关,不需要直接调用,而是发消息到mq,解耦\异步 架构 启动...