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

ffmpeg+D3D实现的MFC音视频播放器,支持录像、截图、音视频播放、码流信息显示等功能

一、简介

    本播放器是在vs2019下开发,通过ffmpeg实现拉流解码功能,通过D3D实现视频的渲染功能。截图功能采用libjpeg实现,可以截取jpg图片,图片的默认保存路径是在C:\MYRecPath中。录像功能采用封装好的类Mp4Record实现,在Mp4Record类中主要还是采用ffmpeg的相关函数方法进行mp4视频的录制。音频的播放采用DirectSound实现,将ffmpeg解码后的音频数据存储到DirectSound的buffer中,再调用DirectSound的play实现对音频的播放功能。码流信息的显示,通过D3D的文本绘制实现。本播放器提供源码下载,直接下载请点击最后的下载链接。

二、界面展示

在这里插入图片描述

三、相关代码

开始播放

int CVideoPlayer::StartPlay(const char* sUrl)
{m_bStop = false;m_nVideoIndex = -1;m_nAudioIndex = -1;int i = 0, res = 0,  nValue = 0;char buf[64] = { 0 };m_bPlaying = false;AVStream* in_stream;_snprintf_s(m_sConnectUrl, sizeof(m_sConnectUrl), sizeof(m_sConnectUrl) - 1, "%s", sUrl);//av_register_all();avformat_network_init();AVDictionary* optionsDict = nullptr;av_dict_set(&optionsDict, "rtsp_transport", "tcp", 0);av_dict_set(&optionsDict, "stimeout", "5000000", 0);av_dict_set(&optionsDict, "buffer_size", "8192000", 0);av_dict_set(&optionsDict, "recv_buffer_size", "8192000", 0);m_lastReadPacktTime = av_gettime();m_pAVFmtCxt = avformat_alloc_context();m_pAVFmtCxt->interrupt_callback.opaque = this;m_pAVFmtCxt->interrupt_callback.callback = decodeInterruptCb;res = avformat_open_input(&m_pAVFmtCxt, m_sConnectUrl, NULL, &optionsDict);if (res < 0){myprint("avformat_open_input fail: %d", res);return -1;}if (!m_pAVFmtCxt){return -1;}m_pAVFmtCxt->probesize = 100 * 1024;    m_pAVFmtCxt->max_analyze_duration = 1 * AV_TIME_BASE; res = avformat_find_stream_info(m_pAVFmtCxt, NULL);if (res < 0){myprint("error %x in avformat_find_stream_info\n", res);return -1;}av_dump_format(m_pAVFmtCxt, 0, m_sConnectUrl, 0);for (i = 0; i < m_pAVFmtCxt->nb_streams; i++){if (m_pAVFmtCxt->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){m_nVideoIndex = i;}else if (m_pAVFmtCxt->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {m_nAudioIndex = i;}myprint("m_pAVFmtCxt->streams[i]->codec->codec_type:%d", m_pAVFmtCxt->streams[i]->codecpar->codec_type);}//videoindex not findif (m_nVideoIndex == -1){myprint("can't find video stream.");return -1;}m_pCodec = avcodec_find_decoder(m_pAVFmtCxt->streams[m_nVideoIndex]->codecpar->codec_id);if (!m_pCodec){myprint("video decoder not found\n");return -1;}if (m_bSupportAudio && m_nAudioIndex != -1){myprint("start audio decoder \n");if (!m_pAudioCodecCxt)m_pAudioCodecCxt = avcodec_alloc_context3(NULL);auto pAudioCodecpar = m_pAVFmtCxt->streams[m_nAudioIndex]->codecpar;avcodec_parameters_to_context(m_pAudioCodecCxt, pAudioCodecpar);m_pAudioCodec = avcodec_find_decoder(pAudioCodecpar->codec_id);if (nullptr == m_pAudioCodec || nullptr == m_pAudioCodecCxt){myprint("audio decoder not found\n");return -1;}m_pSwrContext = swr_alloc_set_opts(0,                                 av_get_default_channel_layout(m_channels_play),AV_SAMPLE_FMT_S16,                         m_nSampleRate,                     av_get_default_channel_layout(m_pAudioCodecCxt->channels),m_pAudioCodecCxt->sample_fmt,       m_pAudioCodecCxt->sample_rate,      0,0);auto ret = swr_init(m_pSwrContext);if (ret < 0){myprint("Failed to swr_init(pSwrContext);");return -1;}if (InitDirectSound() == FALSE)m_bSupportAudio = false;}m_CodecId = m_pCodec->id;if(!m_pCodecCxt)m_pCodecCxt = avcodec_alloc_context3(NULL);avcodec_parameters_to_context(m_pCodecCxt, m_pAVFmtCxt->streams[m_nVideoIndex]->codecpar);if (m_pCodecCxt){if (m_pCodecCxt->width == 0 || m_pCodecCxt->height == 0){myprint("m_pCodecCxt->width:%d, m_pCodecCxt->height:%d", m_pCodecCxt->width, m_pCodecCxt->height);return -1;}}elsereturn -1;AVCodecContext* temp_codecctx = m_pCodecCxt;memcpy(temp_codecctx, m_pCodecCxt, sizeof(m_pCodecCxt));if (m_pCodecCxt->codec_type == AVMEDIA_TYPE_VIDEO){myprint("Soft Solution");avcodec_close(m_pCodecCxt);m_pCodecCxt = temp_codecctx;m_pCodecCxt->thread_count = 4;if (m_Dxva2D3DRender.InitD3DRender(m_showWnd, m_pCodecCxt->width, m_pCodecCxt->height) == false){myprint("InitD3DRender fail");}m_pOutBuffer = (uint8_t*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_YUV420P, m_pCodecCxt->width, m_pCodecCxt->height, 1));if (nullptr == m_pOutBuffer)return -1;av_image_fill_arrays(m_pFrameBGR->data, m_pFrameBGR->linesize, m_pOutBuffer, AV_PIX_FMT_YUV420P, m_pCodecCxt->width, m_pCodecCxt->height, 1); //填充AVFrame数据缓冲m_pImgConvertCtx = sws_getContext(m_pCodecCxt->width, m_pCodecCxt->height, m_pCodecCxt->pix_fmt, m_pCodecCxt->width, m_pCodecCxt->height, AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, NULL, NULL, NULL);if (nullptr == m_pImgConvertCtx)return -1;m_nActualWidth = m_pCodecCxt->width;m_nActualHeight = m_pCodecCxt->height;res = avcodec_open2(m_pCodecCxt, m_pCodec, NULL);if (res < 0){myprint("avcodec_open2 video fail  error:%x", res);return -1;}}if (m_bSupportAudio && m_pAudioCodecCxt){if (m_pAudioCodecCxt->codec_type == AVMEDIA_TYPE_AUDIO){res = avcodec_open2(m_pAudioCodecCxt, m_pAudioCodec, NULL);if (res < 0){myprint("avcodec_open2 audio fail  error:%x", res);avcodec_close(m_pAudioCodecCxt);return -1;}myprint("===Audio Message===");myprint(" bit_rate = %d ", m_pAudioCodecCxt->bit_rate);myprint(" sample_rate = %d ", m_pAudioCodecCxt->sample_rate);myprint(" channels = %d ", m_pAudioCodecCxt->channels);myprint(" code_name = %s ", m_pAudioCodecCxt->codec->name);myprint(" block_align = %d ", m_pAudioCodecCxt->block_align);}}m_pDecodeThread = (my_thread_t*)my_malloc(sizeof(my_thread_t));if (nullptr != m_pDecodeThread){m_bDecodeThreadRun = true;res = my_thread_create(m_pDecodeThread, ThreadDecode, this);if (res == -1){myprint("my_thread_create ThreadDecode failed  res:%x", res);return -1;}}return 0;
}

停止播放

void CVideoPlayer::StopPlay()
{m_bPlaying = false;m_CaptureAudio.SetGrabAudioFrames(FALSE, NULL);m_CaptureAudio.Close();m_bStopAudio = true;while (!m_AudioPlayQue.empty()){m_AudioPlayQue.pop();}while (!m_AudioTalkQue.empty()){EnterCriticalSection(&m_talklock);m_AudioTalkQue.pop();LeaveCriticalSection(&m_talklock);}m_bDecodeThreadRun = false;if (m_pDecodeThread){my_thread_join(m_pDecodeThread);my_free(m_pDecodeThread);m_pDecodeThread = nullptr;}if (m_pAudioPlayThread) {SetEvent(m_event);if (m_pAudioPlayThread->handle) {my_thread_join(m_pAudioPlayThread);m_pAudioPlayThread->handle = nullptr;}}if (m_pDSBuffer8){m_pDSBuffer8->Stop();m_pDSBuffer8->Restore();}m_Dxva2D3DRender.UnitD3DRender();if (m_pCodecCxt){avcodec_close(m_pCodecCxt);}if (m_pAudioCodecCxt){avcodec_close(m_pAudioCodecCxt);}if (m_pSwrContext){swr_free(&m_pSwrContext);m_pSwrContext = nullptr;}if (m_pAVFmtCxt) {avformat_close_input(&m_pAVFmtCxt);avformat_free_context(m_pAVFmtCxt);m_pAVFmtCxt = nullptr;}}

解码线程

void CVideoPlayer::DecodeAndShow()
{if (m_pAVFmtCxt == nullptr || m_pCodecCxt == nullptr)return;AVPacket pkt = { 0 };m_bPlaying = true;uint8_t* pBuffer;bool bEnoughSpace = true;int nTimeCnt = 0;int res = 0;struct SwsContext* img_convert_ctx = nullptr;int nRectDrawWait = 0;bool bRecordLastIFrame = false;int num_av_read_frame_err = 0;int num_stream_index_err = 0;uint8_t * outData[2] = {0};outData[0] = (uint8_t*)av_malloc(1152 * 8);outData[1] = (uint8_t*)av_malloc(1152 * 8);uint8_t* pktdata;int pktsize;int len = 0;bool bPushAudioToQueue = false;m_bStopAudio = false;CRect ShowRect;AVFrame* pAvFrame = av_frame_alloc();if (nullptr == pAvFrame)return;AVFrame* pFrameRGB = av_frame_alloc();if (nullptr == pFrameRGB)return;int numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, m_pCodecCxt->width, m_pCodecCxt->height, 1);pBuffer = (uint8_t*)av_malloc(numBytes);if (nullptr == pBuffer)return;av_image_fill_arrays(pFrameRGB->data,pFrameRGB->linesize, pBuffer, AV_PIX_FMT_RGB24, m_pCodecCxt->width, m_pCodecCxt->height, 1);img_convert_ctx = sws_getCachedContext(img_convert_ctx, m_pCodecCxt->width, m_pCodecCxt->height,m_pCodecCxt->pix_fmt, m_pCodecCxt->width, m_pCodecCxt->height, AV_PIX_FMT_RGB24, SWS_FAST_BILINEAR/*SWS_BICUBIC*/, NULL, NULL, NULL);//Audioif (m_bSupportAudio && m_pAudioPlayThread){res = my_thread_create(m_pAudioPlayThread, ThreadAudioPlay, this);if (res < 0)myprint("my_thread_create ThreadAudioPlay fail");}while (m_bDecodeThreadRun && !m_bQuit){if (m_bPause){Sleep(100);continue;}{if (m_bReconnect){myprint("bReConnect = true, break");break;}}m_lastReadPacktTime = av_gettime();if (av_read_frame(m_pAVFmtCxt, &pkt) >= 0){num_av_read_frame_err = 0;if (pkt.stream_index == m_nVideoIndex || pkt.stream_index == m_nAudioIndex){if (m_bRecord)//Record{if (nTimeCnt != 0 || (!bRecordLastIFrame && pkt.flags == AV_PKT_FLAG_KEY)) {if (m_sRecPath[0] != '\0' && nTimeCnt++ % 200 == 0){bEnoughSpace = CheckRemainSpace(m_sRecPath);if (bEnoughSpace == true){myprint("bEnoughSpace = true");}elsemyprint("bEnoughSpace = false");}m_nRecordCurrentTime = time(NULL);if ((m_nRecordCurrentTime - m_nRecordStartTime) >= (m_nRecordTime * 60)){myprint("Record Finsh!");stopRecord();}else if (bEnoughSpace == false){myprint("bEnoughSpace == false");stopRecord();}else{AVPacket* pPkt = av_packet_clone(&pkt);m_mp4Recorder.saveOneFrame(*pPkt, m_CodecId);av_packet_free(&pPkt);}}bRecordLastIFrame = pkt.flags == AV_PKT_FLAG_KEY;}elsenTimeCnt = 0;}if (pkt.stream_index == m_nVideoIndex){num_stream_index_err = 0;nTimeCnt = 0;if (pkt.flags == 1)bPushAudioToQueue = true;if (nullptr == m_pCodecCxt || nullptr == pAvFrame) {myprint("m_pCodecCxt == NULL || pAvFrame == NULL");break;}int gotvframe = 0;auto sd_ret = avcodec_send_packet(m_pCodecCxt, &pkt);if (sd_ret != 0 && sd_ret != AVERROR(EAGAIN)) {myprint("avcodec_send_packet err, rt=%d", sd_ret);enableReConnect();}else {while (gotvframe == 0 && !m_bQuit) {gotvframe = avcodec_receive_frame(m_pCodecCxt, pAvFrame);if (gotvframe == 0){try{GetShowRectSize(&ShowRect);}catch (const std::exception&){myprint("GetClientRect throw, error");break;}m_nCurPKSize = pkt.size;   SetStreamInfoToD3d();if (pAvFrame->width != m_nActualWidth || pAvFrame->height != m_nActualHeight){myprint("video size change reconnect...");enableReConnect();m_nActualWidth = pAvFrame->width;m_nActualHeight = pAvFrame->height;av_packet_unref(&pkt);continue;}if (m_pImgConvertCtx && m_pFrameBGR && m_pOutBuffer && pAvFrame){sws_scale(m_pImgConvertCtx, (const uint8_t* const*)pAvFrame->data, pAvFrame->linesize, 0,m_pCodecCxt->height, m_pFrameBGR->data, m_pFrameBGR->linesize);{                                    try{int re = 5;for (int i = 0; m_bPlaying && re == 5 && i < 10; ++i) {     // LockRect失败时重复尝试,最多10次re = m_Dxva2D3DRender.D3DSoftDisplayFrame(m_pOutBuffer, pAvFrame->width, pAvFrame->height, ShowRect);Sleep(1);}}catch (int re){myprint("m_Dxva2D3DRender.InitD3DRender again");if (m_Dxva2D3DRender.InitD3DRender(m_showWnd, m_pCodecCxt->width, m_pCodecCxt->height) == false){myprint("m_Dxva2D3DRender.InitD3DRender again fail");av_packet_unref(&pkt);continue;}}}                                }if (m_bCapture /*&& pkt.flags == 1*/ && img_convert_ctx){sws_scale(img_convert_ctx, (const uint8_t* const*)pAvFrame->data, pAvFrame->linesize, 0, m_pCodecCxt->height,pFrameRGB->data, pFrameRGB->linesize);SaveIFrameImage(pFrameRGB->data[0], m_pCodecCxt->width, m_pCodecCxt->height);m_bCapture = false;}}}}}else if (pkt.stream_index == m_nAudioIndex){num_stream_index_err = 0;if (m_bSupportAudio) {pktdata = pkt.data;pktsize = pkt.size;if (pktsize > 0){int gotframe = 0;if (nullptr == m_pAudioCodecCxt || nullptr == pAvFrame) {myprint("m_pAudioCodecCxt == NULL || pAvFrame == NULL");break;}len = avcodec_send_packet(m_pAudioCodecCxt, &pkt);if (len != 0 && len != AVERROR(EAGAIN)){pktsize = 0;myprint("avcodec_send_packet len < 0");break;}auto data_size = av_get_bytes_per_sample(m_pAudioCodecCxt->sample_fmt); if (data_size < 0) {myprint("Failed to calculate data size\n");break;}while (gotframe == 0 && !m_bQuit) {gotframe = avcodec_receive_frame(m_pAudioCodecCxt, pAvFrame);if (!gotframe){if (bPushAudioToQueue == true && m_bEnableAudio && !m_bStopAudio){audio_frame_t audioFrame;numBytes = av_get_bytes_per_sample(AV_SAMPLE_FMT_S16);auto dstNbSamples = av_rescale_rnd(pAvFrame->nb_samples,m_src_sample_rate,pAvFrame->sample_rate,AV_ROUND_ZERO);int data_size = 0;try{auto nb = swr_convert(m_pSwrContext,(uint8_t**)outData,dstNbSamples,(const uint8_t**)pAvFrame->data,pAvFrame->nb_samples);data_size = av_samples_get_buffer_size(nullptr, m_channels_play, nb, AV_SAMPLE_FMT_S16, 1);}catch (const std::exception&){m_bSupportAudio = false;myprint("swr_convert throw err, set m_bSupportAudio false");continue;}int copy_size = 0; int copy_ptr = 0;                              for (int isub = data_size; isub > 0; isub -= copy_size) {if (isub > m_audio_buffer_notify_size) {copy_size = m_audio_buffer_notify_size;copy_ptr = data_size - isub;}elsecopy_size = isub;audioFrame.data_size = copy_size;memcpy(audioFrame.data, outData[0] + copy_ptr, copy_size);EnterCriticalSection(&m_lock);m_AudioPlayQue.push(audioFrame);LeaveCriticalSection(&m_lock);}}}}}}}else if (++num_stream_index_err > 20) {myprint("pkt.stream_index unfind, %d",pkt.stream_index);enableReConnect();}av_packet_unref(&pkt);}else {if (++num_av_read_frame_err > 10) {myprint("num_av_read_frame_err is more than 10");enableReConnect();}}}if (m_bDecodeThreadRun) {myprint("m_bDecodeThreadRun is true");enableReConnect();}if (pAvFrame)av_free(pAvFrame);if (pFrameRGB)av_free(pFrameRGB);if (pBuffer)av_free(pBuffer);if (img_convert_ctx)sws_freeContext(img_convert_ctx);if (outData[0] && outData[1]){av_free(outData[0]);av_free(outData[1]);outData[0] = 0;outData[1] = 0;}
}

四、相关下载

链接: 可执行程序下载

链接: 源码下载

相关文章:

ffmpeg+D3D实现的MFC音视频播放器,支持录像、截图、音视频播放、码流信息显示等功能

一、简介 本播放器是在vs2019下开发&#xff0c;通过ffmpeg实现拉流解码功能&#xff0c;通过D3D实现视频的渲染功能。截图功能采用libjpeg实现&#xff0c;可以截取jpg图片&#xff0c;图片的默认保存路径是在C:\MYRecPath中。录像功能采用封装好的类Mp4Record实现&#xff0c…...

【Flink】-- flink新版本发布:v2.0-preview1

目录 1、简介 2、非兼容变更 2.1、API 2.2、连接器适配计划 2.3、配置 2.4、其它 3、重要新特性 3.1、存算分离状态管理 3.2、物化表 3.3、批作业的自适应执行 3.4、流式湖仓 4、附加 4.1、非兼容性的 api 程序变更 4.1.2、Removed Classes # 4.1.3、Modified Cl…...

Node.js 版本管理的最终答案 Volta

文章目录 特点安装Unix系统安装Windows系统安装 常用命令volta fetchvolta installvolta uninstallvolta pinvolta listvolta completionsvolta whichvolta setupvolta runvolta help 建议 目前对于前端项目的node 版本&#xff0c;我们一般会在项目 package.json 的 engines 字…...

蓝桥杯每日真题 - 第11天

题目&#xff1a;&#xff08;合并数列&#xff09; 题目描述&#xff08;14届 C&C B组D题&#xff09; 解题思路&#xff1a; 题意理解&#xff1a;给定两个数组&#xff0c;目标是通过若干次合并操作使两个数组相同。每次合并操作可以将数组中相邻的两个数相加&#xff…...

Vue vs React:两大前端框架的区别解析

在现代前端开发中&#xff0c;Vue.js 和 React.js 是两个最受欢迎的框架和库。我们常常面临选择它们的困惑。虽然这两者在本质上都是为了构建用户界面而设计的&#xff0c;但它们在设计理念、使用方式和生态系统等方面有着显著的区别。今天&#xff0c;我们将通过深入分析这两个…...

【树莓派raspberrypi烧录Ubuntu远程桌面登入树莓派】

提示&#xff1a;本文利用的是Ubuntu主机和树莓派4B开发板&#xff0c;示例仅供参考 文章目录 一、树莓派系统安装下载前准备工作下载安装树莓派的官方烧录软件imagerimager的使用方法 二、主机与树莓SSH连接查看数梅派IP地址建立ssh连接更新树莓派源地址 三、主机端远程桌面配…...

c# 调用c++ 的dll 出现找不到函数入口点

今天在调用一个设备的dll文件时遇到了一点波折&#xff0c;因为多c 不熟悉&#xff0c;调用过程张出现了找不到函数入口点&#xff0c;一般我们使用c# 调用c 文件&#xff0c;还是比较简单。 [DllImport("AtnDll2.dll",CharSet CharSet.Ansi)]public static extern …...

LInux——环境基础开发工具使用(正在更新中...)

1.软件包管理器 Linux下安装软件的方案&#xff1a; 1. 源代码安装 2. rpm包安装 3. 包管理器安装 --- yum/ apt &#xff08;此图片来自于比特就业课课件&#xff09; 1.1 操作生态系统 好的操作系统定义&#xff1a; 生态环境好 不同的操作系统根本是生态不同&#xff08;…...

linux 内核asmlinkage关键字总结

1&#xff0c;看一下asmlinkage的定义 CPP_ASMLINKAGE __attribute__((regparm(0))) GCC中使用__attribute__((regparm(n)))指定最多可以使用n个寄存器&#xff08;eax, edx, ecx&#xff09;传递参数&#xff0c;n的范围是0~3&#xff0c;超过n时则将参数压入栈中&#xff08;…...

⚡️如何在 React 和 Next.js 项目里优雅的使用 Zustand

前言 你是否曾感觉在 React 中管理状态简直是一场噩梦&#xff1f;如果你已经厌倦了不停地处理 props、context 和 hooks&#xff0c;那么现在是时候认识 Zustand 了。Zustand 是一个轻量级的状态管理库&#xff0c;它简化了你处理应用状态的方式。在这篇文章中&#xff0c;我…...

Pinpoint(APM)进阶--Pinot指标采集(System Metric/Inspector)

接上文 Pinpoint使用Pinot进行指标数据存储&#xff0c;Pinot流摄入需要Kafka 本文详解Kafka和Pinot的安装部署&#xff0c;以及Pinpoint的指标采集 Pinot 简介 Apache Pinot是一个实时分布式OLAP数据存储&#xff0c;专为低延迟、高吞吐量分析而构建&#xff0c;非常适合面…...

Mysql:使用binlog的一些常用技巧

1、如何查看binlog的存放路径 show variables like log% 执行结果&#xff1a; 2、如何清除binlog &#xff08;1&#xff09;按时间清除 purge binary logs before ‘2023-06-5 10:12:00’ &#xff08;2&#xff09;按文件文件名清除 purge binary logs to ‘mybinlog.0000…...

Electron 项目启动外部可执行文件的几种方式

Electron 项目启动外部可执行文件的几种方式 序言 在开发 Electron 应用程序时&#xff0c;有时需要启动外部的可执行文件&#xff08;如 .exe 文件&#xff09;。这可能是为了调用系统工具、运行第三方软件或者集成现有的应用程序。 Electron 提供了多种方式来启动外部可执行…...

前端开发中常用的包管理器(npm、yarn、pnpm、bower、parcel)

文章目录 1. npm (Node Package Manager)2. Yarn (Yarn Package Manager)3. pnpm4. Bower5. Parcel总结 前端开发中常用的包管理器主要有以下几个&#xff1a; 1. npm (Node Package Manager) 简介&#xff1a; npm 是 Node.js 的默认包管理器&#xff0c;也是最广泛使用的包…...

Linux入门:环境变量与进程地址空间

一. 环境变量 1. 概念 1️⃣基本概念&#xff1a; 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如&#xff1a;我们在编写C/C代码的时候&#xff0c;在链接的时候&#xff0c;从来不知道我们的所链接的动态静态库在哪里&#x…...

【Jenkins实战】Windows安装服务启动失败

写此篇短文&#xff0c;望告诫后人。 如果你之前装过Jenkins&#xff0c;出于换域账号/本地帐号的原因想重新安装&#xff0c;你大概率会遇上一次Jenkins服务启动失败提示&#xff1a; Jenkins failed to start - Verify that you have sufficient privileges to start system…...

web实操5——http数据详解,request对象功能

http请求数据 现在我们浏览器f12的那些是浏览器给http格式数据整理之后便于我们阅读的。 原始的http格式信息&#xff1a; 就是按照一定格式和符号的字符串&#xff1a; 请求行&#xff1a;格式如下图 请求头&#xff1a;一个个key&#xff0c;value数据&#xff0c;用,分割…...

C# 如何动态加载程序集

程序集的加载&#xff0c;默认是从当前目录下查找&#xff0c;如果当前目录查找不到&#xff0c;然后再去系统目录中查找&#xff0c;依然查找不到就会从环境变量中查找&#xff0c;如果依然找不到&#xff0c;则会抛出一个异常 FileNotFoundException。 托管代码中&#xff0…...

前端基础的讲解-JS(10)

作用域链 通过上节作用域我们知道&#xff0c;当我们声明一个函数时&#xff0c;程序会生成一个独立的作用域&#xff0c;如果函数中还有函数&#xff0c;那么在这个作用域中就又可以诞生一个作用域&#xff1b;根据 内部函数可以访问外部函数变量 的这种机制&#xff0c;用链…...

JNI整理总结

JNI JNI基础 JNI基础 JNI&#xff0c;java native interface&#xff0c;即java本地接口&#xff0c;是java调用本地化方法的接口&#xff0c;是为java编写本地方法&#xff0c;为jvm嵌入本地应用程序的标准化接口。首要目标是在给定的平台上采用java通过JNI调用本地化方法&am…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动

一、前言说明 在2011版本的gb28181协议中&#xff0c;拉取视频流只要求udp方式&#xff0c;从2016开始要求新增支持tcp被动和tcp主动两种方式&#xff0c;udp理论上会丢包的&#xff0c;所以实际使用过程可能会出现画面花屏的情况&#xff0c;而tcp肯定不丢包&#xff0c;起码…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

OD 算法题 B卷【正整数到Excel编号之间的转换】

文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的&#xff1a;a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用&#xff08;Math::max&#xff09; 2 函数接口…...