Android平台轻量级RTSP服务模块技术对接说明
一、技术背景
随着内网无纸化办公、电子教室等应用场景对超低延迟音视频传输需求的日益增长,为避免用户或开发者单独部署 RTSP 或 RTMP 服务,大牛直播 SDK 推出了轻量级 RTSP 服务 SDK。该 SDK 能够将本地音视频数据(如摄像头、麦克风等)进行编码后,汇聚到内置 RTSP 服务中,对外提供可供拉流的 RTSP URL,适用于内网环境下对并发要求不高的场景。

二、技术特点

(一)支持的编码格式
-
视频编码:支持 H.264/H.265(Android H.265 硬编码)。
-
音频编码:支持 G.711 A 律、AAC。
(二)功能特性
-
协议支持:支持 RTSP 协议。
-
音量调节:Android 平台采集端支持实时音量调节。
-
视频编码:支持 H.264 特定机型硬编码及 H.265 特定机型硬编码。
-
音视频类型:支持纯音频、纯视频及音视频组合。
-
摄像头切换:支持采集过程中前后摄像头实时切换。
-
参数设置:支持帧率、关键帧间隔(GOP)、码率(bit-rate)设置。
-
水印功能:支持动态文字水印、png 水印。
-
快照功能:支持实时快照。
-
降噪处理:支持环境音、手机干扰等引起的噪音降噪处理、自动增益、VAD 检测。
-
外部数据对接:支持 YUV 数据(外部编码前视频数据)、PCM 数据(外部编码前音频数据)、外部 H.264、H.265 数据(外部编码后视频数据)以及外部 AAC 数据(外部编码后音频数据)对接。
-
录像功能:支持与录像 SDK 组合使用,实现录像相关功能。
-
其他:支持 RTSP 端口设置、RTSP 鉴权用户名及密码设置、获取当前 RTSP 服务会话连接数,兼容 Android 5.1 及以上版本。
三、技术对接
(一)系统要求
-
SDK 支持版本:Android 5.1 及以上版本。
-
支持的 CPU 架构:armv7、arm64、x86、x86_64。
(二)准备工作
-
文件放置:确保 SmartPublisherJniV2.java 放置于 com.daniulive.smartpublisher 包名下(可在其他包名下调用)。
-
库文件添加:将 smartavengine.jar 添加至工程中,并拷贝 libSmartPublisher.so 至工程目录。
-
权限配置:在 AndroidManifest.xml 中添加相关权限,具体如下:
<uses-permission android:name="android.permission.CAMERA"/> <uses-feature android:name="android.hardware.camera.autofocus" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> <uses-permission android:name="android.permission.VIBRATE" /> -
加载 so 库:
static {System.loadLibrary("SmartPublisher"); } -
配置 32/64 位库:在 build.gradle 中进行如下配置:
splits {abi {enable truereset()include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'universalApk true} } -
修改 app-name:如需集成至自有系统进行测试,可使用大牛直播 SDK 的 app name,授权版则按照授权 app name 正常使用。修改 app-name 可在 strings.xml 中进行如下操作:
xml复制
<string name="app_name">SmartPublisherSDKDemo</string>
(三)接口设计
1. SmartRTSPServerSDK 接口
| 调用描述 | 接口 | 接口描述 |
|---|---|---|
| 初始化 RTSP Server | InitRtspServer | 初始化 RTSP 服务器(与 UnInitRtspServer 配对使用,启动多个 RTSP 服务也只需调用一次,需在 OpenRtspServer 之前调用) |
| 创建一个 rtsp server | OpenRtspServer | 创建一个 RTSP 服务器,返回 RTSP 服务器句柄 |
| 设置端口 | SetRtspServerPort | 设置 RTSP 服务器监听端口,在 StartRtspServer 之前必须设置 |
| 设置鉴权用户名、密码 | SetRtspServerUserNamePassword | 设置 RTSP 服务器鉴权用户名和密码,可选设置 |
| 获取 rtsp server 当前会话数 | GetRtspServerClientSessionNumbers | 获取 RTSP 服务器当前的客户会话数,此接口必须在 StartRtspServer 之后调用 |
| 启动 rtsp server | StartRtspServer | 启动 RTSP 服务器 |
| 停止 rtsp server | StopRtspServer | 停止 RTSP 服务器 |
| 关闭 rtsp server | CloseRtspServer | 关闭 RTSP 服务器 |
| UnInit rtsp server | UnInitRtspServer | 反初始化 RTSP 服务器(与 InitRtspServer 配对使用,启动多个 RTSP 服务也只需调用一次) |
2. SmartRTSPServerSDK 供 Publisher 调用的接口
| 调用描述 | 接口 | 接口描述 |
|---|---|---|
| 设置 rtsp 的流名称 | SetRtspStreamName | 设置 RTSP 的流名称 |
| 给要发布的 rtsp 流设置 rtsp server | AddRtspStreamServer | 给要发布的 RTSP 流设置 RTSP 服务器,一个流可发布到多个 RTSP 服务器上,服务器的创建启动参考 OpenRtspServer 和 StartRtspServer 接口 |
| 清除设置的 rtsp server | ClearRtspStreamServer | 清除设置的 RTSP 服务器 |
| 启动 rtsp 流 | StartRtspStream | 启动 RTSP 流 |
| 停止 rtsp 流 | StopRtspStream | 停止 RTSP 流 |
(四)接口调用详解
1. 初始化 SDK
在应用的 onCreate() 方法中,调用 LibPublisherWrapper 的 initialize_sdk() 方法进行 SDK 初始化:
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);context_ = this.getApplicationContext();libPublisher = new SmartPublisherJniV2();LibPublisherWrapper.RTSPServer.initialize_sdk(libPublisher, context_);
}
封装代码如下:
public static boolean initialize_sdk(SmartPublisherJniV2 lib_publisher, android.content.Context context) {return sdk_context_.initialize(lib_publisher, context);
}
具体实现逻辑:
public boolean initialize(SmartPublisherJniV2 lib_publisher, android.content.Context context) {if (initialized_) return initialized_result_;if (null == lib_publisher) return false;if (null == context) return false;synchronized (this) {if (initialized_) return initialized_result_;try {int sdk_ret = lib_publisher.InitRtspServer(context);if (0 == sdk_ret) {initialized_result_ = true;} else {initialized_result_ = false;Log.e(TAG, "call sdk InitRtspServer failed, ret:" + sdk_ret);}} catch (Exception e) {initialized_result_ = false;Log.e(TAG, "call sdk InitRtspServer Exception:", e);}initialized_ = true;return initialized_result_;}
}
2. 启动与停止 RTSP 服务
通过按钮点击事件启动或停止 RTSP 服务:
class ButtonRtspServiceListener implements View.OnClickListener {public void onClick(View v) {if (!rtsp_server_.empty()) {rtsp_server_.reset();btnRtspService.setText("启动RTSP服务");btnRtspPublisher.setEnabled(false);return;}Log.i(TAG, "onClick start rtsp service..");int port = 8554;String user_name = null;String password = null;LibPublisherWrapper.RTSPServer.Handle server_handle = LibPublisherWrapper.RTSPServer.create_and_start_server(libPublisher, port, user_name, password);if (null == server_handle) {Log.e(TAG, "启动rtsp server失败! 请检查设置的端口是否被占用!");return;}rtsp_server_.reset(server_handle);btnRtspService.setText("停止RTSP服务");btnRtspPublisher.setEnabled(true);}
}
3. 发布与停止 RTSP 流
同样通过按钮点击事件控制 RTSP 流的发布与停止:
class ButtonRtspPublisherListener implements View.OnClickListener {public void onClick(View v) {if (stream_publisher_.is_rtsp_publishing()) {stopRtspPublisher();btnRtspPublisher.setText("发布RTSP流");btnGetRtspSessionNumbers.setEnabled(false);btnRtspService.setEnabled(true);return;}Log.i(TAG, "onClick start rtsp publisher..");InitAndSetConfig();String rtsp_stream_name = "stream1";stream_publisher_.SetRtspStreamName(rtsp_stream_name);stream_publisher_.ClearRtspStreamServer();stream_publisher_.AddRtspStreamServer(rtsp_server_.get_native());if (!stream_publisher_.StartRtspStream()) {stream_publisher_.try_release();Log.e(TAG, "调用发布rtsp流接口失败!");return;}startAudioRecorder();startLayerPostThread();btnRtspPublisher.setText("停止RTSP流");btnGetRtspSessionNumbers.setEnabled(true);btnRtspService.setEnabled(false);}
}
停止 RTSP 流的实现:
private void stopRtspPublisher() {stream_publisher_.StopRtspStream();stream_publisher_.try_release();if (!stream_publisher_.is_publishing()) {stopAudioRecorder();}
}
4. 配置与初始化
在发布 RTSP 流之前,需要进行相关配置与初始化:
private void InitAndSetConfig() {if (null == libPublisher) return;if (!stream_publisher_.empty()) return;Log.i(TAG, "InitAndSetConfig video width: " + video_width_ + ", height" + video_height_ + " imageRotationDegree:" + cameraImageRotationDegree_);int audio_opt = 1;long handle = libPublisher.SmartPublisherOpen(context_, audio_opt, 3, video_width_, video_height_);if (0 == handle) {Log.e(TAG, "sdk open failed!");return;}Log.i(TAG, "publisherHandle=" + handle);int fps = 25;int gop = fps * 3;initialize_publisher(libPublisher, handle, video_width_, video_height_, fps, gop);stream_publisher_.set(libPublisher, handle);
}
初始化编码参数等设置:
private boolean initialize_publisher(SmartPublisherJniV2 lib_publisher, long handle, int width, int height, int fps, int gop) {// 编码类型设置if (videoEncodeType == 1) {// H.264 硬件编码设置} else if (videoEncodeType == 2) {// HEVC 硬件编码设置}// 软件编码可变比特率模式设置boolean is_sw_vbr_mode = true;if (is_sw_vbr_mode) {int is_enable_vbr = 1;int video_quality = LibPublisherWrapper.estimate_video_software_quality(width, height, true);int vbr_max_kbps = LibPublisherWrapper.estimate_video_vbr_max_kbps(width, height, fps);lib_publisher.SmartPublisherSetSwVBRMode(handle, is_enable_vbr, video_quality, vbr_max_kbps);}// 音频编码类型设置if (is_pcma_) {lib_publisher.SmartPublisherSetAudioCodecType(handle, 3);} else {lib_publisher.SmartPublisherSetAudioCodecType(handle, 1);}// 其他参数设置lib_publisher.SetSmartPublisherEventCallbackV2(handle, new EventHandlerPublisherV2().set(handler_, record_executor_));lib_publisher.SmartPublisherSetSWVideoEncoderProfile(handle, 3);lib_publisher.SmartPublisherSetSWVideoEncoderSpeed(handle, 2);lib_publisher.SmartPublisherSetGopInterval(handle, gop);lib_publisher.SmartPublisherSetFPS(handle, fps);boolean is_noise_suppression = true;lib_publisher.SmartPublisherSetNoiseSuppression(handle, is_noise_suppression ? 1 : 0);boolean is_agc = false;lib_publisher.SmartPublisherSetAGC(handle, is_agc ? 1 : 0);int echo_cancel_delay = 0;lib_publisher.SmartPublisherSetEchoCancellation(handle, 1, echo_cancel_delay);return true;
}
5. 获取 RTSP 会话数
提供获取当前 RTSP 会话数的功能:
class ButtonGetRtspSessionNumbersListener implements View.OnClickListener {public void onClick(View v) {if (rtsp_server_.is_running()) {int session_numbers = rtsp_server_.get_client_session_number();Log.i(TAG, "GetRtspSessionNumbers: " + session_numbers);PopRtspSessionNumberDialog(session_numbers);}}
}
封装实现:
public int get_client_session_number() {if (!is_running()) return 0;if (null == lib_publisher_) return 0;long handle = native_handle_.get();if (0 == handle) return 0;try {int ret = lib_publisher_.GetRtspServerClientSessionNumbers(handle);return ret;} catch (Exception e) {Log.e(TAG, "RTSPServer.Handle.get_client_session_number Exception:", e);return 0;}
}
6. 数据投递
以 Camera2 采集为例,进行数据投递:
@Override
public void onCameraImageData(Image image) {// 数据处理与投递for (LibPublisherWrapper i : publisher_array_) {i.PostLayerImageYUV420888ByteBuffer(0, 0, 0,planes[0].getBuffer(), y_offset, planes[0].getRowStride(),planes[1].getBuffer(), u_offset, planes[1].getRowStride(),planes[2].getBuffer(), v_offset, planes[2].getRowStride(), planes[1].getPixelStride(),w, h, 0, 0,scale_w, scale_h, scale_filter_mode, rotation_degree);}
}
音频采集与投递:
void startAudioRecorder() {if (audio_recorder_ != null) return;audio_recorder_ = new NTAudioRecordV2(this);Log.i(TAG, "startAudioRecorder call audio_recorder_.start()+++...");audio_recorder_callback_ = new NTAudioRecordV2CallbackImpl(stream_publisher_, null);audio_recorder_.AddCallback(audio_recorder_callback_);if (!audio_recorder_.Start(is_pcma_ ? 8000 : 44100, 1)) {audio_recorder_.RemoveCallback(audio_recorder_callback_);audio_recorder_callback_ = null;audio_recorder_ = null;Log.e(TAG, "startAudioRecorder start failed.");} else {Log.i(TAG, "startAudioRecorder call audio_recorder_.start() OK---...");}
}void stopAudioRecorder() {if (null == audio_recorder_) return;Log.i(TAG, "stopAudioRecorder+++");audio_recorder_.Stop();if (audio_recorder_callback_ != null) {audio_recorder_.RemoveCallback(audio_recorder_callback_);audio_recorder_callback_ = null;}audio_recorder_ = null;Log.i(TAG, "stopAudioRecorder---");
}
回调音频数据投递:
private static class NTAudioRecordV2CallbackImpl implements NTAudioRecordV2Callback {private WeakReference<LibPublisherWrapper> publisher_0_;private WeakReference<LibPublisherWrapper> publisher_1_;public NTAudioRecordV2CallbackImpl(LibPublisherWrapper publisher_0) {if (publisher_0 != null)publisher_0_ = new WeakReference<>(publisher_0);}private final LibPublisherWrapper get_publisher_0() {if (publisher_0_ != null)return publisher_0_.get();return null;}@Overridepublic void onNTAudioRecordV2Frame(ByteBuffer data, int size, int sampleRate, int channel, int per_channel_sample_number) {LibPublisherWrapper publisher_0 = get_publisher_0();if (publisher_0 != null)publisher_0.OnPCMData(data, size, sampleRate, channel, per_channel_sample_number);}
}
7. 释放资源
在 onDestroy() 方法中,释放相关资源:
@Override
protected void onDestroy() {Log.i(TAG, "activity destory!");stopAudioRecorder();stopRtspPublisher();stream_publisher_.release();rtsp_server_.reset();LibPublisherWrapper.RTSPServer.deinitialize_sdk(libPublisher);stopLayerPostThread();if (camera2Helper != null) {camera2Helper.release();}super.onDestroy();
}
四、总结
以上为 Android 平台轻量级 RTSP 服务模块的详细技术对接说明。该模块不仅支持编码前音视频数据的对接,还支持编码后音视频数据的对接,并可与本地录像、快照等功能组合使用,以满足多样化的应用场景需求。开发者可根据实际需求进行集成与开发,如有任何疑问或需要进一步探讨,欢迎与我们联系。
相关文章:
Android平台轻量级RTSP服务模块技术对接说明
一、技术背景 随着内网无纸化办公、电子教室等应用场景对超低延迟音视频传输需求的日益增长,为避免用户或开发者单独部署 RTSP 或 RTMP 服务,大牛直播 SDK 推出了轻量级 RTSP 服务 SDK。该 SDK 能够将本地音视频数据(如摄像头、麦克风等&…...
代码随想录第二十天|二叉树part08--669.修建二叉搜索树、108.将有序数组转换为二叉搜索树、538.把二叉搜索树转换为累加树
刷题小记: 上期学习了二叉搜索树的插入和删除操作,这次学习如何按区间修剪二叉搜索树。还有两题,关于借助二叉搜索树的有序特性进行转换。 669.修剪二叉搜索树(669.修剪二叉搜索树) 题目分析: 给定一个…...
RoCEv2 高性能传输协议与 Lossless 无损网络
目录 文章目录 目录RoCERoCEv2 v.s. IBRoCEv2 协议栈RoCEv2 需要 Lossless NetworkLossless Network 拥塞控制技术网络拥塞的原因PFC 基于优先级的流量控制PFC Unfairness (带宽分配不公平)的问题PFC HOL(队头拥塞)的问题PFC Dead…...
C语言多人聊天室 ---chat(客户端聊天)
head.h #ifndef __HEAD_H #define __HEAD_H// 常用头文件 #include <stdio.h> #include <stdlib.h> #include <string.h>// 网络编程涉及的头文件 #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h>#include <…...
联想 SR590 服务器 530-8i RAID 控制器更换损坏的硬盘
坏了的硬盘会自动亮黄灯。用一个空的新盘来替换,新盘最好不要有东西。但是有东西可能也没啥,因为我看 RAID 控制器里有格式化的选项 1. 从 IPMI 把服务器关机,电源键进入绿色闪烁状态 2. 断电,推开塑料滑块拉出支架,…...
城电科技|会追日的智能花,光伏太阳花开启绿色能源新篇章
当艺术与科技相遇,会碰撞出怎样的火花?城电科技推出的光伏太阳花,以其独特的设计与智能化的功能,给出了答案。这款产品不仅具备太阳能发电的实用功能,更是一件充满科技属性的艺术性光伏产品,吸引了广泛关注…...
基于YOLO11深度学习的苹果叶片病害检测识别系统【python源码+Pyqt5界面+数据集+训练代码】
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...
FFmpeg 命令行全解析:高效音视频处理从入门到精通
FFmpeg FFmpeg 是一款开源的多媒体处理工具集,支持音视频编解码、格式转换、流媒体处理等全链路操作。核心功能与工具: 多媒体全链路支持 支持 1000+ 音视频编解码格式(如 H.264、HEVC、AV1)和协议(RTMP、RTSP、HLS),覆盖录制、转码、流化等全流程。提供三大核心工具: …...
kafka数据拉取和发送
文章目录 一、原生 KafkaConsumer1、pom文件引入kafka2、拉取数据3、发送数据二、在spring boot中使用@KafkaListener1、添加依赖2、application.yml3、消息拉取:consumer4、自定义ListenerContainerFactory5、消息发送:producer6、kafka通过clientId鉴权时的鉴权失败问题一、…...
多智能体框架
多个不同的角色的Agent,共同完成一份复杂的工作。由一个统筹管理的智能体,自主规划多个智能体分别做什么,以及执行的顺序。 agent 应该包含的属性 执行特定任务 根据其角色和目标做出决策 能够使用工具来实现目标 与其他代理沟通和协作 保留…...
C++ 正则表达式分组捕获入门指南
在 C 中,正则表达式(regex)是一种用于匹配字符串模式的强大工具。正则表达式不仅能帮助你查找符合特定模式的字符,还能捕获匹配的子字符串(即分组捕获)。这篇文章将介绍 C 正则表达式中的分组捕获机制&…...
C#中级教程(1)——解锁 C# 编程的调试与错误处理秘籍
一、认识错误:编程路上的 “绊脚石” 在 C# 编程中,错误大致可分为两类:语法错误和语义错误(逻辑错误)。语法错误就像是写作文时的错别字和病句,编译器一眼就能识别出来,比如变量名拼写错误、符…...
Jmeter接口并发测试
Apache JMeter 是一款开源的性能测试工具,广泛用于接口并发测试、负载测试和压力测试。以下是使用 JMeter 进行接口并发测试的详细步骤: 一、准备工作 安装 JMeter 下载地址:Apache JMeter 官网 确保已安装 Java 环境(JMeter 依…...
MySQL-增删改查
一、Create(创建) 📖 语法: INSERT INTO table_name(value_list); 当我们使用表的时候,就可以使用这个语法来向表中插入元素~ 我们这边创建一个用于示范的表(Student)~ create table student( id int, name varchar(20), chinese int, math…...
开源堡垒机 JumpServer 社区版实战教程:发布机的配置与Website资产配置使用
文章目录 开源堡垒机 JumpServer 社区版实战教程:发布机的配置与Website资产配置使用一、功能简述二、应用发布机2.1 版本要求2.2 创建应用发布机2.2.1 通过WinRM的协议进行应用发布机的创建2.2.2 通过OpenSSH的协议进行应用发布机的创建2.2.2.1 下载OpenSSH2.2.2.2…...
【STM32】使用电打火器测试火焰传感器,去掉传感器LED依然亮
项目需求:火焰传感器识别到火焰后,LED灯闪烁,然后熄灭。 现象描述:不需要火焰传感器,当使用电打火器时电路板LED灯也会闪烁。(详情看底部视频) fire.h #ifndef __FIRE_H #define __FIRE_H …...
代码随想录算法训练day64---图论系列8《拓扑排序dijkstra(朴素版)》
代码随想录算法训练 —day64 文章目录 代码随想录算法训练前言一、53. 117. 软件构建—拓扑排序二、47. 参加科学大会---dijkstra(朴素版)总结 前言 今天是算法营的第64天,希望自己能够坚持下来! 今天继续图论part!今…...
机器学习数学基础:32.斯皮尔曼等级相关
斯皮尔曼等级相关教程 一、定义与原理 斯皮尔曼等级相关系数(Spearman’s rank - correlation coefficient),常用 ρ \rho ρ表示,是一种非参数统计量,用于衡量两个变量的等级之间的关联程度。它基于变量的秩次&…...
《论区块链技术及应用》审题技巧 - 系统架构设计师
区块链技术及应用论题写作框架 一、考点概述 本论题“区块链技术及应用”主要考察软件测试工程师对区块链技术的理解及其在软件项目中的实际应用能力。论题涵盖了多个关键方面,首先要求考生对区块链技术有全面的认识,包括但不限于其作为分布式记账技术…...
2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷(四)
2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷(四) 第一部分:网络平台搭建与设备安全防护任务书第二部分:网络安全事件响应、数字取证调查、应用程序安全任务书任务 1:应急响应&…...
单片机的串口(USART)
Tx - 数据的发送引脚,Rx - 数据的接受引脚。 串口的数据帧格式 空闲状态高电平,起始位低电平,数据位有8位校验位,9位校验位,停止位是高电平保持一位或者半位,又或者两位的状态。 8位无校验位传输一个字节…...
Modelfile配置说明
参数说明翻译 参数描述值类型示例用法mirostat启用Mirostat采样以控制困惑度。(默认:0,0禁用,1Mirostat,2Mirostat 2.0)intmirostat 0mirostat_eta影响算法对生成文本反馈的响应速度。较低的学习率将导致调…...
pnpm的基本用法
以下是 pnpm 的核心命令和使用指南,涵盖从安装依赖到项目管理的常见操作: 1. 基础命令 (1) 安装依赖 pnpm install # 安装 package.json 中的所有依赖 pnpm install <包名> # 安装指定包(自动添加到 dependencies…...
动态规划(背包问题)--是否逆序使用的问题--二进制拆分的问题
动态规划(背包问题) 题目链接01背包代码 完全背包问题代码 多重背包问题 I代码 什么时候适用逆序多重背包问题 II(超百万级的复杂度)代码 关于二进制拆分 题目链接 01背包 代码 #include <iostream> #include <vector&…...
Vue 中动态实现进度条
在 Vue 中动态实现进度条,基本上有两种常见的方法:直接通过 Vue 数据绑定控制样式,或者利用外部库来实现更复杂的功能。我们会深入探讨这两种方式,并且详细说明每种方法的实现步骤、优缺点以及使用场景。 1. 使用 Vue 数据绑定来…...
如何基于PyTorch做二次开发
基于PyTorch进行二次开发以实现可视化工程,可以从以下几个方面入手:模型结构可视化、训练过程监控、特征可视化等。以下是一些推荐的GitHub项目,这些项目可以帮助你快速搭建一个可视化的工程环境: ### 1. **PyTorch CNN Visualiz…...
Mac 版 本地部署deepseek ➕ RAGflow 知识库搭建流程分享(附问题解决方法)
安装: 1、首先按照此视频的流程一步一步进行安装:(macos版)ragflowdeepseek 私域知识库搭建流程分享_哔哩哔哩_bilibili 2、RAGflow 官网文档指南:https://ragflow.io 3、RAGflow 下载地址:https://github.com/infi…...
算法——后缀平衡树
先回想一下之前讨论的内容。之前我们详细讨论了后缀树,包括它的构建、应用以及相关算法。用户可能是在了解后缀树之后,想要进一步探索相关的数据结构,或者是想比较后缀树和后缀平衡树的异同。 后缀平衡树并不是一个常见的数据结构名称&#…...
姿态矩阵/旋转矩阵/反对称阵
物理意义,端点矢量角速率叉乘本身向量; 负号是动系b看固定系i是相反的; 一个固定 在惯性导航解算中,旋转矢量的叉乘用于描述姿态矩阵的微分方程。你提到的公式中, ω i b b \boldsymbol{\omega}_{ib}^b \times ωibb…...
【大语言模型】【整合版】DeepSeek 模型提示词学习笔记(散装的可以看我之前的学习笔记,这里只是归纳与总结了一下思路,内容和之前发的差不多)
以下是个人笔记的正文内容: 原文在FlowUs知识库上,如下截图。里面内容和这里一样,知识排版好看一点 一、什么是 DeepSeek 1. DeepSeek 简介 DeepSeek 是一家专注于通用人工智能(AGI)的中国科技公司,主攻大模型研发与…...
