Android 列表视频滑动自动播放—滑动过程自动播放(实现思路)

本文基于Exoplayer +  PlayerView 实现列表视频显示一定比例后自动播放

首先引入google media3包

implementation 'androidx.media3:media3-exoplayer:1.1.1'
implementation 'androidx.media3:media3-exoplayer-dash:1.1.1'
implementation 'androidx.media3:media3-ui:1.1.1'
implementation "androidx.media3:media3-common:1.1.1"

列表自动播放,我们需要监听recyclerView.addOnScrollListener(this),并实现对应方法

onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) 中判断滑动过程中,展示视频itemVideoView比例

1、首先我们需要拿到recyclerView显示出来的itemPosition

int firstItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
int lastItemPosition = linearLayoutManager.findLastVisibleItemPosition();

2、当判断第一个(firstItemPosition)和最后一个(lastItemPosition)都大于0时候,开始遍历recyclerView数据,判断显示视频itemVideoView显示比例(因为我项目,视频播放数据是二维数组。RecyclerView1+RecyclerView2结构,所以视频播放时在里层RecyclerView2,如果不是二维,那么就RecyclerView2其实就是视频播放容器,dataItem.getVideoPosition()其实就是告诉我们RecyclerView2中第几条数据播放视频,默认是-1,表示没有视频,需要我们在网络请求后,遍历数据生成对应可以展示视频position)

 public void recyclerViewScrollVideo() {if (recyclerView == null || linearLayoutManager == null || communityPostListAdapter == null) {return;}int firstItemPosition = linearLayoutManager.findFirstVisibleItemPosition();int lastItemPosition = linearLayoutManager.findLastVisibleItemPosition();if (firstItemPosition >= 0 && lastItemPosition >= 0) {DataItem dataItem = communityPostListAdapter.getData(firstItemPosition);CommonViewHolder viewHolder = (CommonViewHolder) recyclerView.findViewHolderForAdapterPosition(firstItemPosition);if (viewHolder != null) {//当第一个显示数据,不支持播放视频时候,需要直接遍历后面,看是否有支持视频的//获取里层 RecyclerView ImageRecyclerView recyclerImage = viewHolder.getView(R.id.communal_post_header_recycler_image);if (dataItem != null && dataItem.getVideoPosition() >= 0 && recyclerImage != null) {//获取里层视频那个itemView positionint videoPosition = dataItem.getVideoPosition();CommonViewHolder itemViewHolder = (CommonViewHolder) recyclerImage.findViewHolderForAdapterPosition(videoPosition);//获取当前视频itemBenVideoAdapter videoAdapter = (CommunalImageAdapter) recyclerImage.getAdapter();//获取视频数据对象VideoDataBean videoDataBean = null;if (videoDataBean != null) {videoDataBean = videoAdapter.getData(videoPosition);}boolean isPlaying = ExoPlayerManager.getInstance().recyclerViewScrollVideo(recyclerImage, itemViewHolder, firstItemPosition, videoDataBean);if (!isPlaying) {//firstItemPosition不支持播放,则遍历RecyclerView数据判断下一个是否支持播放int newFirstItemPosition = firstItemPosition + 1;traversal(recyclerView, newFirstItemPosition, lastItemPosition);}} else {//有可能是多布局,则第一条数据,找不到视频播放view,那么我们需要遍历数据,从第二条数据开始找int newFirstItemPosition = firstItemPosition + 1;traversal(recyclerView, newFirstItemPosition, lastItemPosition);}}}}

3、当第一条不满足,开始遍历

 /*** 遍历寻找,屏幕显示可以播放视频的item** @param recycler* @param newFirstItemPosition* @param lastItemPosition*/private void traversal(RecyclerView recycler, int newFirstItemPosition, int lastItemPosition) {//标记是否找到视频-1,表示未找到视频int playPosition = -1;for (int i = newFirstItemPosition; i <= lastItemPosition; i++) {DataItem dataItem = communityPostListAdapter.getData(i);CommonViewHolder viewHolder = (CommonViewHolder) recycler.findViewHolderForAdapterPosition(i);if (viewHolder != null && dataItem != null && dataItem.getVideoPosition() >= 0) {RecyclerView recyclerImage = viewHolder.getView(R.id.communal_post_header_recycler_image);if (recyclerImage != null) {CommonViewHolder itemViewHolder = (CommonViewHolder) recyclerImage.findViewHolderForAdapterPosition(dataItem.getVideoPosition());//获取当前视频itemBenVideoAdapter videoAdapter = (CommunalImageAdapter) recyclerImage.getAdapter();VideoDataBean videoDataBean = null;if (videoAdapter != null) {videoDataBean = videoAdapter.getData(dataItem.getVideoPosition());}if (ExoPlayerManager.getInstance().recyclerViewScrollVideo(recyclerImage, itemViewHolder, i, communalImageBean)) {playPosition = i;break;}}}}if (playPosition == -1) {//都没有找到视频ExoPlayerManager.getInstance().stopVideo();}}

4、视频播放器单例(Exoplayer +  PlayerView)


public class ExoPlayerManager {private static volatile ExoPlayerManager inStance = null;ExoPlayer mExoPlayer;public ExoPlayerListener mExoPlayerListener;private UserPlayerView mUserPlayerView;//视频容器private FrameLayout mLayout;//loading viewprivate ProgressBar mLoading;//视频logoprivate ImageView mLogo;//点击播放按钮private ImageView mPlay;//计算RecyclerView显示位置private Rect mItemRect;//RecyclerView显示高度float visibleHeight;//RecyclerView内容高度float totalHeight;//RecyclerView 显示高度和高度比例float visibleRatio;int mItemPlayPosition;//视频播放数据对象VideoDataBean mVideoDataBean;//视频最先显示比例private float minRatio;/*** 监听*/private AnalyticsListener mAnalyticsListener = new AnalyticsListener() {@Overridepublic void onPlaybackStateChanged(EventTime eventTime, int state) {AnalyticsListener.super.onPlaybackStateChanged(eventTime, state);switch (state) {case Player.STATE_IDLE:  //未加载到资源,停止播放,包含无网也会执行if (mExoPlayerListener != null) {mExoPlayerListener.onVideoPlayIdle();} else {stopShowView();}showController();break;case Player.STATE_BUFFERING: //缓冲中if (mExoPlayerListener != null) {mExoPlayerListener.onVideoPlayBuffering(eventTime != null ? eventTime.currentPlaybackPositionMs : -1L);} else {loadingShowView();}break;case Player.STATE_READY:  //开始播放if (mExoPlayerListener != null) {mExoPlayerListener.onVideoPlay(eventTime != null ? eventTime.currentPlaybackPositionMs : -1L);} else {startShowView();}break;case Player.STATE_ENDED:  //播放结束,当循环播放时候,改方法不会被触发  onPositionDiscontinuity  DISCONTINUITY_REASON_AUTO_TRANSITIONif (mExoPlayerListener != null) {mExoPlayerListener.onVideoPlayerCompletion();}break;}}@Overridepublic void onPositionDiscontinuity(EventTime eventTime, Player.PositionInfo oldPosition, Player.PositionInfo newPosition, int reason) {AnalyticsListener.super.onPositionDiscontinuity(eventTime, oldPosition, newPosition, reason);if (mExoPlayerListener != null) {mExoPlayerListener.onVideoPlayerCompletion();} else {//循环播放了,显示时间if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) {showController();}}}@Overridepublic void onPlayerError(EventTime eventTime, PlaybackException error) {AnalyticsListener.super.onPlayerError(eventTime, error);if (mExoPlayerListener != null) {mExoPlayerListener.onVideoPlayerError(eventTime != null ? eventTime.currentPlaybackPositionMs : -1l);} else {Toast.makeText(CommonParam.getInstance().getApplication(), "网络异常", Toast.LENGTH_LONG).show();if (eventTime != null) {long currentPlaybackPositionMs = eventTime.currentPlaybackPositionMs;if (mVideoDataBean != null && currentPlaybackPositionMs > 0) {mVideoDataBean.setSeekToPositionMs(currentPlaybackPositionMs);}}//网络异常会执行--onPlayerError---onPlaybackStateChanged(1)----onIsPlayingChanged()stopShowView();}}};public static ExoPlayerManager getInstance() {if (inStance == null) {synchronized (ExoPlayerManager.class) {if (inStance == null) {inStance = new ExoPlayerManager();}}}return inStance;}private ExoPlayerManager() {init();}private void init() {//初始化exoPlayerif (mExoPlayer == null) {mExoPlayer = new ExoPlayer.Builder(CommonParam.getInstance().getApplication()).build();mExoPlayer.addAnalyticsListener(mAnalyticsListener);}// 设置重复模式// Player.REPEAT_MODE_ALL 无限重复// Player.REPEAT_MODE_ONE 重复一次// Player.REPEAT_MODE_OFF 不重复mExoPlayer.setRepeatMode(Player.REPEAT_MODE_ALL);setVolume(CommonParam.getInstance().isVideoVolumeChange());if (mItemRect == null) {mItemRect = new Rect();}if (mUserPlayerView == null) {mUserPlayerView = new UserPlayerView(CommonParam.getInstance().getApplication());ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);mUserPlayerView.setLayoutParams(layoutParams);}//设置视频填充模式  RESIZE_MODE_FILL 拉伸视频达到没有黑边效果,RESIZE_MODE_ZOOM:这个是居中填充效果mUserPlayerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH);minRatio = 9f / 16f;}/*** 获取视频View** @return*/public UserPlayerView getUserPlayerView() {return mUserPlayerView;}/*** 添加监听*/public void addAnalyticsListener() {if (mExoPlayer != null) {mExoPlayer.removeAnalyticsListener(mAnalyticsListener);mExoPlayer.addAnalyticsListener(mAnalyticsListener);}}/*** 移除监听*/public void removeAnalyticsListener() {if (mExoPlayer != null) {mExoPlayer.removeAnalyticsListener(mAnalyticsListener);}}/*** 视频显示尺寸修改** @param params* @param playerView* @param maxWidth   屏幕显示最大宽* @param width      视频真实宽* @param height     视频真实高*/public void disposeVideoSize(ViewGroup.LayoutParams params, View playerView, int maxWidth, float width, float height) {if (params != null && playerView != null) {if (width > 0 && height > 0) {if (height >= width) {int showWidth = (int) (maxWidth > 0 ? maxWidth : width);params.width = showWidth;params.height = showWidth;} else {params.width = maxWidth;float ratio = height / width;params.height = (int) ((ratio >= minRatio) ? ratio * maxWidth : minRatio * maxWidth);}} else if (maxWidth > 0) {params.width = maxWidth;params.height = maxWidth;} else {params.width = ViewGroup.LayoutParams.MATCH_PARENT;params.height = ViewGroup.LayoutParams.MATCH_PARENT;}playerView.setLayoutParams(params);}}/*** 获取当前列表布局控件,一会计算时候需要用** @param recyclerImage* @param itemViewHolder* @param communalImageBean*/public boolean recyclerViewScrollVideo(RecyclerView recyclerImage, CommonViewHolder itemViewHolder, int itemPlayPosition, CommunalImageBean communalImageBean) {if (recyclerImage != null && itemViewHolder != null && communalImageBean != null) {FrameLayout frameLayout = itemViewHolder.getView(R.id.video);ImageView logo = itemViewHolder.getView(R.id.logo);ImageView play = itemViewHolder.getView(R.id.play);ProgressBar loading = itemViewHolder.getView(R.id.loading);ImageView volume = itemViewHolder.getView(R.id.volume);setVolumeViewChange(volume);setVolume(CommonParam.getInstance().isVideoVolumeChange());return calculateVideoPlay(recyclerImage, frameLayout, play, logo, loading, itemPlayPosition, communalImageBean);}return false;}/*** 计算是否滑动自动播放视频** @param view* @param frameLayout* @param play* @param logo* @param loading* @param videoDataBean*/public boolean calculateVideoPlay(View view, FrameLayout frameLayout, ImageView play, ImageView logo, ProgressBar loading, int itemPlayPosition,VideoDataBean videoDataBean ) {view.getLocalVisibleRect(mItemRect);visibleHeight = mItemRect.bottom - mItemRect.top;totalHeight = view.getHeight();visibleRatio = visibleHeight / totalHeight;if (mItemRect.top >= 0 && visibleRatio > BaseConstantValue.VIDEO_START_VISIBLE_RATIO) {playVideo(frameLayout, play, logo, loading, itemPlayPosition, videoDataBean);return true;} else {//不满足播放if (play != null) {play.setVisibility(View.VISIBLE);}if (loading != null) {loading.setVisibility(View.GONE);}if (logo != null) {logo.setVisibility(View.VISIBLE);}if (frameLayout != null) frameLayout.removeAllViews();}return false;}/*** 满足播放视频,需要再判断,是不是已经还在播放当前视频** @param layout* @param play* @param logo* @param loading* @param itemPlayPosition* @param videoDataBean*/public void playVideo(FrameLayout layout, ImageView play, ImageView logo, ProgressBar loading, int itemPlayPosition, VideoDataBean videoDataBean) {if (mItemPlayPosition != itemPlayPosition) {//不满足当前播放那么需要停止播放,做部分资源保存if (videoDataBean != null && mExoPlayer.isPlaying()) {//视频已经播放位置videoDataBean.setSeekToPositionMs(mExoPlayer.getContentPosition());}//显示暂停不播布局stopShowView();//暂停播放stopVideo();}//重新复制相关控件mLayout = layout;mPlay = play;mLogo = logo;mLoading = loading;//获取当前播放状态,如果未播放,则直接设置资源播放,如果已经播放,则不做处理if (!mExoPlayer.isPlaying()) {//设置播放布局loadingShowView();//移除播放Viewif (mUserPlayerView != null) {ViewParent parent = mUserPlayerView.getParent();if (parent != null && parent instanceof FrameLayout) {((FrameLayout) parent).removeAllViews();}}//将PlayerView 添加 FrameLayout上if (layout != null) {layout.removeAllViews();layout.addView(mUserPlayerView);}if (videoDataBean != null) {String videoUrl = videoDataBean.getVideoUrl();long seekToPositionMs = videoDataBean.getSeekToPositionMs();long durationMs = videoDataBean.getDurationMs();mUserPlayerView.setVideoPosition(seekToPositionMs, durationMs);MediaItem mediaItem = MediaItem.fromUri(videoUrl != null ? videoUrl : "");mExoPlayer.setMediaItem(mediaItem, seekToPositionMs);}mUserPlayerView.setPlayer(mExoPlayer);mExoPlayer.prepare();
//            mExoPlayer.play();mExoPlayer.setPlayWhenReady(true);}mItemPlayPosition = itemPlayPosition;mVideoDataBean = videoDataBean;}public ExoPlayer exoPlayer() {return mExoPlayer;}/*** 是否正在播放** @return*/public boolean isPlaying() {return mExoPlayer != null ? mExoPlayer.isPlaying() : false;}/*** 获取当前播放进度** @return*/public long getCurrentPositionMs() {if (mExoPlayer != null && mExoPlayer.isPlaying()) {return mExoPlayer.getCurrentPosition();}return -1;}/*** 获取总时长** @return*/public long getDurationMs() {if (mExoPlayer != null) {return mExoPlayer.getDuration();}return 0l;}/*** 设置进度** @param seekToCurrentPositionMs*/public void seekTo(long seekToCurrentPositionMs) {if (mExoPlayer != null) {mExoPlayer.seekTo(seekToCurrentPositionMs);if (!isPlaying()) {mExoPlayer.play();}}}/*** 设置是否有视频控制器** @param useController*/private void setUseController(boolean useController) {mUserPlayerView.setUseController(useController);}/*** 绑定全屏播放** @param videoUrl* @param currentPositionMs* @return*/private UserPlayerView bindVideoFullScreen(String videoUrl, long currentPositionMs) {mItemPlayPosition = -1;mExoPlayer.setMediaItem(MediaItem.fromUri(videoUrl == null ? "" : videoUrl), currentPositionMs);mUserPlayerView.setPlayer(mExoPlayer);mExoPlayer.prepare();mVideoDataBean = null;return mUserPlayerView;}/*** 开始播放*/public void startVideo() {if (mExoPlayer != null && !mExoPlayer.isPlaying()) {mExoPlayer.play();}}/*** 开始播放*/public void startVideo(long currentPositionMs) {if (mExoPlayer != null && !mExoPlayer.isPlaying()) {mExoPlayer.seekTo(currentPositionMs);mExoPlayer.play();}}/*** 开始播放*/public void startVideo(String videoUrl, long currentPositionMs) {if (mExoPlayer != null) {if (!mExoPlayer.isPlaying()) {mExoPlayer.stop();}mExoPlayer.setMediaItem(MediaItem.fromUri(videoUrl == null ? "" : videoUrl), currentPositionMs);mUserPlayerView.setPlayer(mExoPlayer);mExoPlayer.prepare();mExoPlayer.play();}}/*** 暂停播放*/public void pauseVideo() {if (mExoPlayer != null && mExoPlayer.isPlaying()) {mExoPlayer.pause();}}/*** 停止播放*/public void stopVideo() {mItemPlayPosition = -1;if (mExoPlayer != null && mExoPlayer.isPlaying()) {if (mVideoDataBean != null) {mVideoDataBean.setSeekToPositionMs(mExoPlayer.getContentPosition());}mExoPlayer.stop();}releaseView();}/*** 页面关闭,释放资源*/public void releaseVideo() {if (mExoPlayer != null) {mExoPlayer.removeAnalyticsListener(mAnalyticsListener);mExoPlayer.release();mExoPlayer = null;}releaseView();}private void releaseView() {if (mUserPlayerView != null) {ViewParent parent = mUserPlayerView.getParent();if (parent != null && parent instanceof FrameLayout) {((FrameLayout) parent).removeAllViews();}}//将PlayerView 添加 FrameLayout上if (mLayout != null) {mLayout.removeAllViews();mLayout = null;}if (mPlay != null) {mPlay = null;}if (mLogo != null) {mLogo = null;}if (mLoading != null) {mLoading = null;}mVideoDataBean = null;}/*** 设置播放器是否开启声音** @param volumeChange*/public void setVolume(boolean volumeChange) {if (volumeChange) {//设置声音if (mExoPlayer.getVolume() == 0f) {AudioManager audioManager = (AudioManager) CommonParam.getInstance().getApplication().getSystemService(Context.AUDIO_SERVICE);float streamVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);float streamMaxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);float volume = (streamMaxVolume != 0 && streamVolume != 0) ? streamVolume / streamMaxVolume : 0.3f;mExoPlayer.setVolume(volume);}} else {//设置声音为0mExoPlayer.setVolume(0f);}CommonParam.getInstance().setVideoVolumeChange(volumeChange);}/*** 设置 音量开关状态** @param volumeView*/public void setVolumeViewChange(View volumeView) {if (volumeView != null) {volumeView.setSelected(CommonParam.getInstance().isVideoVolumeChange());}}/*** 视频正在播放,设置相关布局show or hide*/public void startShowView() {if (mLoading != null) {mLoading.setVisibility(View.GONE);}if (mLogo != null) {mLogo.setVisibility(View.GONE);}if (mPlay != null) {mPlay.setVisibility(View.GONE);}}/*** 视频正在加载中,设置相关布局show or hide*/public void loadingShowView() {if (mLoading != null) {mLoading.setVisibility(View.VISIBLE);}if (mLogo != null) {mLogo.setVisibility(View.VISIBLE);}if (mPlay != null) {mPlay.setVisibility(View.GONE);}}/*** 视频停止播放,设置相关布局show or hide*/public void stopShowView() {if (mLoading != null) {mLoading.setVisibility(View.GONE);}if (mLogo != null) {mLogo.setVisibility(View.VISIBLE);}if (mPlay != null) {mPlay.setVisibility(View.VISIBLE);}}/*** 显示视频控制器*/public void showController() {if (mUserPlayerView != null) {UserPlayerControlView controller = mUserPlayerView.getController();if (controller != null) {controller.show();}}}/*** 设置监听** @param exoPlayerListener*/public void setExoPlayerListener(ExoPlayerListener exoPlayerListener) {mExoPlayerListener = exoPlayerListener;}
}

5、建议我们在开发视频时自定义PlayerView,只需要把源码中,这三个文件拷贝一份,然后自己根据具体需求,实现对应功能。

①、PlayerView

②、PlayerControlView

③、PlayerControlViewLayoutManager

6、如果项目是appBarLayout+RecyclerView的话。我们需要对appBarLayout滑动事件进行监听,从而实现appBarLayout滑动,也能播放视频

  mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.BaseOnOffsetChangedListener() {@Overridepublic void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {//appBarLayout 滑动监听int newOffset = Math.abs(verticalOffset);if (mVerticalOffset != newOffset && adapter != null) {Fragment fragment = adapter .getFragment(viewPagerShowType);if (fragment != null && fragment.isOnResume()) {fragment.startVideo();}mVerticalOffset = newOffset;}}});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/43221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++深度探索】继承机制详解(二)

hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff1a;大耳朵土土垚的博客 &#x1…

Redis排行榜

long 整数长度总共有 19位&#xff0c;923XXX…&#xff0c;时间戳 毫秒精度 是 13位&#xff0c;所以只需 14 ~ 19 位存 等级&#xff0c;其他13位存时间。接下来看怎么存。 等级偏移&#xff1a; Math.power(10, 14) 10000000000000000&#xff08;14位&#xff09; 这里有一…

如何把已经上传到gitlab的代码或者文件夹从git上删掉

有小伙伴不小心把缓存文件上传到了git&#xff0c;跑来问我&#xff0c;要怎么把这些文件给删掉&#xff0c;这里一共有两种方式&#xff0c; 先说第一种&#xff0c;通过命令删除&#xff0c;终端进入存在这个缓存文件的目录&#xff0c;执行命令ls&#xff0c;可以看到确实有…

[C++][ProtoBuf][Proto3语法][二]详细讲解

目录 1.Any类型1.说明2.代码&使用 2.oneof类型1.说明2.代码&使用 3.map类型1.说明2.代码&使用 1.Any类型 1.说明 字段还可以声明为Any类型&#xff0c;可以理解为泛型类型 使⽤时可以在Any中存储任意消息类型 父类是Message Any类型的字段也可以⽤repeated来修饰…

从零开始搭建vite开发环境

准备 nodejs 18 pnpm https://vitejs.cn/ 开始 pnpm init pnpm add -D vite新建index.html <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width…

飞睿智能无线高速uwb安全数据传输模块,低功耗、抗干扰超宽带uwb芯片传输速度技术新突破

在信息化的时代&#xff0c;数据传输的速度和安全性无疑是每个企业和个人都极为关注的话题。随着科技的飞速发展&#xff0c;超宽带&#xff08;Ultra-Wideband&#xff0c;简称UWB&#xff09;技术凭借其性能和广泛的应用前景&#xff0c;逐渐成为了数据传输领域的新星。今天&…

JavaScript学习笔记(七)

45.9 JavaScript 可迭代对象 可迭代对象&#xff08;Iterables&#xff09;是可以使用 for..of 进行迭代的对象。 从技术上讲&#xff0c;可迭代对象必须实现 Symbol.iterator 方法。 45.9.1 遍历字符串 <body><p id"demo"></p><script>c…

使用vllm部署大语言模型

vLLM是一个快速且易于使用的库&#xff0c;用于LLM&#xff08;大型语言模型&#xff09;推理和服务。通过PagedAttention技术&#xff0c;vLLM可以有效地管理注意力键和值内存&#xff0c;降低内存占用和提高计算效率。vLLM能够将多个传入的请求进行连续批处理&#xff0c;从而…

PTrade常见问题系列5

回测失败&#xff1a;可用资源不足。 回测运行失败&#xff0c;错误码&#xff1a;2 错误信息&#xff1a;可用资源不足&#xff0c;请稍后在创建。 1、之前客户未限制客户容器使用内存和CPU&#xff0c;周末修改配置&#xff0c;限制了内存和CPU&#xff1b; 2、此报错是用户…

【Javascript】微信小程序项目结构目录详解

我白天是个 搞笑废物 表演不在乎 夜晚变成 忧伤怪物 撕扯着孤独 我曾经是个 感性动物 小心地感触 现在变成 无关人物 &#x1f3b5; 张碧晨/王赫野《何物》 微信小程序开发工具提供了一个便捷的开发环境&#xff0c;使开发者可以快速构建和部署小程序。在…

代码随想录算法训练营Day38|1049. 最后一块石头的重量 II , 494. 目标和 , 474.一和零

好久不见&#xff0c;兄弟们&#xff0c;我终于把期末考试考完了&#xff0c;现在已经放暑假回家了&#xff0c;开始恶补算法了&#xff0c;那么废话不多说&#xff0c;来看今天的内容 1049. 最后一块石头的重量 II&#xff1a;代码随想录 这道题目的意思就是给你一个数组表示每…

【Python】已解决:FileNotFoundError: [Errno 2] No such file or directory: ‘D:\1. PDF’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;FileNotFoundError: [Errno 2] No such file or directory: ‘D:\1. PDF’ 一、分析问题背景 在Python编程中&#xff0c;当你尝试打开一个不存在的文件时&…

索引唯一约束问题SQL

新增报错违反唯一约束条件 (JING_DIAN.SYS_C0096533) 【问题原因】 这个问题可能是由于在Oracle APEX中&#xff0c;虽然你创建了一个名为"ISEQ_520227"的索引&#xff0c;但是在插入数据时&#xff0c;违反了唯一约束条件。这可能是因为你的数据表中已经存在相同的…

压测引擎数据库设计(上)

压测引擎数据库设计&#xff08;上&#xff09; 引言 在当今快速发展的互联网时代&#xff0c;软件质量保证和性能测试变得尤为重要。自动化测试平台&#xff0c;提供了一套完整的解决方案&#xff0c;以确保软件产品在发布前能够满足性能和稳定性的要求。本文将深入探讨滴云自…

jmeter-beanshell学习6-beanshell生成测试报告

前面写了各种准备工作&#xff0c;内容组合用起来&#xff0c;应该能做自动化了&#xff0c;最后一步&#xff0c;生成一个报告&#xff0c;报告格式还是csv 报告生成的路径和文件&#xff0c;在用户参数写好&#xff0c;防止以后改路径或者名字&#xff0c;要去代码里面改。以…

[AHK V2]AHK能取消正常窗口的双击标题栏最大化事件吗?

问题&#xff1a; AHK能取消正常窗口的双击标题栏最大化事件吗&#xff1f; 解答&#xff1a; AutoHotkey (AHK)是一个强大的脚本语言&#xff0c;可以用来自定义键盘快捷键、鼠标操作等。如果你想阻止双击Windows标题栏进行最大化操作&#xff0c;你可以编写一个脚本来拦截…

Django自动生成Swagger接口文档 —— Python

1. 前言 当接口开发完成&#xff0c;紧接着需要编写接口文档。传统的接口文档通常都是使用Word或者一些接口文档管理平台进行编写&#xff0c;但此类接口文档维护更新比较麻烦&#xff0c;每次接口有变更&#xff0c;需要手动修改接口文档。在实际的工作中&#xff0c;经常会遇…

tomcat的优化和tomcat和nginx实现动静分离:

tomcat的优化 tomcat自身的优化 tomcat的并发处理能力不强。大项目不使用tomcat做为转发动态的中间件&#xff08;k8s集群&#xff0c;python&#xff0c;rubby&#xff09;&#xff0c;小项目会使用&#xff08;内部使用&#xff09;&#xff0c;动静分离。 优化tomcat的启动…

Python入门 2024/7/8

目录 数据容器 dict(字典&#xff0c;映射) 语法 定义字典字面量 定义字典变量 定义空字典 从字典中基于key获取value 字典的嵌套 字典的常用操作 新增元素 更新元素 删除元素 清空字典 获取全部的key 遍历字典 统计字典内的元素数量 练习 数据容器的通用操作…

linux环境下echo命令简单测试端口是否连通——筑梦之路

语法格式 echo > /dev/tcp/目标主机地址/端口号 示例 echo > /dev/tcp/example.com/80 当命令执行后&#xff0c;若端口是开放的&#xff0c;命令不会有任何输出并且会立即返回命令提示符&#xff1b;若端口未开放或连接失败&#xff0c;则可能由于网络问题、防火墙限…