video_topic
使用qt5,ffmpeg6.0,opencv,os2来实现。qt并非必要,只是用惯了。
步骤是:
1.读取rtsp码流,转换成mat图像
2.发送ros::mat图像
项目结构如下:
videoplayer.h
#ifndef VIDEOPLAYER_H
#define VIDEOPLAYER_H#include <QThread>
#include <QImage>class VlcInstance;
class VlcMedia;
class VlcMediaPlayer;class VideoPlayer : public QThread
{Q_OBJECTpublic:explicit VideoPlayer();~VideoPlayer();void startPlay();void stopPlay();signals:void sig_GetOneFrame(QImage); //每获取到一帧图像 就发送此信号void sig_GetRFrame(QImage); signals://void SigFinished(void);protected:void run();private:QString mFileName;VlcInstance *_instance;VlcMedia *_media;VlcMediaPlayer *_player;std::string rtspaddr;bool mStopFlag;//是否退出标志
public slots:void setrtsp(std::string addr);
};#endif // VIDEOPLAYER_H
videoplayer.cpp
#include "videoplayer.h"
extern "C"
{#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"#include "libavutil/pixfmt.h"#include "libswscale/swscale.h"#include "libavutil/imgutils.h"}#include <stdio.h>
#include<iostream>
using namespace std;
VideoPlayer::VideoPlayer()
{rtspaddr="rtsp://admin:123456@192.168.123.104:554/stream1";
}VideoPlayer::~VideoPlayer()
{}void VideoPlayer::setrtsp(std::string addr){rtspaddr=addr;
}void VideoPlayer::startPlay()
{///调用 QThread 的start函数 将会自动执行下面的run函数 run函数是一个新的线程this->start();
}void VideoPlayer::stopPlay(){mStopFlag= true;
}void VideoPlayer::run()
{AVFormatContext *pFormatCtx;AVCodecContext *pCodecCtx;const AVCodec *pCodec;AVFrame *pFrame, *pFrameRGB;AVPacket *packet;uint8_t *out_buffer;static struct SwsContext *img_convert_ctx;int videoStream, i, numBytes;int ret, got_picture;avformat_network_init();//Allocate an AVFormatContext.pFormatCtx = avformat_alloc_context();AVDictionary *avdic=NULL;/*char option_key[]="rtsp_transport";char option_value[]="tcp";av_dict_set(&avdic,option_key,option_value,0);char option_key2[]="max_delay";char option_value2[]="100";av_dict_set(&avdic,option_key2,option_value2,0);*/av_dict_set(&avdic, "buffer_size", "1024000", 0); //设置最大缓存,1080可调到最大av_dict_set(&avdic, "rtsp_transport", "udp", 0); //以tcp的方式传送av_dict_set(&avdic, "stimeout", "5000000", 0); //设置超时断开链接时间,单位usav_dict_set(&avdic, "max_delay", "500000", 0); //设置最大时延av_dict_set(&avdic, "framerate", "5", 0);//av_dict_set(&avdic, "video_size","640x40",0);/*AVDictionary* options = NULL;av_dict_set(&options, "buffer_size", "1024000", 0); //设置最大缓存,1080可调到最大av_dict_set(&options, "rtsp_transport", "udp", 0); //以tcp的方式传送av_dict_set(&options, "stimeout", "5000000", 0); //设置超时断开链接时间,单位usav_dict_set(&options, "max_delay", "500000", 0); //设置最大时延av_dict_set(&options, "framerate", "20", 0);*////rtsp地址,可根据实际情况修改/// rtsp://127.0.0.1:8554/stream/// rtsp://admin:123456@192.168.123.104:554/stream1//char * tmp=(char*)rtspaddr.data();//char url[50];//strcpy(url, tmp);//char url[] ="rtsp://admin:123456@192.168.123.104:554/stream1";char url[100];for(int i=0;i<rtspaddr.length();i++){url[i] = rtspaddr[i];}url[rtspaddr.length()]='\0';if (avformat_open_input(&pFormatCtx, url, NULL, &avdic) != 0) {printf("can't open the file. \n");return;}if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {printf("Could't find stream infomation.\n");return;}videoStream = -1;///循环查找视频中包含的流信息,直到找到视频类型的流///便将其记录下来 保存到videoStream变量中///这里我们现在只处理视频流 音频流先不管他for (i = 0; i < pFormatCtx->nb_streams; i++) {if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {videoStream = i;break;}}///如果videoStream为-1 说明没有找到视频流if (videoStream == -1) {printf("Didn't find a video stream.\n");return;}printf("nb_stream:%d videoStream:%d\n",pFormatCtx->nb_streams,videoStream);pCodec = avcodec_find_decoder(pFormatCtx->streams[videoStream]->codecpar->codec_id);pCodecCtx = avcodec_alloc_context3(pCodec);avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar);//printf("pCodecCtx->frame_number:%d\n", pCodecCtx->frame_number);//printf("pCodecCtx->time_base.num:%d\n", pCodecCtx->time_base.num);//printf("pCodecCtx->time_base.den:%d\n", pCodecCtx->time_base.den);//printf("pCodecCtx->bit_rate:%d\n", pCodecCtx->bit_rate);//printf("pCodecCtx->framerate:%d\n", pCodecCtx->framerate);// pCodecCtx->bit_rate =0; //初始化为0// pCodecCtx->time_base.num=1; //下面两行:一秒钟25帧// pCodecCtx->time_base.den=10;// pCodecCtx->frame_number=1; //每包一个视频帧if (pCodec == NULL) {printf("Codec not found.\n");return;}///打开解码器if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {printf("Could not open codec.\n");return;}pFrame = av_frame_alloc();pFrameRGB = av_frame_alloc();///这里我们改成了 将解码后的YUV数据转换成RGB32img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,AV_PIX_FMT_RGBA, SWS_BICUBIC, NULL, NULL, NULL);numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGBA, pCodecCtx->width,pCodecCtx->height,1);out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));av_image_fill_arrays(pFrameRGB->data,pFrameRGB->linesize,out_buffer,AV_PIX_FMT_RGBA,pCodecCtx->width,pCodecCtx->height,1);int y_size = pCodecCtx->width * pCodecCtx->height;packet = (AVPacket *) malloc(sizeof(AVPacket)); //分配一个packetav_new_packet(packet, y_size); //分配packet的数据mStopFlag = false;while (!mStopFlag){if (av_read_frame(pFormatCtx, packet) < 0){continue; //这里认为视频读取完了}if (packet->stream_index == videoStream) {ret = avcodec_send_packet(pCodecCtx,packet);if( 0 != ret){continue;}while (avcodec_receive_frame(pCodecCtx,pFrame) == 0){sws_scale(img_convert_ctx,(uint8_t const * const *) pFrame->data,pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data,pFrameRGB->linesize);//把这个RGB数据 用QImage加载QImage tmpImg((uchar *)out_buffer,pCodecCtx->width,pCodecCtx->height,QImage::Format_RGBA8888);//QImage tmpImg((uchar *)out_buffer,pCodecCtx->width,pCodecCtx->height,QImage::Format_RGB888);QImage image = tmpImg.copy(); //把图像复制一份 传递给界面显示emit sig_GetOneFrame(image); //发送信号/*printf("pCodecCtx->width:%d\n", pCodecCtx->width);printf("pCodecCtx->height:%d\n", pCodecCtx->height);printf("pCodecCtx->frame_number:%d\n", pCodecCtx->frame_number);printf("pCodecCtx->time_base.num:%d\n", pCodecCtx->time_base.num);printf("pCodecCtx->time_base.den:%d\n", pCodecCtx->time_base.den);printf("pCodecCtx->bit_rate:%d\n", pCodecCtx->bit_rate);printf("pCodecCtx->framerate:%d\n", pCodecCtx->framerate);printf("pCodecCtx->frame_size:%d\n", pCodecCtx->frame_size);*/}}av_packet_unref(packet); //释放资源,否则内存会一直上升msleep(0.02); //停一停 不然放的太快了}av_free(out_buffer);av_free(pFrameRGB);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);//emit SigFinished();
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QLineEdit>
#include <QDir>
#include <QSettings>
#include <QDebug>
#include <QPushButton>
#include <QPainter>
#include <QInputDialog>
#include <QtMath>
#include <iostream>#include "videoplayer.h"
#include <iostream>
#include <csignal>
#include <opencv4/opencv2/opencv.hpp>#include <iostream>
#include <iomanip>
#include <ctime>
#include <opencv2/opencv.hpp>#include<algorithm>
#include<vector>
#include<iostream>#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"#include <QTimer>#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/msg/image.hpp>
#include <std_msgs/msg/string.hpp>
using namespace std::chrono_literals;QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
signals:void sig_fame(QImage img);private:Ui::Widget *ui;
private:void readconfig();QString rtspaddr;void initWidget();void initconnect();
private slots:void slot_open_or_close();protected://void paintEvent(QPaintEvent *event);private:VideoPlayer *mPlayer; //播放线程QImage mImage; //记录当前的图像QString url;//QImage initimage;cv::Mat QImage2Mat(QImage image);QImage Mat2QImage(const cv::Mat &mat);//void readvideo();//std::vector<cv::Vec3b> colors(32);//cv::VideoWriter outputVideo;//int encode_type ;//= VideoWriter::fourcc('M', 'J', 'P', 'G');//std::vector<cv::Vec3b> colors;//cv::VideoWriter outputVideo;private slots:void slotGetOneFrame(QImage img);private:cv::Mat tempmat;// -------------------------------------// ros// -------------------------------------// noderclcpp::Node::SharedPtr node_;// pubrclcpp::Publisher<sensor_msgs::msg::CompressedImage>::SharedPtr publisher_;// sub//rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscriber_;// spinrclcpp::TimerBase::SharedPtr timer_;void initSpin(void);QTimer spin_timer_;void timer_callback();};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{mPlayer = new VideoPlayer;ui->setupUi(this);readconfig();initWidget();initconnect();// -------------------------------------/*// create topic pubthis->publisher_ = this->node_->create_publisher<std_msgs::msg::String>("pub_topic", 10);// create topic subthis->subscriber_ = node_->create_subscription<std_msgs::msg::String>("sub_topic", 10,[&](const std_msgs::msg::String::SharedPtr msg){// 處理訂閱到的消息QString receivedMsg = QString::fromStdString(msg->data);std::cout << msg->data << std::endl;//ui->textBrowser->append(receivedMsg);});this->initSpin();*/rclcpp::init(0, nullptr);// create nodethis->node_ = rclcpp::Node::make_shared("video");this->publisher_ = this->node_->create_publisher<sensor_msgs::msg::CompressedImage>("pubImageTopic", 10);this->timer_ = this->node_->create_wall_timer(33ms, std::bind(&Widget::timer_callback, this));this->initSpin();}Widget::~Widget()
{delete ui;// -------------------------------------// ROS 釋放// -------------------------------------this->spin_timer_.stop();rclcpp::shutdown();// -------------------------------------}void Widget::initSpin(void)
{this->spin_timer_.setInterval(1); // 1 msQObject::connect(&this->spin_timer_, &QTimer::timeout, [&](){ rclcpp::spin_some(node_); });this->spin_timer_.start();
}void Widget::timer_callback(){try{//ros_img_ = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", tempmat).toImageMsg();//sensor_msgs::msg::Image::SharedPtr ros_img_ = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", tempmat).toImageMsg();if(!tempmat.empty()){//rclcpp::Publisher<sensor_msgs::msg::CompressedImage>::SharedPtr video_compressed_publisher_;cv::Mat des1080;cv::resize(tempmat, des1080, cv::Size(1080, 720), 0, 0, cv::INTER_NEAREST);sensor_msgs::msg::CompressedImage::SharedPtr ros_img_compressed_ = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", des1080).toCompressedImageMsg();//video_compressed_publisher_->publish(*ros_img_compressed_);this->publisher_ ->publish(*ros_img_compressed_);qDebug()<<"publisher";}else{qDebug()<<"empty image";}//RCLCPP_WARN(this->get_logger(), "empty image");// video_publisher_->publish(*ros_img_);}catch (cv_bridge::Exception &e){//RCLCPP_ERROR(this->get_logger(),ros_img_->encoding.c_str());qDebug()<<"Exception";}}void Widget::readconfig(){QSettings settingsread("./src/video_topic/conf/config.ini",QSettings::IniFormat);rtspaddr = settingsread.value("SetUpOption/camerartsp").toString();mPlayer->setrtsp(rtspaddr.toStdString());
}void Widget::initWidget(){qDebug()<<rtspaddr;ui->le_rtstspaddr->setText(rtspaddr);
}void Widget::slot_open_or_close(){if(ui->btn_openorclose->text()=="open"){ui->btn_openorclose->setText("close");mPlayer->startPlay();// ROS 初始化// -------------------------------------/*rclcpp::init(0, nullptr);// create nodethis->node_ = rclcpp::Node::make_shared("video");this->publisher_ = this->node_->create_publisher<sensor_msgs::msg::CompressedImage>("pubImageTopic", 10);this->timer_ = this->node_->create_wall_timer(500ms, std::bind(&Widget::timer_callback, this));//pub_img = this->create_publisher<sensor_msgs::msg::Image>("res_img", 10);rclcpp::spin(this->node_);*///readvideo();}else{ui->btn_openorclose->setText("open");mPlayer->stopPlay();}
}void Widget::initconnect(){connect(ui->btn_openorclose,&QPushButton::clicked,this,&Widget::slot_open_or_close);connect(mPlayer,SIGNAL(sig_GetOneFrame(QImage)),this,SLOT(slotGetOneFrame(QImage)));connect(this,&Widget::sig_fame,this,&Widget::slotGetOneFrame);//connect(mPlayer,&VideoPlayer::SigFinished, mPlayer,&VideoPlayer::deleteLater);//自动释放
}void Widget::slotGetOneFrame(QImage img)
{//cv::Mat tempmat = QImage2Mat(img);tempmat = QImage2Mat(img);if (tempmat.empty()) {printf("null img\n");}else {QImage outimg = Mat2QImage(tempmat);//printf("get img\n");mImage = outimg;QImage imageScale = mImage.scaled(QSize(ui->label->width(), ui->label->height()));QPixmap pixmap = QPixmap::fromImage(imageScale);ui->label->setPixmap(pixmap);}}cv::Mat Widget::QImage2Mat(QImage image)
{cv::Mat mat = cv::Mat::zeros(image.height(), image.width(),image.format()); //初始化Matswitch(image.format()) //判断image的类型{case QImage::QImage::Format_Grayscale8: //灰度图mat = cv::Mat(image.height(), image.width(),CV_8UC1,(void*)image.constBits(),image.bytesPerLine());break;case QImage::Format_RGB888: //3通道彩色mat = cv::Mat(image.height(), image.width(),CV_8UC3,(void*)image.constBits(),image.bytesPerLine());break;case QImage::Format_ARGB32: //4通道彩色mat = cv::Mat(image.height(), image.width(),CV_8UC4,(void*)image.constBits(),image.bytesPerLine());break;case QImage::Format_RGBA8888:mat = cv::Mat(image.height(), image.width(),CV_8UC4,(void*)image.constBits(),image.bytesPerLine());break;default:return mat;}cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB);return mat;}QImage Widget::Mat2QImage(const cv::Mat &mat)
{if(mat.type()==CV_8UC1 || mat.type()==CV_8U){QImage image((const uchar *)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);return image;}else if(mat.type()==CV_8UC3){QImage image((const uchar *)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);return image.rgbSwapped(); //r与b调换}
}
widget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Widget</class><widget class="QWidget" name="Widget"><property name="geometry"><rect><x>0</x><y>0</y><width>645</width><height>461</height></rect></property><property name="windowTitle"><string>Widget</string></property><layout class="QVBoxLayout" name="verticalLayout"><item><widget class="QStackedWidget" name="stackedWidget"><widget class="QWidget" name="page"><layout class="QVBoxLayout" name="verticalLayout_2"><item><widget class="QLabel" name="label"><property name="text"><string>TextLabel</string></property></widget></item><item><layout class="QHBoxLayout" name="horizontalLayout"><item><widget class="QLineEdit" name="le_rtstspaddr"><property name="readOnly"><bool>true</bool></property></widget></item><item><widget class="QPushButton" name="btn_openorclose"><property name="text"><string>open</string></property></widget></item></layout></item></layout></widget><widget class="QWidget" name="page_2"/></widget></item></layout></widget><resources/><connections/>
</ui>
main.cpp
#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();//w.showMaximized();return a.exec();
}
package.xml
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3"><name>video_topic</name><version>0.0.0</version><description>TODO: Package description</description><maintainer email="cl@todo.todo">cl</maintainer><license>TODO: License declaration</license><buildtool_depend>ament_cmake</buildtool_depend><buildtool_depend>cv_bridge</buildtool_depend><depend>rclcpp</depend><depend>std_msgs</depend><depend>cv_bridge</depend><test_depend>ament_lint_auto</test_depend><test_depend>ament_lint_common</test_depend><export><build_type>ament_cmake</build_type></export>
</package>
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(video_topic)# Default to C++14
if(NOT CMAKE_CXX_STANDARD)set(CMAKE_CXX_STANDARD 14)
endif()if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic)
endif()# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
# qt
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets)
find_package(cv_bridge REQUIRED)
find_package(image_transport)
find_package(sensor_msgs REQUIRED)add_executable(videosrc/main.cppsrc/videoplayer.hsrc/videoplayer.cppsrc/widget.hsrc/widget.cppsrc/widget.ui
)#set(FFMPEG_LIBS_DIR /usr/local/ffmpeg/lib)
#set(FFMPEG_HEADERS_DIR /usr/local/ffmpeg/include)set(FFMPEG_LIBS_DIR /usr/lib/aarch64-linux-gnu)
set(FFMPEG_HEADERS_DIR /usr/include/aarch64-linux-gnu)
include_directories(${FFMPEG_HEADERS_DIR})
#link_directories(${FFMPEG_LIBS_DIR})
#set(FFMPEG_LIBS libavutil.so libavcodec.so libavdevice.so libavformat.so libavfilter.so libswresample.so libswscale.so libavutil.so)
set(FFMPEG_LIBS libavcodec.so libavformat.so libswscale.so libavutil.so)find_package(OpenCV REQUIRED)
include_directories( ${OpenCV_INCLUDE_DIRS})
target_link_libraries(video ${OpenCV_LIBS})# ros
target_link_libraries(video${rclcpp_LIBRARIES}
)
# qt
target_link_libraries(video Qt5::Core Qt5::GuiQt5::Widgets
)
#ffmpegtarget_link_libraries(video ${FFMPEG_LIBS})ament_target_dependencies(videorclcppstd_msgssensor_msgs cv_bridge OpenCV image_transport
)# ------------------------------------------
# 設置自動MOC、UIC和RCC (與QT相關)
# ------------------------------------------
set_target_properties(video PROPERTIES AUTOMOC ON)
set_target_properties(video PROPERTIES AUTOUIC ON)
set_target_properties(video PROPERTIES AUTORCC ON)
# ------------------------------------------# 安装可执行文件
install(TARGETS videoDESTINATION lib/${PROJECT_NAME}
)ament_package()
相关文章:

video_topic
使用qt5,ffmpeg6.0,opencv,os2来实现。qt并非必要,只是用惯了。 步骤是: 1.读取rtsp码流,转换成mat图像 2.发送ros::mat图像 项目结构如下: videoplayer.h #ifndef VIDEOPLAYER_H #define VIDEOPLAYER_H#include …...

uniapp获取公钥、MD5,‘keytool‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
获取MD5、SHA1、SHA256指纹信息 通过命令的形式获取 winr调出黑窗口cd到证书所在目录输入keytool -list -v -keystore test.keystore,其中 test.keystore为你的证书名称加文件后缀按照提示输入你的证书密码,就可以查看证书的信息 通过uniapp云端查看(证书是在DClou…...

Jetson Orin NX 开发指南(5): 安装 OpenCV 4.6.0 并配置 CUDA 以支持 GPU 加速
一、前言 Jetson 系列的开发板 CPU 性能不是很强,往往需要采用 GPU 加速的方式处理图像数据,因此本文主要介绍如何安装带有 GPU 加速的 OpenCV,其中 GPU 加速通过 CUDA 来实现。 参考博客 Ubuntu 20.04 配置 VINS-Fusion-gpu OpenCV 4.6.…...

Spring Security 6.x 系列【67】认证篇之安装 ApacheDS
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列Spring Security 版本 6.1.0 源码地址:https://gitee.com/pearl-organization/study-spring-security-demo 文章目录 1. 概述2. 安装3. 连接工具1. 概述 官方文档 在前两篇文档中,我们简单了…...

理解线程池源码 【C++】面试高频考点
理解线程池 C 文章目录 理解线程池 C程序源码知识点emplace_back 和 push_back有什么区别?互斥锁 mutexcondition_variablestd::move()函数bind()函数join 函数 线程池的原理就是管理一个任务队列和一个工作线程队列。 工作线程不断的从任务队列取任务,然…...

BP神经网络应用案例
目录 背景介绍 【神经网络符号说明】 【建立网络拓扑结构】 【神经网络学习步骤】 步骤1 准备输入和输出样本 步骤2 确定网络学习参数 步骤3 初始化网络权值W和阀值B 步骤4 计算网络第一层的输入和输出 步骤5 计算中间层(隐含层输入和输出) 步骤…...

日常学习记录随笔-大数据之日志(hadoop)收集实战
数据收集(nginx)--->数据分析---> 数据清洗--->数据聚合计算---数据展示 可能涉及到zabix 做任务调度我们的项目 电商日志分析 比如说我们现在有一个系统,我们的数仓建立也要有一个主题 我这个项目是什么我要干什么定义方向 对用户进行分析,用户信息 要懂整个数据的流…...

【云计算】相关解决方案介绍
文章目录 1.1 云服务环境 Eucalyptus1.1.1 介绍1.1.2 开源协议及语言1.1.3 官方网站 1.2 开源云计算平台 abiCloud1.2.1 开源协议及语言1.2.2 官方网站 1.3 分布式文件系统 Hadoop1.3.1 开源协议及语言1.3.2 官方网站 1.4 JBoss云计算项目集 StormGrind1.4.1 开源协议及语言1.4…...

攻防世界题目练习——Crypto密码新手+引导模式(二)(持续更新)
题目目录 1. 转轮机加密2. easychallenge 上一篇:攻防世界题目练习——Crypto密码新手引导模式(一)(持续更新) 1. 转轮机加密 首先了解一下轮转机加密吧。 传统密码学(三)——转轮密码机 题目内容如下: …...

LeetCode【1】两数之和
题目: 代码: public int[] twoSum(int[] nums, int target) {int[] result new int[2];Map<Integer, Integer> map new HashMap<>();// for (int i 0; i < nums.length; i) { // 这么写不能防重复啊!注意这里不…...

【运维笔记】VMWare 另一个程序已锁定文件的一部分,进程无法访问
情景再现 这里使用的是VMware 17 解决办法 进入设置 点击选项,全选复制里面内容 进入文件夹,删除所有包含.lck后缀的文件和文件夹 再启动虚拟机即可...

[Springboot]统一响应和异常处理配置
背景 前后端分离情况下,后端接口通常只需要返回JSON数据。 但有时候因为某些原因可能会导致得不到正确的结果。 比如 因为登录密码错误,你不能直接返回错误信息和null,这样前端很难处理。 又比如 因为后端接口爆出了异常,也不能直…...

Redis第四五六章 持久化事务主从复制
Redis ⽀持 RDB 和 AOF 两种持久化机制,持久化功能有效地避免因进程退出造成数据丢失问题, 当下次重启时利⽤之前持久化的⽂件即可实现数据恢复。 目录 第四章 持久化 4.1 RDB 4.1.1 触发机制 4.1.2 流程说明 4.1.3 RDB ⽂件的处理 4.1.4 RDB 的优…...

【强烈推荐】免费的PDF工具,包括PDF拆分/分割、转WORD等功能的免费在线软件工具,救了大命,找了半天什么pdf365、福xipdf、还有哔果pdf全是打着免费名义收费,烦死了
PDF拆分 - 图文工具箱 - imgtool.net,嘎嘎好用,主要是免费 除此之外,还有其他的功能,需要的可以去看看...

SpringMVC源码分析(二)启动过程之RequestMappingHandlerMapping分析
a、http请求中的url是如何与对应Handler的即Controller对应method映射的? 在上篇中提到在SpringMVC中,初始化9大内置组件的时候其中有一个组件就是HandlerMapping,在初始化HandlerMapping的时候会加载代码中所有标注了Controller和RequestMap…...

KWin、libdrm、DRM从上到下全过程 —— drmModeAddFBxxx(7)
接前一篇文章:KWin、libdrm、DRM从上到下全过程 —— drmModeAddFBxxx(6) 上一回讲到了drm_internal_framebuffer_create函数中的framebuffer_check函数。讲解了该函数的参数检查部分中的第二部分,本回对于该函数余下部分进行解析。 为了便于理解,再次贴出framebuffer_ch…...

2023 年 Arm A-Profile 架构发展
随着人工智能 (AI) 的兴起和安全威胁的加剧,计算需求不断发展,作为世界设备核心的基础计算架构也必须不断发展。这就是为什么我们的工程团队向普遍存在的 Arm 架构添加新功能和技术,然后软件团队确保软件尽可能无缝地适应这些未来的功能和技术。 Arm架构是如何开发的 Arm …...

2023年09月 C/C++(五级)真题解析#中国电子学会#全国青少年软件编程等级考试
C/C++编程(1~8级)全部真题・点这里 Python编程(1~6级)全部真题・点这里 第1题:红与黑 有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。 时间限…...

CentOS系统/root根目录扩容(扩展逻辑卷)
具体操作步骤 1、查看本机磁盘环境挂载情况 2、添加磁盘分区 3、开始扩容 4、同步到文件系统 1、查看本机磁盘环境挂载情况 [rooticon ~]# df -lh 可以看到/dev/mapper/centos-root 路径下容量为50G,我们要给这个路径下的容量扩容:[rooticon ~]# lsblk…...

苍穹外卖(三) 员工分页及技术实现细节
2. 员工分页查询 2.1 需求分析和设计 2.1.1 产品原型 2.1.2 接口设计 2.2 代码开发 2.2.1 设计DTO类 根据请求参数进行封装 2.2.2 封装PageResult 后面所有的分页查询,统一都封装为PageResult对象。 员工信息分页查询后端返回的对象类型为: Result 2.…...

二进制部署MySQL8.0
1、下载MySQL官方包 ## 下载MySQL [rootlocalhost ~]# wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz2、解压并移动安装包 # 解压安装包 [rootlocalhost ~]# tar xf mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz# 移动 mv…...

全力以赴,火山引擎边缘云代表团出战亚运会
END 未来,火山引擎边缘云赛事阵容将继续全力以赴,通过领先、可信赖的云和智能技术,助力游戏行业呈现更加精彩的竞技赛事。...

WPF页面向后端传参
WPF页面(前端)向后端传参 1、编写一个Button,绑定后端命令,并传递参数: <ButtonWidth"100"Command"{Binding SendCommand}"CommandParameter"{Binding ElementNameSendMessage, PathTex…...

PyTorch 入门
一、说明 深度学习是机器学习的一个分支,其中编写的算法模仿人脑的功能。深度学习中最常用的库是 Tensorflow 和 PyTorch。由于有各种可用的深度学习框架,人们可能想知道何时使用 PyTorch。以下是人们更喜欢使用 Pytorch 来完成特定任务的原因。 Pytorch…...

微信自动批量添加好友的方法
在现在的营销中微信已成为一种重要的沟通方式。微信目前是没有自动批量添加好友的功能,需要运营者一个一个手动去添加,这样太过于浪费时间,并且加频繁了还容易被封号,今天给大家介绍几种手动批量加好友的方式以及怎么借助第三方软…...

[网鼎杯 2018]Comment git泄露 / 恢复 二次注入 .DS_Store bash_history文件查看
首先我们看到账号密码有提示了 我们bp爆破一下 我首先对数字爆破 因为全字符的话太多了 爆出来了哦 所以账号密码也出来了 zhangwei zhangwei666 没有什么用啊 扫一下吧 有git git泄露 那泄露看看 真有 <?php include "mysql.php"; session_start(); if(…...

生态兼容性进一步提升!白鲸开源 WhaleStudio 与火山引擎ByteHouse完成产品互认
数据作为新型生产要素,已快速融入生产、分配、流通、消费和社会服务管理等各环节,深刻改变着生产方式、生活方式和治理方式。越来越多企业也在尝试充分利用数据要素,开辟全新发展路径,进一步实现业务价值提升。 在数字化转型的大…...

iOS 内存管理和优化
对内存管理和拓展有独特的描述 iOS学习-内存管理 比较详细说明内存的关系 iOS 内存管理机制与原理 iOS 内存泄漏排查方法及原因分析 对weak的实现原理描写详细 【iOS】—— weak的基本原理 iOS copy & mutableCopy iOS 深拷贝与浅拷贝 对iOS的浅复制和深复制的深入解释…...

常见工具指令【Vim | GIT | ZIP | UNZIP | IDEA】
VIM 快捷键说明Ctrl U (up)向上翻动半页Ctrl B (back)向上翻动一页Ctrl D (down)向下翻页半页Ctrl F (forward)向下翻动一页 GIT 指令解释git init 使用指定目录作为Git仓库git add filename向资源库添加文件filenamegit rm file从资源库中删除文件git branch 分支名称创…...

中国人民大学与加拿大女王大学金融硕士——顺势而为,掌握人生的方向盘
在这个快速发展的时代,每个人在不断面临全新挑战的同时, 也在时刻接收着各种机会。有人抓住时代红利,实现更新迭代;有人却只能作为旁观者,眼看时代发展,而自己被逐渐淘汰。时代从不会抛下任何一个人&#x…...