android c++ 硬编码硬解码官方demo
参考:
https://fossies.org/linux/opencv/modules/videoio/src/cap_android_mediandk.cpp
代码:
// This file is part of OpenCV project.// It is subject to the license terms in the LICENSE file found in the top-level directory// of this distribution and at http://opencv.org/license.html#include "precomp.hpp"#include <stdio.h>#include <string.h>#include <fstream>#include <iostream>#include <unistd.h>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>#include <android/log.h>#include <android/native_window.h>#include "media/NdkMediaCodec.h"#include "media/NdkMediaMuxer.h"#include "media/NdkMediaExtractor.h"#include "media/NdkMediaFormat.h"#define INPUT_TIMEOUT_MS 2000#define COLOR_FormatYUV420Planar 19#define COLOR_FormatYUV420SemiPlanar 21#define COLOR_FormatSurface 0x7f000789 //See https://developer.android.com/reference/android/media/MediaCodecInfo.CodecCapabilities for codesusing namespace cv;#define TAG "NativeCodec"#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)static inline void deleter_AMediaExtractor(AMediaExtractor *extractor) {AMediaExtractor_delete(extractor);}static inline void deleter_AMediaCodec(AMediaCodec *codec) {AMediaCodec_stop(codec);AMediaCodec_delete(codec);}static inline void deleter_AMediaFormat(AMediaFormat *format) {AMediaFormat_delete(format);}class AndroidMediaNdkCapture : public IVideoCapture{public:AndroidMediaNdkCapture():sawInputEOS(false), sawOutputEOS(false),frameStride(0), frameWidth(0), frameHeight(0), colorFormat(0),videoWidth(0), videoHeight(0),videoFrameCount(0),videoRotation(0), videoRotationCode(-1),videoOrientationAuto(false) {}std::shared_ptr<AMediaExtractor> mediaExtractor;std::shared_ptr<AMediaCodec> mediaCodec;bool sawInputEOS;bool sawOutputEOS;int32_t frameStride;int32_t frameWidth;int32_t frameHeight;int32_t colorFormat;int32_t videoWidth;int32_t videoHeight;float videoFrameRate;int32_t videoFrameCount;int32_t videoRotation;int32_t videoRotationCode;bool videoOrientationAuto;std::vector<uint8_t> buffer;Mat frame;~AndroidMediaNdkCapture() { cleanUp(); }bool decodeFrame() {while (!sawInputEOS || !sawOutputEOS) {if (!sawInputEOS) {auto bufferIndex = AMediaCodec_dequeueInputBuffer(mediaCodec.get(), INPUT_TIMEOUT_MS);LOGV("input buffer %zd", bufferIndex);if (bufferIndex >= 0) {size_t bufferSize;auto inputBuffer = AMediaCodec_getInputBuffer(mediaCodec.get(), bufferIndex, &bufferSize);auto sampleSize = AMediaExtractor_readSampleData(mediaExtractor.get(), inputBuffer, bufferSize);if (sampleSize < 0) {sampleSize = 0;sawInputEOS = true;LOGV("EOS");}auto presentationTimeUs = AMediaExtractor_getSampleTime(mediaExtractor.get());AMediaCodec_queueInputBuffer(mediaCodec.get(), bufferIndex, 0, sampleSize,presentationTimeUs, sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0);AMediaExtractor_advance(mediaExtractor.get());}}if (!sawOutputEOS) {AMediaCodecBufferInfo info;auto bufferIndex = AMediaCodec_dequeueOutputBuffer(mediaCodec.get(), &info, 0);if (bufferIndex >= 0) {size_t bufferSize = 0;auto mediaFormat = std::shared_ptr<AMediaFormat>(AMediaCodec_getOutputFormat(mediaCodec.get()), deleter_AMediaFormat);AMediaFormat_getInt32(mediaFormat.get(), AMEDIAFORMAT_KEY_WIDTH, &frameWidth);AMediaFormat_getInt32(mediaFormat.get(), AMEDIAFORMAT_KEY_STRIDE, &frameStride);AMediaFormat_getInt32(mediaFormat.get(), AMEDIAFORMAT_KEY_HEIGHT, &frameHeight);AMediaFormat_getInt32(mediaFormat.get(), AMEDIAFORMAT_KEY_COLOR_FORMAT, &colorFormat);uint8_t* codecBuffer = AMediaCodec_getOutputBuffer(mediaCodec.get(), bufferIndex, &bufferSize);buffer = std::vector<uint8_t>(codecBuffer, codecBuffer + bufferSize);LOGV("colorFormat: %d", colorFormat);LOGV("buffer size: %zu", bufferSize);LOGV("width (frame): %d", frameWidth);LOGV("stride (frame): %d", frameStride);LOGV("height (frame): %d", frameHeight);if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM){LOGV("output EOS");sawOutputEOS = true;}AMediaCodec_releaseOutputBuffer(mediaCodec.get(), bufferIndex, info.size != 0);return true;} else if (bufferIndex == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {LOGV("output buffers changed");} else if (bufferIndex == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {auto format = AMediaCodec_getOutputFormat(mediaCodec.get());LOGV("format changed to: %s", AMediaFormat_toString(format));AMediaFormat_delete(format);} else if (bufferIndex == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {LOGV("no output buffer right now");} else {LOGV("unexpected info code: %zd", bufferIndex);}}}return false;}bool isOpened() const CV_OVERRIDE { return mediaCodec.get() != nullptr; }int getCaptureDomain() CV_OVERRIDE { return CAP_ANDROID; }bool grabFrame() CV_OVERRIDE{// clear the previous framebuffer.clear();return decodeFrame();}bool retrieveFrame(int, OutputArray out) CV_OVERRIDE{if (buffer.empty()) {return false;}Mat yuv(frameHeight + frameHeight/2, frameStride, CV_8UC1, buffer.data());if (colorFormat == COLOR_FormatYUV420Planar) {cv::cvtColor(yuv, frame, cv::COLOR_YUV2BGR_YV12);} else if (colorFormat == COLOR_FormatYUV420SemiPlanar) {cv::cvtColor(yuv, frame, cv::COLOR_YUV2BGR_NV21);} else {LOGE("Unsupported video format: %d", colorFormat);return false;}Mat croppedFrame = frame(Rect(0, 0, videoWidth, videoHeight));out.assign(croppedFrame);if (videoOrientationAuto && -1 != videoRotationCode) {cv::rotate(out, out, videoRotationCode);}return true;}double getProperty(int property_id) const CV_OVERRIDE{switch (property_id){case CV_CAP_PROP_FRAME_WIDTH:return (( videoOrientationAuto &&(cv::ROTATE_90_CLOCKWISE == videoRotationCode || cv::ROTATE_90_COUNTERCLOCKWISE == videoRotationCode))? videoHeight : videoWidth);case CV_CAP_PROP_FRAME_HEIGHT:return (( videoOrientationAuto &&(cv::ROTATE_90_CLOCKWISE == videoRotationCode || cv::ROTATE_90_COUNTERCLOCKWISE == videoRotationCode))? videoWidth : videoHeight);case CV_CAP_PROP_FPS: return videoFrameRate;case CV_CAP_PROP_FRAME_COUNT: return videoFrameCount;case CAP_PROP_ORIENTATION_META: return videoRotation;case CAP_PROP_ORIENTATION_AUTO: return videoOrientationAuto ? 1 : 0;}return 0;}bool setProperty(int property_id, double value) CV_OVERRIDE{switch (property_id){case CAP_PROP_ORIENTATION_AUTO: {videoOrientationAuto = value != 0 ? true : false;return true;}}return false;}bool initCapture(const char * filename){struct stat statBuffer;if (stat(filename, &statBuffer) != 0) {LOGE("failed to stat file: %s (%s)", filename, strerror(errno));return false;}int fd = open(filename, O_RDONLY);if (fd < 0) {LOGE("failed to open file: %s %d (%s)", filename, fd, strerror(errno));return false;}mediaExtractor = std::shared_ptr<AMediaExtractor>(AMediaExtractor_new(), deleter_AMediaExtractor);if (!mediaExtractor) {return false;}media_status_t err = AMediaExtractor_setDataSourceFd(mediaExtractor.get(), fd, 0, statBuffer.st_size);close(fd);if (err != AMEDIA_OK) {LOGV("setDataSource error: %d", err);return false;}int numtracks = AMediaExtractor_getTrackCount(mediaExtractor.get());LOGV("input has %d tracks", numtracks);for (int i = 0; i < numtracks; i++) {auto format = std::shared_ptr<AMediaFormat>(AMediaExtractor_getTrackFormat(mediaExtractor.get(), i), deleter_AMediaFormat);if (!format) {continue;}const char *s = AMediaFormat_toString(format.get());LOGV("track %d format: %s", i, s);const char *mime;if (!AMediaFormat_getString(format.get(), AMEDIAFORMAT_KEY_MIME, &mime)) {LOGV("no mime type");} else if (!strncmp(mime, "video/", 6)) {int32_t trackWidth, trackHeight, fps, frameCount = 0, rotation = 0;AMediaFormat_getInt32(format.get(), AMEDIAFORMAT_KEY_WIDTH, &trackWidth);AMediaFormat_getInt32(format.get(), AMEDIAFORMAT_KEY_HEIGHT, &trackHeight);AMediaFormat_getInt32(format.get(), AMEDIAFORMAT_KEY_FRAME_RATE, &fps);#if __ANDROID_API__ >= 28AMediaFormat_getInt32(format.get(), AMEDIAFORMAT_KEY_ROTATION, &rotation);LOGV("rotation (track): %d", rotation);#endif#if __ANDROID_API__ >= 29AMediaFormat_getInt32(format.get(), AMEDIAFORMAT_KEY_FRAME_COUNT, &frameCount);#endifLOGV("width (track): %d", trackWidth);LOGV("height (track): %d", trackHeight);if (AMediaExtractor_selectTrack(mediaExtractor.get(), i) != AMEDIA_OK) {continue;}mediaCodec = std::shared_ptr<AMediaCodec>(AMediaCodec_createDecoderByType(mime), deleter_AMediaCodec);if (!mediaCodec) {continue;}if (AMediaCodec_configure(mediaCodec.get(), format.get(), NULL, NULL, 0) != AMEDIA_OK) {continue;}sawInputEOS = false;sawOutputEOS = false;if (AMediaCodec_start(mediaCodec.get()) != AMEDIA_OK) {continue;}videoWidth = trackWidth;videoHeight = trackHeight;videoFrameRate = fps;videoFrameCount = frameCount;videoRotation = rotation;switch(videoRotation) {case 90:videoRotationCode = cv::ROTATE_90_CLOCKWISE;break;case 180:videoRotationCode = cv::ROTATE_180;break;case 270:videoRotationCode = cv::ROTATE_90_COUNTERCLOCKWISE;break;default:videoRotationCode = -1;break;}return true;}}return false;}void cleanUp() {sawInputEOS = true;sawOutputEOS = true;frameStride = 0;frameWidth = 0;frameHeight = 0;colorFormat = 0;videoWidth = 0;videoHeight = 0;videoFrameRate = 0;videoFrameCount = 0;videoRotation = 0;videoRotationCode = -1;}};class AndroidMediaNdkVideoWriter CV_FINAL :public cv::IVideoWriter{typedef struct {int fourcc;const char* mime;OutputFormat muxerFormat;}FourCCInfo;static const int64_t TIMEOUT = 1000L;static const FourCCInfo FOURCC_INFO[];static const FourCCInfo* findInfo(int fourcc) {for( const FourCCInfo *it = FOURCC_INFO; NULL != it->mime; it++ ) {if (fourcc == it->fourcc) return it;}return NULL;}AMediaFormat* format;AMediaCodec* encoder;AMediaMuxer* muxer;#if __ANDROID_API__ >= 26ANativeWindow* surface;#endiflong frameIndex;int width;int height;double frameRate;ssize_t videoTrackIndex;int fd;void drainEncoder(bool end) {if (end) {#if __ANDROID_API__ >= 26AMediaCodec_signalEndOfInputStream(encoder);#elsewriteBytes(NULL, 0);#endif}AMediaCodecBufferInfo bufferInfo;ssize_t bufferIndex;size_t bufferSize;uint8_t *buffer;while (true) {bufferIndex = AMediaCodec_dequeueOutputBuffer(encoder, &bufferInfo, TIMEOUT);if (bufferIndex >= 0) {buffer = AMediaCodec_getOutputBuffer(encoder, (size_t)bufferIndex, &bufferSize);if (NULL == buffer || 0 == bufferSize){LOGE("Can't get output buffer");break;}if (videoTrackIndex >= 0) {bufferInfo.presentationTimeUs = frameIndex * 1000000L / frameRate;LOGV("Muxer write to track %d: %d byte(s)", (int)videoTrackIndex, (int)bufferInfo.size);AMediaMuxer_writeSampleData(muxer, (size_t)videoTrackIndex, buffer, &bufferInfo);} else {LOGE("Invalid video track !");}AMediaCodec_releaseOutputBuffer(encoder, (size_t)bufferIndex, false);if (bufferInfo.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) break;} else if (AMEDIACODEC_INFO_TRY_AGAIN_LATER == bufferIndex) {if (!end) break;} else if (AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED == bufferIndex) {videoTrackIndex = AMediaMuxer_addTrack(muxer, AMediaCodec_getOutputFormat(encoder));if (videoTrackIndex >= 0) {AMediaMuxer_start(muxer);}LOGV("New videoTrackIndex: %d", (int)videoTrackIndex);}}}#if __ANDROID_API__ < 26void writeBytes( uint8_t* inputBuffer, size_t inputBufferSize ) {LOGV("[writeBytes] inputBufferSize=%u", (unsigned int)inputBufferSize);ssize_t bufferIndex;size_t bufferSize;uint8_t* buffer;size_t partialSize;bool firstCall = true;uint32_t flags;while(inputBufferSize > 0 || firstCall) {bufferIndex = AMediaCodec_dequeueInputBuffer(encoder, TIMEOUT);if (bufferIndex >= 0) {firstCall = false;buffer = AMediaCodec_getInputBuffer(encoder, (size_t)bufferIndex, &bufferSize);if (NULL == buffer || 0 == bufferSize) break;flags = 0;partialSize = (inputBufferSize > bufferSize) ? bufferSize : inputBufferSize;if (partialSize > 0) {memcpy(buffer, inputBuffer, partialSize);inputBuffer += partialSize;inputBufferSize -= partialSize;if (inputBufferSize > 0) {flags = AMEDIACODEC_BUFFER_FLAG_PARTIAL_FRAME;}} else {flags = AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM;}LOGV("[writeBytes] partial - bufferIndex=%d, bufferSize=%u, partialSize=%u, remaining inputBufferSize=%u",(int)bufferIndex, (unsigned int)bufferSize, (unsigned int)partialSize, (unsigned int)inputBufferSize);AMediaCodec_queueInputBuffer(encoder, (size_t)bufferIndex, 0, partialSize, frameIndex * 1000000L / frameRate, flags);if (NULL != inputBuffer) drainEncoder(false);}}}#endifpublic:AndroidMediaNdkVideoWriter(const cv::String& filename, int fourcc, double fps, cv::Size frameSize, const VideoWriterParameters& params): format(NULL),encoder(NULL),muxer(NULL),#if __ANDROID_API__ >= 26surface(NULL),#endifframeIndex(0),width(0),height(0),frameRate(0.),videoTrackIndex(-1),fd(-1) {open(filename, fourcc, fps, frameSize, params);}virtual ~AndroidMediaNdkVideoWriter() { close(); }virtual int getCaptureDomain() const CV_OVERRIDE { return cv::CAP_ANDROID; }virtual void write(cv::InputArray image_ ) CV_OVERRIDE{if (!image_.isMat()) {LOGE("Support only Mat input");return;}Mat image = image_.getMat();if (CV_8UC3 != image.type() || image.cols > width || image.rows > height) {LOGE("Expected input to be a mat of maximum %d x %d of type CV_8UC3 (%d), but received %d x %d of type: %d",width, height, CV_8UC3,image.cols, image.rows, image.type());return;}#if __ANDROID_API__ >= 26ANativeWindow_Buffer buffer;if (0 != ANativeWindow_lock(surface, &buffer, NULL)) {LOGE("Failed to lock the surface");} else {if (AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM == buffer.format) {Mat bufferMat(image.rows, image.cols, CV_8UC4, buffer.bits, buffer.stride * 4);cvtColor(image, bufferMat, CV_BGR2RGBA);} else {LOGE("Unknow surface buffer format: %u", buffer.format);}ANativeWindow_unlockAndPost(surface);}#elseLOGV("[write] image: %d x %d", image.cols, image.rows);//OpenCV don't support RGB to NV12 so we need to connvert to YV12 and then manually changed it to NV12Mat imageYV12;cvtColor(image, imageYV12, CV_BGR2YUV_YV12);//convert from YV12 to NV12size_t yPlaneSize = width * height;size_t vPlaneSize = yPlaneSize / 4;Mat channels[2] = {Mat( vPlaneSize, 1, CV_8UC1, imageYV12.ptr() + yPlaneSize + vPlaneSize ).clone(),Mat( vPlaneSize, 1, CV_8UC1, imageYV12.ptr() + yPlaneSize ).clone()};Mat vuMat( vPlaneSize, 1, CV_8UC2, imageYV12.ptr() + yPlaneSize );merge(channels, 2, vuMat);writeBytes( imageYV12.ptr(), imageYV12.rows * imageYV12.cols );#endifdrainEncoder(false);frameIndex++;}virtual bool open( const cv::String& filename, int fourcc, double fps, cv::Size frameSize, const VideoWriterParameters& params ){media_status_t status;close();const FourCCInfo* info = findInfo(fourcc);if (NULL == info) {LOGE("ERROR: findInfo");return false;}format = AMediaFormat_new();if (NULL == format) {LOGE("ERROR: AMediaFormat_new");goto error;}LOGV("mime: %s, width: %d, height: %d, fps: %f", info->mime, frameSize.width, frameSize.height, fps);AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, info->mime);AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, frameSize.width);AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, frameSize.height);AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_FRAME_RATE, (float)fps);AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_I_FRAME_INTERVAL, 5);AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, frameSize.width * frameSize.height * 5);AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT,#if __ANDROID_API__ >= 26COLOR_FormatSurface#elseCOLOR_FormatYUV420SemiPlanar#endif);encoder = AMediaCodec_createEncoderByType(info->mime);if (NULL == encoder) {LOGE("ERROR: AMediaCodec_createEncoderByType");goto error;}status = AMediaCodec_configure(encoder, format, NULL, NULL, AMEDIACODEC_CONFIGURE_FLAG_ENCODE);if (AMEDIA_OK != status) {LOGE("ERROR: AMediaCodec_configure (%d)", status);goto error;}#if __ANDROID_API__ >= 26status = AMediaCodec_createInputSurface(encoder, &surface);if (AMEDIA_OK != status || NULL == surface) {LOGE("ERROR: AMediaCodec_createInputSurface (%d)", status);goto error;}#endifAMediaCodec_start(encoder);fd = ::open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0666);if (fd < 0) {LOGE("ERROR: open");goto error;}muxer = AMediaMuxer_new(fd, info->muxerFormat);if (NULL == muxer) {LOGE("ERROR: AMediaMuxer_new");goto error;}AMediaMuxer_setOrientationHint(muxer, params.get(CAP_PROP_ORIENTATION_META, 0));frameIndex = 0;width = frameSize.width;height = frameSize.height;frameRate = fps;videoTrackIndex = -1;return true;error:close();return false;}virtual void close(){if (videoTrackIndex >= 0 && NULL != muxer) {drainEncoder(true);AMediaMuxer_stop(muxer);}if (NULL != encoder) AMediaCodec_delete(encoder);if (NULL != muxer) AMediaMuxer_delete(muxer);#if __ANDROID_API__ >= 26if (NULL != surface) ANativeWindow_release(surface);#endifif (fd >= 0) ::close(fd);if (NULL != format) AMediaFormat_delete(format);format = NULL;encoder = NULL;muxer = NULL;#if __ANDROID_API__ >= 26surface = NULL;#endifframeIndex = 0;width = 0;height = 0;frameRate = 0.;videoTrackIndex = -1;fd = -1;}virtual double getProperty(int) const CV_OVERRIDE { return 0.; }virtual bool setProperty(int, double) CV_OVERRIDE { return false; }virtual bool isOpened() const CV_OVERRIDE { return NULL != encoder; }};const AndroidMediaNdkVideoWriter::FourCCInfo AndroidMediaNdkVideoWriter::FOURCC_INFO[] = {{ CV_FOURCC('H', '2', '6', '4'), "video/avc", AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4 },{ CV_FOURCC('H', '2', '6', '5'), "video/hevc", AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4 },{ CV_FOURCC('H', '2', '6', '3'), "video/3gpp", AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4 },{ CV_FOURCC('M', 'P', '4', 'V'), "video/mp4v-es", AMEDIAMUXER_OUTPUT_FORMAT_MPEG_4 },{ 0, NULL },};/****************** Implementation of interface functions ********************/Ptr<IVideoCapture> cv::createAndroidCapture_file(const std::string &filename) {Ptr<AndroidMediaNdkCapture> res = makePtr<AndroidMediaNdkCapture>();if (res && res->initCapture(filename.c_str()))return res;return Ptr<IVideoCapture>();}Ptr<IVideoWriter> cv::createAndroidVideoWriter(const std::string& filename, int fourcc,double fps, const cv::Size& frameSize,const VideoWriterParameters& params) {Ptr<AndroidMediaNdkVideoWriter> writer = makePtr<AndroidMediaNdkVideoWriter>(filename, fourcc, fps, frameSize, params);if (writer && writer->isOpened())return writer;return Ptr<IVideoWriter>();}
相关文章:
android c++ 硬编码硬解码官方demo
参考: https://fossies.org/linux/opencv/modules/videoio/src/cap_android_mediandk.cpp 代码: // This file is part of OpenCV project.// It is subject to the license terms in the LICENSE file found in the top-level directory// of this d…...
Python之Excel数据相关
Excel Microsoft Excel是Microsoft为使用Windows和Apple Macintosh操作系统的电脑编写的一款电子表格软件。直观的界面、出色的计算功能和图表工具,再加上成功的市场营销,使Excel成为最流行的个人计算机数据处理软件。在1993年,作为Microsof…...
Ubuntu网络IP地址一直显示127.0.0.1
问题描述: 终端输入ip a显示127.0.0.1,原来类似192.168.231.1的地址不见了。 ip a 点击网络配置(ubuntu桌面版),发现无线网络模块看不见了 正常情况应该有wired 模块,就是下面标红的 解决方案:…...
Vulnhub-DC-3 靶机复现完整过程
啰嗦两句: 提权之前完成是一个月前做的,当时在提权处出了点问题就搁置了,今天才完成,所以IP地址可能会会有变化 注意:后续出现的IP地址为192.168.200.55同样是靶机IP地址,若本文能有帮助到你的地方…...
Dubbo篇---第三篇
系列文章目录 文章目录 系列文章目录一、Dubbo 容错策略二、Dubbo 动态代理策略有哪些?三、说说 Dubbo 与 Spring Cloud 的区别?一、Dubbo 容错策略 failover cluster 模式 provider 宕机重试以后,请求会分到其他的 provider 上,默认两次,可以手动设置重试次数,建 议把写…...
Redis-使用java代码操作Redis->java连接上redis,java操作redis的常见类型数据存储,redis中的项目应用
java连接上redisjava操作redis的常见类型数据存储redis中的项目应用 1.java连接上redis package com.zlj.ssm.redis;import redis.clients.jedis.Jedis;/*** author zlj* create 2023-11-03 19:27*/ public class Demo1 {public static void main(String[] args) { // …...
react 使用笔记
1.学习:https://reactjs.bootcss.com/learn 2.项目启动报错:Delete ␍ prettier/prettier 解决:https://blog.csdn.net/qq_30272167/article/details/133280165 3.访问地址配置 文件:config-overrides.js devServer: functio…...
Ubuntu下启动Apache对.htaccess 的支持步骤, 利用.htaccess绑定域名到子目录
Ubuntu下启动Apache对.htaccess 的支持步骤 1. 终端运行 sudo a2enmod 程序提示可供激活的模块名称,输入: rewrite 2. 修改/etc/apache2/sites-enabled/000-default (该链接指向的是站点配置文件) 把(默认的www目录、或者需要应用.htacc…...
C++常用格式化输出
在C语言中可以用printf以一定的格式打印字符,C当然也可以。 输入输出及命名空间还不太了解的小伙伴可以看一看C入门讲解第一篇。 在C中,可以用流操作符(stream manipulators)控制数据的输出格式,这些流操作符定义在2…...
QCC TX 音频输入切换+提示声音
QCC TX 音频输入切换提示声音 QCC蓝牙芯片(QCC3040 QCC3056 等等),AUX、I2S、USB输入 蓝牙音频输入,模拟输出是最常见的方式。 也可以再此基础上动态切换输入方式。 针对TX切换EQ,调节音量不能出提示声音问题,可以增…...
【Java】封装、继承、多态
面向对象的重要特征:封装、继承、多态; 面向对象的语言的语言并不止Java,C也是面向对象的语言; 访问限定符 public:在哪里都可以使用(公开的);private:仅在当前类可以使用…...
第九章 异常处理
系列文章目录 第一章 Python 基础知识 第二章 python 字符串处理 第三章 python 数据类型 第四章 python 运算符与流程控制 第五章 python 文件操作 第六章 python 函数 第七章 python 常用内建函数 第八章 python 类(面向对象编程) 第九章 python 异常处理 第十章 python 自定…...
(四) Python Pandas入门
一、介绍 Pandas是Python中一个强大的数据处理库,它提供了许多功能强大的数据结构和数据分析工具。在本文中,我们将介绍Pandas的基本概念和如何使用它生成一个包含今天到未来20个工作日的日期列表的Excel文件。 Pandas提供了大量的数据结构和数据分析工…...
软件测试面试最经典的5个问题
软件测试面试灵魂五问! 请做一下自我介绍?你为什么从上家公司离职?为什么转行做测试? 你对测试行业的认识?你的期望薪资是多少?最后,你要问我什么? 一、请做一下自我介绍 简历上有的可以一两…...
从公共业务提取来看架构演进——功能设置篇
1.引言 上一篇文章我们以帐号权限的提取为例,介绍了当架构跟不上业务发展时及时调整架构的一种思路。这篇文章我们以功能设置为例,进一步讨论公共业务提取这个话题。 功能设置在本文中是指产品开放给企业和用户的一些功能设置项,以视频会议…...
Java基础-015-System.java常用类
Java基础-015-System.java常用类 1、标准输入输出2、获取属性3、System.java初始化4、设置标准输出System.out java/lang/System.java 1、标准输入输出 System.in、System.out public class Test {public static void main(String[] args) {String charsetName String.valueOf…...
Flutter笔记:发布一个模块 scale_design - (移动端)设计师尺寸适配工具
Flutter笔记 发布一个模块scale_design设计师尺寸适配工具与常用组件库 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/a…...
torch增加维度操作
使用none作为占位符 在Python中,None 表示空值或占位符。 在masked_pos[:, :, None]这个切片操作中,None 被用作一个占位符,以改变张量的维度。这通常用于将一维张量变为二维张量,或者改变张量的形状。 具体来说,ma…...
软件测试面试题及答案2024
1、你们的缺陷等级如何划分的?☆☆☆☆☆ 我们的缺陷一般分为四个等级,致命级,严重级,一般级和轻微级。致命级指能够导致软件程序无法使用的缺陷,比如宕机,崩溃,手机APP的闪退,数据…...
C现代方法(第18章)笔记——声明
文章目录 第18章 声明18.1 声明的语法18.2 存储类型18.2.1 变量的性质18.2.2 auto存储类型18.2.3 static存储类型18.2.4 extern存储类型18.2.5 register存储类型18.2.6 函数的存储类型18.2.7 小结 18.3 类型限定符18.4 声明符18.4.1 解释复杂声明18.4.2 使用类型定义来简化声明…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...
