11 - FFmpeg - 编码 AAC
Planar 模式是 ffmpeg内部存储模式,我们实际使用的音频文件都是Packed模式的。
FFmpeq解码不同格式的音频输出的音频采样格式不是一样。
其中AAC解码输出的数据为浮点型的 AV_SAMPLE_FMT_FLTP 格式,MP3 解码输出的数据为 AV_SAMPLE_FMT_S16P 格式(使用的mp3文件为16位深)。
具体采样格式可以査看解码后的 AVframe 中的 format 成员或解码器的AVCodecContext中的sample_fmt成员。
Planar或者Packed模式直接影响到保存文件时写文件的操作,操作数据的时候一定要先检测音频采样格式。
方法1
int encodeAudioInterface(AVCodecContext *encoderCtx, AVFrame *frame, AVPacket *packet, FILE *dest_fp)
{int ret = avcodec_send_frame(encoderCtx, frame);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "send frame to encoder failed:%s\n", av_err2str(ret));ret = -1;}while (ret >= 0){ret = avcodec_receive_packet(encoderCtx, packet);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){av_log(NULL, AV_LOG_WARNING, "[encodeAudioInterface] -- AVERROR(EAGAIN) || AVERROR_EOF \n");return 0;}else if (ret < 0){av_log(NULL, AV_LOG_ERROR, "encode frame failed:%s\n", av_err2str(ret));return -1;}fwrite(packet->data, 1, packet->size, dest_fp);av_packet_unref(packet);}return 0;
}
int encodeAudio(const char *inFileName, const char *outFileName)
{int ret = 0;/*****************************************************************************/FILE *src_fp = fopen(inFileName, "rb");if (src_fp == NULL){av_log(NULL, AV_LOG_ERROR, "open infile:%s failed!\n", inFileName);ret = -1;goto end;}FILE *dest_fp = fopen(outFileName, "wb+");if (dest_fp == NULL){av_log(NULL, AV_LOG_ERROR, "open outfile:%s failed!\n", outFileName);ret = -1;goto end;}/*****************************************************************************/AVFrame *frame = av_frame_alloc();frame->sample_rate = 48 * 1000; // 采样率 - 48Kframe->channels = 2;frame->channel_layout = AV_CH_LAYOUT_STEREO;frame->format = AV_SAMPLE_FMT_S16;frame->nb_samples = 1024;// libfdk_aacav_frame_get_buffer(frame, 0);AVCodec *encoder = avcodec_find_encoder_by_name("libfdk_aac");if (encoder == NULL){av_log(NULL, AV_LOG_ERROR, "find encoder failed!\n");ret = -1;goto end;}AVCodecContext *encoderCtx = avcodec_alloc_context3(encoder);if (encoderCtx == NULL){av_log(NULL, AV_LOG_ERROR, "alloc encoder context failed!\n");ret = -1;goto end;}encoderCtx->sample_fmt = frame->format;encoderCtx->sample_rate = frame->sample_rate;encoderCtx->channels = frame->channels;encoderCtx->channel_layout = frame->channel_layout;ret = avcodec_open2(encoderCtx, encoder, NULL);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "open encoder failed:%s\n", av_err2str(ret));goto end;}AVPacket packet;av_init_packet(&packet);while (1){// packet L R L R// 2 * 2 * 1024 = 4096int readSize = fread(frame->data[0], 1, frame->linesize[0], src_fp);if (readSize == 0){av_log(NULL, AV_LOG_INFO, "finish read infile!\n");break;}encodeAudioInterface(encoderCtx, frame, &packet, dest_fp);}encodeAudioInterface(encoderCtx, NULL, &packet, dest_fp);end:if (frame){av_frame_free(&frame);}if (encoderCtx){avcodec_free_context(&encoderCtx);return ret;}if (src_fp){fclose(src_fp);}if (dest_fp){fclose(dest_fp);}
}
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
方法 2
int CheckSampleRate(const AVCodec *encoder, const int SampleRate)
{// encoder->supported_samplerates 支持的音频采样数组,如果未知则为NULL,数组以0结尾const int *SupportSampleRate = encoder->supported_samplerates;while (*SupportSampleRate != 0){av_log(NULL, AV_LOG_DEBUG, "[%s] encoder->name: %s, support %d hz -- line:%d\n", __FUNCTION__, encoder->name, *SupportSampleRate, __LINE__); // 受 frame->format等参数影响if (*SupportSampleRate == SampleRate){av_log(NULL, AV_LOG_INFO, "[%s] This sampling rate is supported by the encoder %d hz -- line:%d\n", __FUNCTION__, *SupportSampleRate, __LINE__); // 受 frame->format等参数影响return 1;}SupportSampleRate++;}return 0;
}
int CheckChannelLayout(const AVCodec *encoder, const uint64_t ChannelLayout)
{// 支持通道布局的数组,如果未知则为NULL。数组以0结尾const uint64_t *SupportsChannelLayout = encoder->channel_layouts;if (!SupportsChannelLayout){ // 不是每个AVCodec都给出支持的channel_layoutav_log(NULL, AV_LOG_WARNING, "[%s] the encoder %s no set channel_layouts -- line:%d\n", __FUNCTION__, encoder->name, __LINE__);return 1;}while (*SupportsChannelLayout != 0){av_log(NULL, AV_LOG_DEBUG, "[%s] encoder->name: %s, support channel_layout %ld -- line:%d\n", __FUNCTION__, encoder->name, *SupportsChannelLayout, __LINE__); // 受 frame->format等参数影响if (*SupportsChannelLayout == ChannelLayout){av_log(NULL, AV_LOG_INFO, "[%s] This channel layout is supported by the encoder %d -- line:%d\n", __FUNCTION__, *SupportsChannelLayout, __LINE__); // 受 frame->format等参数影响return 1;}*SupportsChannelLayout++;}return 0;
}
int CheckSampleFmt(const AVCodec *codecCtx, enum AVSampleFormat SampleFmt)
{ // 数组支持的样例格式,如果未知则为NULL,数组以-1结尾const enum AVSampleFormat *SampleFmts = codecCtx->sample_fmts;while (*SampleFmts != AV_SAMPLE_FMT_NONE) // 通过 AV_SAMPLE_FMT_NONE 作为结束{if (*SampleFmts == SampleFmt){return 1;}*SampleFmts++;}return 0;
}
void GetAdtsHeader(AVCodecContext *codecCtx, uint8_t *adtsHeader, int aacLength)
{uint8_t freqIdx = 0; // 0: 96000HZ 3:48000Hz 4:44100Hzswitch (codecCtx->sample_rate){case 96000:freqIdx = 0;break;case 88200:freqIdx = 1;break;case 64000:freqIdx = 2;break;case 48000:freqIdx = 3;break;case 44100:freqIdx = 4;break;case 32000:freqIdx = 5;break;case 24000:freqIdx = 6;break;case 22050:freqIdx = 7;break;case 16000:freqIdx = 8;break;case 12000:freqIdx = 9;break;case 11025:freqIdx = 10;break;case 8000:freqIdx = 11;break;case 7350:freqIdx = 12;break;default:freqIdx = 4;break;}uint8_t chanCfg = codecCtx->channels;uint32_t frameLength = aacLength + 7;adtsHeader[0] = 0xff;adtsHeader[1] = 0xF1;adtsHeader[2] = ((codecCtx->profile) << 6) + (freqIdx << 2) + (chanCfg >> 2);adtsHeader[3] = (((chanCfg & 3) << 6) + (frameLength >> 11));adtsHeader[4] = ((frameLength & 0x7FF) >> 3);adtsHeader[5] = (((frameLength & 7) << 5) + 0x1F);adtsHeader[6] = 0xFC;
}
int decodeAudioInterface(AVCodecContext *codecCtx, AVFrame *frame, AVPacket *pkt, FILE *output)
{int ret = avcodec_send_frame(codecCtx, frame);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "[%s] sending the frame to the encoder error! -- line:%d\n", __FUNCTION__, __LINE__);return -1;}// 编码和解码都是一样的,都是send 1次,然后 receive 多次,直到AVERROR(EAGAIN)或者AVERROR_EOFwhile (ret >= 0){ret = avcodec_receive_packet(codecCtx, pkt);if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){return 0;}else if (ret < 0){av_log(NULL, AV_LOG_ERROR, "[%s] encoding audio frameerror! -- line:%d\n", __FUNCTION__, __LINE__);return -1;}uint8_t aacHeader[7];GetAdtsHeader(codecCtx, aacHeader, pkt->size);size_t len = fwrite(aacHeader, 1, 7, output);if (len != 7){av_log(NULL, AV_LOG_ERROR, "[%s] fwrite aac_header failed! -- line:%d\n", __FUNCTION__, __LINE__);return -1;}len = fwrite(pkt->data, 1, pkt->size, output);if (len != pkt->size){av_log(NULL, AV_LOG_ERROR, "[%s] fwrite aac data failed! -- line:%d\n", __FUNCTION__, __LINE__);return -1;}}return -1;
}
void f32leConvert2fltp(float *f32le, float *fltp, int nb_samples)
{float *fltp_l = fltp; // 左通道float *fltp_r = fltp + nb_samples; // 右声道for (int i = 0; i < nb_samples; i++){fltp_l[i] = f32le[i * 2]; // 1 0 - 2 3fltp_r[i] = f32le[i * 2 + 1]; // 可以尝试注释左声道或者右声道听听声音}
}
int decodeAudio(const char *pcmFileName, const char *aacFileName, const char *encoderName)
{FILE *pcmfile = fopen(pcmFileName, "rb");FILE *aacfile = fopen(aacFileName, "wb");if (pcmfile == NULL || aacfile == NULL){av_log(NULL, AV_LOG_ERROR, "[%s] open %s or %s file failed -- line:%d \n", __FUNCTION__, aacFileName, pcmFileName, __LINE__);goto _end;}const AVCodec *encoder = NULL;if (encoderName != NULL && (strcmp(encoderName, "libfdk_aac") == 0 || strcmp(encoderName, "aac") == 0)) // encoderName 如果制定了编码器{encoder = avcodec_find_encoder_by_name(encoderName); // 设置为指定编码器av_log(NULL, AV_LOG_INFO, "[%s] force codec name: %s -- line:%d\n", __FUNCTION__, encoderName, __LINE__);}else{encoder = avcodec_find_encoder(AV_CODEC_ID_AAC);av_log(NULL, AV_LOG_INFO, "[%s] default codec name: %s -- line:%d\n", __FUNCTION__, "aac", __LINE__);}if (encoder == NULL){av_log(NULL, AV_LOG_ERROR, "[%s] Codec found error! -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}// 创建编码器上下文AVCodecContext *codecCtx = avcodec_alloc_context3(encoder);if (codecCtx == NULL){av_log(NULL, AV_LOG_ERROR, "[%s] Conld not allocate audio codec context -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}codecCtx->codec_id = AV_CODEC_ID_AAC;codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;codecCtx->bit_rate = 128 * 1024;codecCtx->channel_layout = AV_CH_LAYOUT_STEREO;codecCtx->sample_rate = 48000;codecCtx->channels = av_get_channel_layout_nb_channels(codecCtx->channel_layout);codecCtx->profile = FF_PROFILE_AAC_LOW;if (strcmp(encoder->name, "libfdk_aac") == 0){codecCtx->sample_fmt = AV_SAMPLE_FMT_S16;}else{codecCtx->sample_fmt = AV_SAMPLE_FMT_FLTP;}// 检测采样格式的支持情况if (!CheckSampleFmt(encoder, codecCtx->sample_fmt)){av_log(NULL, AV_LOG_ERROR, "[%s] Encoder does not support sample format %s -- line:%d\n", __FUNCTION__, av_get_sample_fmt_name(codecCtx->sample_fmt), __LINE__);goto _end;}if (!CheckSampleRate(encoder, codecCtx->sample_rate)){av_log(NULL, AV_LOG_ERROR, "[%s] Encoder does not support sample rate codecCtx->sample_rate:%d -- line:%d\n", __FUNCTION__, codecCtx->sample_rate, __LINE__);goto _end;}if (!CheckChannelLayout(encoder, codecCtx->channel_layout)){av_log(NULL, AV_LOG_ERROR, "[%s] Encoder does not support sample channel_layout %lu -- line:%d\n", __FUNCTION__, codecCtx->channel_layout, __LINE__);goto _end;}av_log(NULL, AV_LOG_INFO, "\n[%s] ------------------------ Audio encode config ------------------------ line:%d \n", __FUNCTION__, __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] codecCtx->bit_rate: %ld kbps -- line:%d\n", __FUNCTION__, codecCtx->bit_rate / 1024, __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] codecCtx->sample_rate: %d -- line:%d\n", __FUNCTION__, codecCtx->sample_rate, __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] codecCtx->sample_fmt: %s -- line:%d\n", __FUNCTION__, av_get_sample_fmt_name(codecCtx->sample_fmt), __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] codecCtx->channels: %d -- line:%d\n", __FUNCTION__, codecCtx->channels, __LINE__);// frame_size 是在 av_coedc_open2后进行关联av_log(NULL, AV_LOG_INFO, "[%s] Before frame size %d -- line:%d\n", __FUNCTION__, codecCtx->frame_size, __LINE__);if (avcodec_open2(codecCtx, encoder, NULL) < 0){av_log(NULL, AV_LOG_ERROR, "[%s] Could not open codec -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}av_log(NULL, AV_LOG_INFO, "[%s] Once frame_size %d -- line:%d\n\n", __FUNCTION__, codecCtx->frame_size, __LINE__); // 决定每次送多少个采样点AVPacket *packet = av_packet_alloc();if (!packet){av_log(NULL, AV_LOG_ERROR, "[%s] packet alloc error! -- line:%d \n", __FUNCTION__, __LINE__);goto _end;}AVFrame *frame = av_frame_alloc();if (!frame){av_log(NULL, AV_LOG_ERROR, "[%s] Could not allocate audio frame -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}frame->nb_samples = codecCtx->frame_size;frame->format = codecCtx->sample_fmt;frame->channel_layout = codecCtx->channel_layout;frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout);av_log(NULL, AV_LOG_INFO, "[%s] frame nb_samples: %d -- line:%d\n", __FUNCTION__, frame->nb_samples, __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] frame sample_fmt: %s -- line:%d\n", __FUNCTION__, av_get_sample_fmt_name(frame->format), __LINE__);av_log(NULL, AV_LOG_INFO, "[%s] frame channel_layout: %lu -- line:%d\n", __FUNCTION__, frame->channel_layout, __LINE__);// 为frame分配bufferint ret = av_frame_get_buffer(frame, 0);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "[%s] Could not allocate audio data buffers -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}// 计算出每一帧的数据 单个采样点的字节 * 通道数目 * 每帧采样点的数量size_t FrameByteSize = av_get_bytes_per_sample(frame->format) * frame->channels * frame->nb_samples;av_log(NULL, AV_LOG_INFO, "[%s] frame_bytes %ld frame->channels %d frame->nb_samples %d -- line:%d\n", __FUNCTION__, FrameByteSize, frame->channels, frame->nb_samples, __LINE__);uint8_t *pcmBuf = (uint8_t *)malloc(FrameByteSize);uint8_t *pcmBufTemp = (uint8_t *)malloc(FrameByteSize);if (!pcmBuf || !pcmBufTemp){av_log(NULL, AV_LOG_ERROR, "[%s] pcmBuf or pcmBufTemp malloc failed -- line:%d\n", __FUNCTION__, __LINE__);goto _end;}memset(pcmBuf, 0, FrameByteSize);memset(pcmBufTemp, 0, FrameByteSize);int64_t pts = 0;av_log(NULL, AV_LOG_INFO, "\n[%s] ------------------------ start enode ------------------------ line:%d \n", __FUNCTION__, __LINE__);while (1){memset(pcmBuf, 0, FrameByteSize);size_t ReadByteSize = fread(pcmBuf, 1, FrameByteSize, pcmfile);if (ReadByteSize <= 0){av_log(NULL, AV_LOG_INFO, "[%s] read file finish -- line:%d \n", __FUNCTION__, __LINE__);break;}/*确保该 frame 可写, 如果编码器内部保持了内存参数计数,则需要重新拷贝一个备份目的是新写入的数据和编码器保存的数据不能产生冲突*/ret = av_frame_make_writable(frame);if (ret != 0){av_log(NULL, AV_LOG_ERROR, "[%s] av_frame_make_writable failed!!! -- line:%d\n", __FUNCTION__, __LINE__);}if (AV_SAMPLE_FMT_S16 == frame->format){// 将读取到的PCM数据填充到frame去,但是要注意匹配格式,(planner | packet )ret = av_samples_fill_arrays(frame->data, frame->linesize, pcmBuf, frame->channels, frame->nb_samples, frame->format, 0);}else{// 将读取到的PCM数据填充到frame去,但是要注意匹配格式,(planner | packet )// 将本地的f32le packed 模式的数据转为 float palannermemset(pcmBufTemp, 0, FrameByteSize);f32leConvert2fltp((float *)pcmBuf, (float *)pcmBufTemp, frame->nb_samples);ret = av_samples_fill_arrays(frame->data, frame->linesize, pcmBufTemp, frame->channels, frame->nb_samples, frame->format, 0);}// 设置 ptspts += frame->nb_samples;frame->pts = pts; // 使用采样率作为pts的单位,具体换算成秒 pts*1/采样率ret = decodeAudioInterface(codecCtx, frame, packet, aacfile);if (ret < 0){av_log(NULL, AV_LOG_ERROR, "[%s] encode failed -- line:%d\n", __FUNCTION__, __LINE__);break;}}/*冲刷编码器*/decodeAudioInterface(codecCtx, NULL, packet, aacfile);
_end:if (aacfile){fclose(aacfile);}if (pcmfile){fclose(pcmfile);}if (pcmBuf){free(pcmBuf);}if (pcmBufTemp){free(pcmBufTemp);}if (packet){av_packet_free(&packet);}if (frame){av_frame_free(&frame);}if (codecCtx){avcodec_free_context(&codecCtx);}return ret;
}
对于 flush encoder 的操作:
编码器通常的冲洗方法:调用一次 avcodec_send_frame(NULL)(返回成功),
然后不停调用 avcodec_receive_packet() 直到其返回 AVERROR_EOF,取出所有缓存帧,
avcodec_receive_packet() 返回 AVERROR EOF 这一次是没有有效数据的,仅仅获取到一个结束标志
相关文章:
11 - FFmpeg - 编码 AAC
Planar 模式是 ffmpeg内部存储模式,我们实际使用的音频文件都是Packed模式的。 FFmpeq解码不同格式的音频输出的音频采样格式不是一样。 其中AAC解码输出的数据为浮点型的 AV_SAMPLE_FMT_FLTP 格式,MP3 解码输出的数据为 AV_SAMPLE_FMT_S16P 格式(使用的…...

OS Copilot初体验的感受与心得
本文介绍体验操作系统智能助手OS Copilot后,个人的一些收获、体验等。 最近,抽空体验了阿里云的操作系统智能助手OS Copilot,在这里记录一下心得与收获。总体观之,从个人角度来说,感觉这个OS Copilot确实抓住了不少开发…...
Ajax学习笔记
文章目录标题 Ajax学习笔记axios使用axios请求拦截器axios响应拦截器优化axios响应结果 form-serialize插件图片上传HTTP协议请求报文相应报文接口文档 AJAX原理 - XMLHttpRequest使用XMLHttpRequestXMLHttpRequest - 查询参数查询字符串对象 XMLHttpRequest - 数据提交 事件循…...
医学深度学习与机器学习融合的随想
医学深度学习与机器学习融合的随想 近年来,深度学习(图像类)和机器学习在医学领域的应用取得了飞速发展,为医学影像分析、疾病诊断和预后预测等领域带来了革命性的变革。深度学习擅长从复杂数据中提取高层次特征,而机…...
坑人的macos tar 命令 (实际上是bsdtar)换用 gnu tar
周末 看着笔记本上好用的朗文当代高级词典(mac版)和其它两部词典,准备复制到黑苹果台式机上去。考虑到词典内容有太多小文件,普通复制传输太慢,毫无疑问用 tar 打包肯定快而且能保留原始文件的各种信息。命令如下: time tar czf …...

【SpringBoot3】全局异常处理
【SpringBoot3】全局异常处理 一、全局异常处理器step1:创建收入数字的页面step2:创建控制器,计算两个整数相除step3:创建自定义异常处理器step5:创建给用提示的页面step6:测试输入(10/0) 二、BeanValidato…...
vue-Treeselect
一、Node KeyTypeDescriptionid (required)Number | String用于标识树中的选项。其值在所有选项中必须是唯一的label (required)String用于显示选项childrennode[] | null声明一个分支节点。你可以: 1) 设置为由a组成的子选项数组。叶节点,b…...
【机器学习框架TensorFlow和PyTorch】基本使用指南
机器学习框架TensorFlow和PyTorch:基本使用指南 目录 引言TensorFlow概述 TensorFlow简介TensorFlow的基本使用 PyTorch概述 PyTorch简介PyTorch的基本使用 TensorFlow和PyTorch的对比结论 引言 随着深度学习的快速发展,机器学习框架在实际应用中起到…...
matlab 中的methods(Access = protected) 是什么意思
gpt版本 在 MATLAB 中,methods 是用于定义类方法的一部分。(Access protected) 是一种访问控制修饰符,它限制了方法的访问权限。具体来说,当你在类定义中使用 methods(Access protected) 时,你是在定义只有类本身及其子类可以访…...

【漏洞复现】Netgear WN604 downloadFile.php 信息泄露漏洞(CVE-2024-6646)
0x01 产品简介 NETGEAR WN604是一款由NETGEAR(网件)公司生产的无线接入器(或无线路由器)提供Wi-Fi保护协议(WPA2-PSK, WPA-PSK),以及有线等效加密(WEP)64位、128位和152…...
图像处理 -- ISP调优(tuning)的步骤整理
ISP调优流程培训文档 1. 硬件准备 选择合适的图像传感器:根据项目需求选择合适的传感器型号。搭建测试环境:包括测试板、光源、色彩卡和分辨率卡等。 2. 初始设置 寄存器配置:初始化传感器的寄存器设置,包括曝光、增益、白平衡…...

【中项】系统集成项目管理工程师-第4章 信息系统架构-4.2系统架构
前言:系统集成项目管理工程师专业,现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试,全称为“全国计算机与软件专业技术资格(水平)考试”&…...

node.js中nodemon : 无法加载和使用问题,这是由于windows安全策略影起的按如下操作即可
1、用管理员权限打开vscode 2、文件终端中打开,输入 Set-ExecutionPolicy -Scope CurrentUser 3、再输入RemoteSigned 4、使用get-ExecutionPolicy查看权限,可以看到变为了RemoteSigned 重启问题解决...

【SD】 Stable Diffusion(SD)原理详解与ComfyUI使用 2
Stable Diffusion(SD)原理详解与ComfyUI使用 Stable Diffusion(SD)原理详解与ComfyUI使用1. SD整体结构2. Clip(文本编码器)3. Unit(生成模型)4. VAE(变分自编码器&#…...

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(七)-广播远程识别码(Broadcast Remote ID)
目录 引言 5.5 广播远程识别码(Broadcast Remote ID) 5.5.1 使用PC5的广播远程识别码 5.5.2 使用MBS的广播远程识别码 引言 3GPP TS 23.256 技术规范,主要定义了3GPP系统对无人机(UAV)的连接性、身份识别、跟踪及…...
VMware 虚拟机 ping 不通原因排查
目录 一、检查网络 二、重启虚拟机网络 因为最近遇到了一个比较奇怪的 ping 不通虚拟机的事,在此过程中,检查了很多的设置,故而写一篇文章记录下,如有 VMware 虚拟机 ping 不通可以尝试本文的排查方式。 下面以 VMware 虚拟机为…...

websocket状态机
websocket突破了HTTP协议单向性的缺陷,基于HTTP协议构建了双向通信的通道,使服务端可以主动推送数据到前端,解决了前端不断轮询后台才能获取后端数据的问题,所以在小程序和H5应用中被广泛使用。本文主要集合报文分析对于websocket…...

JCR一区级 | Matlab实现CPO-Transformer-LSTM多变量回归预测【2024新算法】
JCR一区级 | Matlab实现CPO-Transformer-LSTM多变量回归预测【2024新算法】 目录 JCR一区级 | Matlab实现CPO-Transformer-LSTM多变量回归预测【2024新算法】效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.【JCR一区级】Matlab实现CPO-Transformer-LSTM多变量回归预测…...

力扣3226 使两个整数相等的位更改次数
写的代码: class Solution { public:string cc(int num){string res"";while(num>0){int rnum % 2;resstatic_cast<char>(48r)res;num/2;}return res;}int minChanges(int n, int k) {int res0;string n2cc(n);string k2cc(k);int n_sizen2.siz…...

VLAN 划分案例详解
vlan 的应用在网络项目中是非常广泛的,基本上大部分的项目都需要划分 vlan,这里从基础的 vlan 的知识开始,了解 vlan 的划分原理。 为什么需要 vlan: 1、什么是 VLAN? VLAN(Virtual LAN)&…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造,完美适配AGV和无人叉车。同时,集成以太网与语音合成技术,为各类高级系统(如MES、调度系统、库位管理、立库等)提供高效便捷的语音交互体验。 L…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...