uniapp中videojs、renderjs的使用
在uniapp中使用了某些前端库或iframe,需要操作这些库中的dom的时候, 而uni上又没有document等基础对象。也就无法操作这些dom去实现一些交互逻辑,那么,涉及到这些的前端类库就无法使用,例如html2、canvas、image、video。而要用这些怎么办,这是用就出现了renderjs这种视图层工具来进行渲染。大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力
使用方法:
- 在原有script下方再添加script,其中lang="renderjs"固定, module=“demo”,module的名字任意起
- 可以通过 this.$ownerInstance 获取当前组件的 ComponentDescriptor 实例。类似于vm
- 视图层绑定事件通过 module名称 . 逻辑层定义方法,有两个参数,1.事件对象event,2. 当前组件实例ComponentDescriptor
- 两个script间的通信需要通过:this.$ownerInstance 全局组件实例 或者 事件参数ComponentDescriptor 身上的callMethod方法,去抛出方法、传值,类似于vue组件间emit
- 可以使用 vue 组件的生命周期不可以使用 App、Page 的生命周期
使用参考:https://blog.csdn.net/dabaooooq/article/details/129272111
代码
uniapp在APP端video层级最高,不能被其它覆盖,引入videojs实现,使用renderjs实现原生的DOM操作。
<template><div class="full_screen_video" v-show="visible" :class="{ 'normal': !fullScreen }"><!-- 遮盖video 添加点击事件 --><div class="video_mask" @click="foldShortVideo" ></div><p v-if="fullScreen" class="back" @click="closeDialogHandle"><image src="@i/common/back_white.svg" alt=""></image><span>{{ title}}</span></p><view :info="videoItem" :change:info="videos.updateVideo" :options="videoOptions" :change:options="videos.optionsChange"class="video_box"ref="videoEle" id="videoEle"></view><view class="video_control_box" v-if="fullScreen" ><!-- 开始结束时间 --><view class="video_time"><span>{{ formatTime(videoCurrentTime) }} </span> <span>{{ formatTime(videoTotalTime) }}</span></view><!-- 视频播放器 --><div class="video_control"><p class="disp_ac"><image v-if="!isStart" src="@i/video/icon_video_start.svg" mode="widthFix" @tap="startAndStop('start')" alt=""></image><image v-else src="@i/video/icon_video_stop.svg" mode="widthFix" @tap="startAndStop('stop')" alt=""></image><image src="@i/video/icon_video_next.svg" mode="widthFix" @tap="playNext" alt="" v-if="videoList.length > 0"></image></p><p><view :class="{'normal_mode':normalMode}" class="formation_select_box mr60" @click="showOption = !showOption"><span class="select_text">{{ speedValue +'x'}}</span><view class="select_menu" :class="{ ani: showOption }" v-show="showOption"><view class="select_menu_item" v-for="item in speedOptions" :key="item.value"><span :class="{'active': speedValue === item.value}" @click="changeSpeed(item.value)">{{ item.label +'x'}}</span></view></view></view><image v-if="normalMode" src="@i/video/full_screen.svg" mode="widthFix" @tap="fullScreenVideo" alt=""></image></p></div></view><view v-else class="video_control_box video_control_box_small" ><div class="time_bar_box"><div class="time_btn"><image v-if="!isStart" src="@i/video/icon_video_start.svg" mode="widthFix" @tap="startAndStop('start')" alt=""></image><image v-else src="@i/video/icon_video_stop.svg" mode="widthFix" @tap="startAndStop('stop')" alt=""></image><image src="@i/video/icon_video_next.svg" mode="widthFix" @tap="playNext" alt="" v-if="videoList.length > 0"></image></div><div class="time_bar"><span>{{ formatTime(videoCurrentTime) }} </span> <span>{{ formatTime(videoTotalTime) }}</span></div></div><div class="video_btn"><view class="formation_select_box mr50" @click="showOption = !showOption"><span class="select_text">{{ speedValue +'x'}}</span><view class="select_menu" :class="{ ani: showOption }" v-show="showOption"><view class="select_menu_item" v-for="item in speedOptions" :key="item.value"><span :class="{'active': speedValue === item.value}" @click="changeSpeed(item.value)">{{ item.label +'x'}}</span></view></view></view> <image src="@i/video/download.svg" mode="widthFix" @tap="downloadVideo" alt=""></image><image v-if="normalMode" src="@i/video/full_screen.png" mode="widthFix" @tap="fullScreenVideo" alt=""></image></div></view><!-- 视频列表 --><div class="video_list" v-if="showVideoList && videoList.length" ><scroll-view scroll-x="true" ><div class="video_list_item"><div v-for="(item, index) in videoList" :key="index" class="video_item" :class="{'active': index === currentVideoIndex}" @click="playVideo(item, index)"><div class="video_img"><image class="snapshot" :src="item.snapshot && !item.imgError ? item.snapshot : defaultSnapshot" @error="item.imgError = true" alt="snapshot" ></image><span class="total_time" v-if="item.end && item.start">{{formatTime(item.end - item.start)}}</span></div><div class="clip_info"><div class="text_over">{{item.name || item.label || ''}}</div><div class="video_list_time">{{ formatDate(item.createTime).split('-').slice(0,3).join('/').split(' ').slice(0,1).join() }}</div></div></div></div></scroll-view></div></div>
</template><script>
export default {name: 'pad-video-play', // 在主视频内播放的组件,短片会跳转到主视频对应的时间props: {// 控制显示隐藏visible: {type: Boolean,default: false},// 主视频下的短视频播放列表videoList: {type: Array,default:() => []},// 主视频播放源videoMain: {type: Object,default: () => { }},// 视频类型, 默认为全屏播放videoType: {type: String,default: 'full_screen'},},data() {return {videoCurrentTime: 0, // 视频当前时间videoTotalTime: 0, // 视频总时长isStart: false, // 是否开始volumeValue: 1, // 音量初始值(0-1)showVideoList: true, // 是否显示视频列表currentVideoIndex: -1, // 当前播放的视频下标defaultSnapshot: require("static/images/video/default_snapshot.svg"), // 默认缩略图videoOptions: {closeDialog: false}, // 视频操作选项fullScreen: this.videoType === 'full_screen', // 是否是全屏speedValue: '1.0', // 初始播放速度showOption:false, // 控制倍速弹窗speedOptions: [ // 阵型选项{ label: '2.0', labelEn: '2.0', value: '2.0' },{ label: '1.5', labelEn: '1.5', value: '1.5' },{ label: '1.25', labelEn: '1.25', value: '1.25' },{ label: '1.0', labelEn: '1.0', value: '1.0' },{ label: '0.5', labelEn: '0.5', value: '0.5' },],videoItem: {},title:''};},computed: {// 是否是正常模式下的视频播放normalMode() {let boolean = this.videoType === 'normal';return boolean;}},watch: {currentVideoIndex(newVal) {this.$emit('change-video-index', newVal);},videoMain: {handler (newVal) { this.videoItem = {url: newVal.url}this.title = newVal.name },immediate: true,deep:true},visible(newVal) {if (newVal) { this.videoOptions = {closeDialog: false,volumeChangeOption: { volume: 1 } }this.volumeValue = 1;}}},methods: {foldShortVideo(){this.showVideoList = !this.showVideoList},// 关闭弹框closeDialogHandle () {this.videoOptions = {closeDialog: true}if (this.videoType === 'full_screen') {// setTimeout(() => { this.$emit('cancelVideo', false);// },100)} else {this.fullScreen = false;}this.showVideoList = false;this.$emit('update:visible',false)},// 开始视频onPlayerPlay() {this.speedValue = '1.0'this.isStart = true;},// 实时更新onTimeUpdate(currentTime){this.videoCurrentTime = currentTime;},// 暂停视频onPlayerPause() {this.isStart = false;},// 加载视频源数据onLoadedmetadata(totalTime) {this.videoTotalTime = totalTime;},// 开始或暂停视频startAndStop(type) {this.videoOptions = {startAndStopOption: { type }}},// 改变视频音量volumeChange(volume) {this.volumeValue = volume;this.videoOptions = {volumeChangeOption: { volume } }},// 播放视频playVideo(item, index) {this.speedValue = '1.0'// // 在正常模式播放下, 不可重复点击当前视频if (this.normalMode && item && this.currentVideoIndex === index) {return;}this.$set(this.videoItem, 'startTime', item.start);this.currentVideoIndex = index;this.videoList.forEach(item => {item.forceUpdate = false})item.forceUpdate = true},// 改变视频的速度changeSpeed(speed) {this.speedValue = speed || '1.0';this.videoOptions = {playbackRate: { speed }}},// 播放下一个playNext(){this.speedValue = '1.0'this.videoList.forEach(item => {item.forceUpdate = false})let index = this.currentVideoIndex;if(this.currentVideoIndex+1<this.videoList.length){ this.currentVideoIndex = index+1;this.$set(this.videoList[index+1],'forceUpdate',true)this.$set(this.videoList, index + 1, this.videoList[index + 1]);this.$set(this.videoItem, 'startTime', this.videoList[index+1].start);}else{ this.currentVideoIndex = 0;this.$set(this.videoList[0],'forceUpdate',true)this.$set(this.videoList, 0, this.videoList[0]);this.$set(this.videoItem, 'startTime', this.videoList[0].start);}},// 进入/退出 全屏视频fullScreenVideo() {this.fullScreen = !this.fullScreen;},// 格式化时间formatTime(result) {let h = Math.floor(result / 3600) < 10 ? "0" + Math.floor(result / 3600) : Math.floor(result / 3600);let m = Math.floor((result / 60) % 60) < 10 ? "0" + Math.floor((result / 60) % 60) : Math.floor((result / 60) % 60);let s = Math.floor(result % 60) < 10 ? "0" + Math.floor(result % 60) : Math.floor(result % 60);return Math.floor(result / 3600) == 0 ? m + ":" + s : h + ":" + m + ":" + s;},// 格式化日期formatDate(createTime){let date = new Date(createTime);let str = `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;return str;}}
};
</script><script module="videos" lang="renderjs">import './video-offset.js'; // videojs 引入import Videojs from 'video.js';import 'video.js/dist/video-js.css';export default {data() {return {videoPlayer: null, // 当前视频播放器}},mounted() {},methods: {// 初始化视频initVideoJS(item) {if(this.videoPlayer){this.videoPlayer.dispose();this.videoPlayer = null;}let that = this;let videoEle = document.createElement('video');videoEle.style = 'width:100%; height:100%';videoEle.setAttribute("class", "video-js vjs-big-play-centered");let videos = document.getElementById('videoEle');console.log(videos);videos.appendChild(videoEle)let option = {controls: true, // 是否显示控制条preload: 'auto', // 是否预加载视频数据muted: false, // 是否静音language: 'zh-CN', // 设置语言autoplay: true, // 自动播放, 正常模式下不进行自动播放sources: [ // 视频源{type: "video/mp4",src: item.url}, {type: "video/webm",// webm格式src: item.url}, {type: "video/mov", // mov格式src: item.url},],controlBar: { // 设置控制条组件children: [{ name: 'progressControl' }, // 播放进度条// // { name: 'fullscreenToggle' } // 全屏按钮]}};// video.js初始化实例化的对象this.videoPlayer = Videojs(videoEle, option, function onPlayerReady() {// 开始视频this.on('play', function() {that.$ownerInstance.callMethod('onPlayerPlay');})// 暂停视频this.on('pause', function() {that.$ownerInstance.callMethod('onPlayerPause');})// 实时更新this.on('timeupdate', function() {let currentTime = that.videoPlayer ? that.videoPlayer.currentTime() : 0;that.$ownerInstance.callMethod('onTimeUpdate', currentTime);})// 加载视频源数据this.on('loadedmetadata', function() {let totalTime = parseInt(that.videoPlayer.duration()) || 0;that.$ownerInstance.callMethod('onLoadedmetadata', totalTime);})});},// 监听 videoData 数据变更updateVideo(newValue) {if(!newValue || !newValue.url) return;if(this.videoPlayer && newValue.startTime){this.videoPlayer.currentTime(newValue.startTime)return}this.initVideoJS(newValue);},// 监听改变视频操作选项optionsChange(newValue) {if (newValue && newValue.startAndStopOption) {// 开始或暂停视频let { type } = newValue.startAndStopOption;type === 'start' ? this.videoPlayer.play() : this.videoPlayer.pause();} else if (newValue && newValue.volumeChangeOption) {// 改变视频音量let { volume } = newValue.volumeChangeOption;this.videoPlayer && this.videoPlayer.volume(volume);} else if (newValue && newValue.closeDialog) {console.log('销毁了')// 销毁videoJs实例this.videoPlayer && this.videoPlayer.dispose();this.videoPlayer = null} else if (newValue && newValue.continuePlay) {// 继续播放视频let { url } = newValue.continuePlay;this.initVideoJS(url);} else if(newValue && newValue.playbackRate){let { speed } = newValue.playbackRate;// 改变视频的播放速度this.videoPlayer && this.videoPlayer.playbackRate(speed);}}}}
</script><style lang='less' scoped>
.video_mask {position: absolute;width: 100%;height: calc(100% - 62.81rpx);top: 0;left: 0;background-color: transparent;z-index: 1;
}
::v-deep {// 视频style.video_box{width: 100%;height: 100%;video{object-fit:fill;}}.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar{opacity: 1;}.video-js{position: relative;.vjs-control-bar {width:663.32rpx;left: 43.34rpx;bottom: 47.9rpx;background-color: transparent;z-index: 105;opacity: 1;}.vjs-play-progress{background: #38CB89;&::before{color: #38CB89;}}.vjs-slider{background-color: rgba(255, 255, 255, 0.36);}}
}
.disp_ac{display: flex;align-items: center;
}
/* 文字超出部分设置为... */
.text_over {max-width: 85%;word-break: break-all;text-overflow: ellipsis;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 2; /* 这里是超出几行省略 */overflow: hidden;
}
.full_screen_video{width: 100%;height: 100%;position: fixed;z-index: 102;left: 0;top: 0;box-sizing: border-box;color: #fff;font-family: 'SysFontR';// 默认视频样式&.normal{width: 100%;height: 100%;position: relative;.video_list,.video_shrink{display: none;}.video_control_box{width: 100%;height: 37.69rpx;position: absolute;left: 0;bottom: 4.71rpx;z-index: 5;display: flex;flex-direction: column;align-items: center;padding: 0 10.05rpx;box-sizing: border-box;&.video_control_box_small{.formation_select_box{bottom: 7rpx;.select_text{font-size: 10.05rpx;}.select_menu{bottom:0;transform:scale(.8) }}}.time_bar_box{width: 100%;height: 12.25rpx;display: flex;align-items: center;.time_btn{image{width: 11.93rpx;height: 9.42rpx;margin-right: 10.05rpx;}}.time_bar{flex: 1;display: flex;justify-content:space-between;font-size: 9.74rpx;color: #f3f3f3;}}.video_btn{width: 100%;display: flex;justify-content: flex-end;text-align: right;margin-top: 6.28rpx;image{width: 10.99rpx;height: 10.05rpx;margin-right: 15.7rpx;}}}.video_control{height: 47.11rpx;bottom: 4.71rpx;image{width: 10.05rpx !important;height: 10.05rpx !important;margin-right: 15.7rpx;}}::v-deep {.vjs-control-bar{width: calc(100% - 74.75rpx - 37.69rpx);left: 76.75rpx;bottom: 27.84rpx;}}}.back{position: absolute;z-index: 200;top: 0;left: 0;width: 100%;height: 58.59rpx;padding-left: 14.64rpx;font-size: 13.82rpx;display: flex;align-items: center;cursor: pointer;background: linear-gradient(180deg, #000000 0%, rgba(0, 0, 0, 0) 100%);image{width: 6.44rpx;height: 12.3rpx;margin-right: 20.1rpx;}}.formation_select_box{position: relative;border-radius: 3.77rpx;display: flex;align-items: center;justify-content: center;&.normal_mode{right: 118rpx;}.select_text{font-family: 'AkrobatMedium';font-size: 11.31rpx;color: #fff;position: relative;}.select_menu {width: 43.66rpx;position: absolute;bottom: 18.04rpx;left: -13rpx;z-index: 999;padding: 13.82rpx 0 0;text-align: center;box-sizing: border-box;border-radius: 3.77rpx;background: #000000;color: #F3F3F3;.select_menu_item {position: relative;z-index: 2;margin-bottom: 12.56rpx;>span {display: inline-block;width: 100%;height: 100%;box-sizing: border-box;font-size: 10.05rpx;font-family: AkrobatRegular;&.active{color: #38CB89;}}}}.ani {animation: ani 0.2s;}@keyframes ani {0% {transform: scaleY(0);}100% {transform: scaleY(1);}}.mask_box {width: 70vw;height: 100vh;position: fixed;left: 0;top: 60rpx;z-index: 99;background: transparent;}}.video_time{position: absolute;bottom: 49.94rpx;width: 100%;box-sizing: border-box;padding:0 15.7rpx;line-height: 14.13rpx;display: flex;justify-content:space-between;z-index: 104;}.video_control{position: absolute;left: 0;z-index: 5;bottom: 5.85rpx;width: 161.13rpx;height: 35.15rpx;display: flex;align-items: center;justify-content: space-between;padding: 0 19.04rpx;box-sizing: border-box;width: 100%;p{display:flex;align-items: center;image{width: 17.59rpx;height: 17.59rpx;margin-right: 15.23rpx;// opacity: .6;}.video_volume{position: relative;.video_volume_slider{display: none;position: absolute;right: 30px;top: -85px;padding-top: 5px;background-color: rgba(0, 0, 0, 0.36);&.hover{display: inline-block;}}}}}.video_list{position: absolute;width: 100%;top: 0;right: 0;z-index: 201;background: rgba(29, 29, 29, 0.8);backdrop-filter: blur(50px);color: #fff;padding-top: 25.13rpx;padding-bottom: 6.28rpx;box-sizing: border-box;display: flex;// transition: all 200ms;.close_img{position: absolute;top: 50%;transform: translateY(-50%);right: 236.81rpx;width: 20.5rpx;height: 75rpx;}.video_item{width: 83.54rpx;flex-shrink: 0;display: flex;flex-direction: column;margin-left: 12.56rpx;box-sizing: border-box;display: flex;&.active{.text_over{font-family: SysFontM;color: #38CB89;}}.video_img{width: 100%;height: 47.11rpx;box-sizing: border-box;position: relative;image.snapshot{border-radius: 3.77rpx;width: 100%;height: 100%;}.total_time{font-family: SysFontR;height: 12.89rpx;position: absolute;left: 2.92rpx;bottom: 2.92rpx;padding: 0 5.85rpx;font-size: 8.2rpx;line-height: 12.89rpx;color: rgb(255, 255, 255);background: rgba(30, 30, 30, .6);}}.clip_info{width: 100%;box-sizing: border-box;font-size: 8.2rpx;color: rgba(255, 255, 255, .8);position: relative;padding: 4.71rpx 0;// .clip_label{// font-size: 10.68rpx;// color: rgba(255, 255, 255,1);// line-height: 14.06rpx;// margin-bottom: 7.54rpx;// display: flex;// align-items: center;// }}}}.video_list_item {display: flex;width: 100%;overflow-x: auto;}.video_shrink{position: fixed;top: 50%;transform: translateY(-50%);right: 0;width: 20.5rpx;height: 75rpx;}.video_list_time {font-family: AkrobatRegular;margin-top: 3px;}
}
</style>;
相关文章:
uniapp中videojs、renderjs的使用
在uniapp中使用了某些前端库或iframe,需要操作这些库中的dom的时候, 而uni上又没有document等基础对象。也就无法操作这些dom去实现一些交互逻辑,那么,涉及到这些的前端类库就无法使用,例如html2、canvas、image、vide…...

AIGC AI绘画 Midjourney 参数大全详细列表
AIGC ChatGPT 职场案例 AI 绘画 与 短视频制作, Power BI 商业智能 68集, 数据库Mysql8.0 54集 数据库Oracle21C 142集, Office 2021实战, Python 数据分析, ETL Informatica 案例实战 Excel 2021实操,函数大全,图表大全,大屏可视化制作 加技巧500集 数据分析可视化T…...

安装hadoop,并配置hue
0、说明 对于大数据学习的初始阶段,我也曾尝试搭建相应的集群环境。通过搭建环境了解组件的一些功能、配置、原理。 在实际学习过程中,我更多的还是使用docker来快速搭建环境。 这里记录一下我搭建hadoop的过程。 1、下载hadoop 下载地址:…...

23种经典设计模式:单例模式篇(C++)
前言: 博主将从此篇单例模式开始逐一分享23种经典设计模式,并结合C为大家展示实际应用。内容将持续更新,希望大家持续关注与支持。 什么是单例模式? 单例模式是设计模式的一种(属于创建型模式 (Creational Pa…...
ros中对move_base的调用
move_base包中自带costmap2d, global planner 等功能 也可以直接调用其中make_plan进行路径规划 #include "geometry_msgs/PoseStamped.h" #includde "nav_msgs/GetPlan.h"void fillPathRequest(nav_msgs::GetPlan::Request &request, float start_x…...

Git从本地库撤销已经添加的文件或目录
场景 在提交时, 误将一个目录添加到了暂存区, 而且commit 了本地库,同批次commit 的还有其他需要提交的文件。 commit 之后发现这个目录下所有的文件都不需要提交, 现在需要撤销这个提交, 使这个目录不被push到远端库。 这里以远端服务器github 为例,在Git GUI下看到的…...

百度SEO优化的特点(方式及排名诀窍详解)
百度SEO优化的特点介绍: 百度SEO优化是指对网站进行优化,使其在百度搜索引擎中获得更好的排名,进而获取更多的流量和用户。百度SEO优化的特点是综合性强、效果持久、成本低廉、投资回报高。百度的搜索算法不断更新,所以长期稳定的…...

Gin 文件上传操作(单/多文件操作)
参考地址: 单文件 | Gin Web Framework (gin-gonic.com)https://gin-gonic.com/zh-cn/docs/examples/upload-file/single-file/ 单文件 官方案例: func main() {router := gin.Default()// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)router.MaxMultipartMem…...

分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测
分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测 目录 分类预测 | MATLAB实现KOA-CNN-LSTM开普勒算法优化卷积长短期记忆神经网络数据分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现KOA-CNN-LSTM开普勒算法优化…...

Qt应用开发(基础篇)——列表视图 QListView
一、前言 QListView类继承于QAbstractItemView类,提供了一个列表或者图标视图的模型。 视图基类 QAbstractItemView QListView效果相当于Windows文件夹右键->查看->图标和列表,使用setViewMode()设置视图模式,并且提供setIconSize()函数…...

vue-6
一、声明式导航-导航链接 1.需求 实现导航高亮效果 如果使用a标签进行跳转的话,需要给当前跳转的导航加样式,同时要移除上一个a标签的样式,太麻烦!!! 2.解决方案 vue-router 提供了一个全局组件 router…...

温度在线检测技术在电力电缆线路的应用
在电力电缆的日常运行检测中,针对电缆温度的状况,所采用的电力温度在线检测技术也得到了大范围的普及。电网系统中,其单位时间内可输送的电力能源受到其温度的变化影响。因此,采用更有效的方式实时检测电缆系统运行温度࿰…...

2023年中国自动化微生物样本处理系统竞争现状及行业市场规模分析[图]
微生物检测能够对感染性疾病的病原体或者代谢物进行检测分析,是IVD的细分领域之一。2022年中国体外诊断市场规模1424亿元。 2015-2022年中国体外诊断市场规模 资料来源:共研产业咨询(共研网) 微生物检测由于样本类型多样…...
硬链接和软连接的区别
软链接(也称为软连接或符号链接)是一种特殊的文件,其内容是另一个文件的路径。当你使用软链接时,实际上是在操作另一个文件。软链接的优点是它可以跨文件系统使用,因此可以跨分区或磁盘链接文件。此外,软链…...

保护隐私与增强网络安全之网络代理技术
目录 前言 一、网络代理技术原理 二、网络代理技术类型 1. HTTP代理 2. SOCKS代理 3. DNS代理 4. 加密代理 5. 反向代理 三、网络代理技术应用 1. 加速网络访问速度 2. 绕过网络限制 3. 保护个人隐私 4. 节省带宽 5. 改善网络安全 四、网络代理技术优缺点 网络…...
【每日一题】CF1680C. Binary String | 双指针 | 简单
题目内容 原题链接 给定一个长度为 n n n 的 01 01 01 字符串,对于一个子串 s u b sub sub ,子串内部的 0 0 0 的数量为 x x x ,子串以外的 1 1 1 的数量为 y y y ,子串的代价为 m a x ( x , y ) max(x, y) max(x,y) &…...

10.selenium进阶
文章目录 1、嵌套网页1、1 什么是嵌套页面1、2 selenium获取嵌套页面的数据 2、执行JavaScript代码3、鼠标动作链4、selenium键盘事件5、其他方法5、1 选择下拉框5、2 弹窗的处理 6、selenium设置无头模式7、selenium应对检测小结 1、嵌套网页 在前端开发中如果有这么一个需…...

【安全】 Java 过滤器 解决存储型xss攻击问题
文章目录 XSS简介什么是XSS?分类反射型存储型 XSS(cross site script)跨站脚本攻击攻击场景解决方案 XSS简介 跨站脚本( cross site script )为了避免与样式css(Cascading Style Sheets层叠样式表)混淆,所以简称为XSS。 XSS是一种经常出现在web应用中的计算机安全…...

一、Excel VBA 是个啥?
Excel VBA 从入门到出门一、Excel VBA 是个啥?二、Excel VBA 简单使用 👋Excel VBA 是个啥? ⚽️1. Excel 中的 VBA 是什么?⚽️2. 为什么 VBA 很重要?⚽️3. 是否有无代码方法可以在 Excel 中实现工作流程自动化&…...
Spring Boot读取配置文件
Spring Boot 是一种用于快速构建基于Spring的应用程序的框架,它提供了很多便利的功能和约定,使开发者可以快速搭建、配置和部署应用程序。在Spring Boot中,读取配置文件是一个非常常见的任务,本文将介绍如何在Spring Boot应用程序…...

ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
LLaMA-Factory 微调 Qwen2-VL 进行人脸情感识别(二)
在上一篇文章中,我们详细介绍了如何使用LLaMA-Factory框架对Qwen2-VL大模型进行微调,以实现人脸情感识别的功能。本篇文章将聚焦于微调完成后,如何调用这个模型进行人脸情感识别的具体代码实现,包括详细的步骤和注释。 模型调用步骤 环境准备:确保安装了必要的Python库。…...