当前位置: 首页 > article >正文

Unity3D开发AI桌面精灵/宠物系列 【三】 语音识别 ASR 技术、语音转文本多平台 - 支持科大讯飞、百度等 C# 开发

Unity3D 交互式AI桌面宠物开发系列【三】ASR 语音识别


该系列主要介绍怎么制作AI桌面宠物的流程,我会从项目开始创建初期到最终可以和AI宠物进行交互为止,项目已经开发完成,我会仔细梳理一下流程,分步讲解。 这篇文章主要讲有关于语音识别 ASR 方面的一些方法。


提示:内容纯个人编写,欢迎评论点赞,来指正我。

文章目录

  • Unity3D 交互式AI桌面宠物开发系列【三】ASR 语音识别
  • 前言
  • 一、语音识别 (ASR) 概述
  • 二、Unity开发准备阶段
    • 1.Unity平台
    • 2.示例:讯飞平台
  • 三、科大讯飞 ASR 短语音识别API
    • 1. 创建应用
    • 2. 查看免费测试服务量
    • 3. 查看 WebSocket 接口信息
    • 4. API 开发文档查看
  • 四、功能开发阶段
    • 1. Unity界面开发
    • 2. 代码分析
    • 3. 代码片段
    • 4. 数据配置
    • 5. 效果展示
    • 6. 问题反馈
    • 然后就,大功告成了!!!
  • 总结


前言

本篇内容主要讲Unity开发桌面宠物的语音识别功能,大家感兴趣也可以了解一下这个开发方向,目前还是挺有前景的,AI智能科技发展这么迅猛,紧跟步伐哈~

下面让我们出发吧 ------------>----------------->


一、语音识别 (ASR) 概述

语音识别(Automatic Speech Recognition,ASR)是一种技术,指的是通过计算机程序和算法,将人类所说的语音信号转化为文字或其他形式的电子文本的过程。ASR系统通过分析语音信号中包含的声音波形、频谱和语音特征等信息,识别并转录出语音中所包含的文字内容。这项技术在语音识别软件、智能语音助手、语音搜索、电话客服系统等领域有着广泛的应用。

在这里插入图片描述

二、Unity开发准备阶段

1.Unity平台

  • 该系列全部使用Unity2021.3.44开发;
  • 该系列前后文章存在关联,不懂的可以看前面文章;
  • 该系列完成之后我会上传源码工程,着急的小伙伴可以自己写框架,我就先编写各模块的独立功能。

2.示例:讯飞平台

  • 注册讯飞账户,已注册的直接登录;
  • 创建语音识别应用,然后 领取 语音识别 (短语音识别) 免费测试服务量绑定该应用,或者付费购买服务量;(个人认证可以领取免费服务量)
  • 前两步我就不贴流程图了,该系列在上节的语音唤醒文章中提到过注册和领取相关功能免费服务量的流程;

  • 上述操作很简单
  • 重点来了,科大讯飞平台的ASR接口怎么接入,下面来看一下吧

三、科大讯飞 ASR 短语音识别API

1. 创建应用

在这里插入图片描述在这里插入图片描述

  • 点击用户下面的 “我的应用” 然后创建应用,命名语音识别的应用,创建成功后会生成一个APPKey或者APPID 保存好。(名字随便起,记住APPID,后续要用到)

2. 查看免费测试服务量

在这里插入图片描述

  • 个人测试的话领取免费开发测试服务量就可以了,商用的话就购买相应的服务量。

3. 查看 WebSocket 接口信息

在这里插入图片描述

  • 记录保存该各项数据,后续在WebSocket连接的时候要用到这些。

4. API 开发文档查看

在这里插入图片描述

  • 这里有开发文档可以自行查看并学习,当然我是看过的,那么接下来就到了开发阶段了!
  • ps: 记住这个接口地址,这是WebSocket的API 地址 (调用的网址),接下来会用到。

四、功能开发阶段

1. Unity界面开发

在这里插入图片描述

  • ① 用于显示识别内容的 Text 文本
  • ② 用于按住进行录音操作的 Button 按钮
  • ③ 用于显示按钮的提示词的 Text 文本
  • ④ 用于挂载ASR语音识别 脚本 的空物体

2. 代码分析

在这里插入图片描述

  • 参数:用于定义变量;
  • 语音输入:用于录制音频片段;
  • 获取鉴权Url:用于鉴权加密的API地址;
  • 语音识别:用于实现语音识别的API接口调用功能;
  • 工具方法:用于处理Unity中的音频片段,转换成讯飞标准格式;
  • 数据定义:用于定义发送数据和接收数据的数据结构,根据第三方平台的参数数据。

3. 代码片段

using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.WebSockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;public class XunfeiSpeechToText : MonoBehaviour
{#region 参数/// <summary>/// host地址/// </summary>[SerializeField] private string m_HostUrl = "iat-api.xfyun.cn";/// <summary>/// 语言/// </summary>[SerializeField] private string m_Language = "zh_cn";/// <summary>/// 应用领域/// </summary>[SerializeField] private string m_Domain = "iat";/// <summary>/// 方言mandarin:中文普通话、其他语种/// </summary>[SerializeField] private string m_Accent = "mandarin";/// <summary>/// 音频的采样率/// </summary>[SerializeField] private string m_Format = "audio/L16;rate=16000";/// <summary>/// 音频数据格式/// </summary>[SerializeField] private string m_Encoding = "raw";/// <summary>/// websocket/// </summary>private ClientWebSocket m_WebSocket;/// <summary>/// 传输中断标记点/// </summary>private CancellationToken m_CancellationToken;/// <summary>/// 语音识别API地址/// </summary>[SerializeField][Header("语音识别API地址")]private string m_SpeechRecognizeURL;/// <summary>/// 讯飞的AppID/// </summary>[Header("填写APP ID")][SerializeField] private string m_AppID = "讯飞的AppID";/// <summary>/// 讯飞的APIKey/// </summary>[Header("填写Api Key")][SerializeField] private string m_APIKey = "讯飞的APIKey";/// <summary>/// 讯飞的APISecret/// </summary>[Header("填写Secret Key")][SerializeField] private string m_APISecret = "讯飞的APISecret";/// <summary>/// 计算方法调用的时间/// </summary>[SerializeField] protected System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();#endregionprivate void Awake(){//注册按钮事件RegistButtonEvent();//绑定地址 地址就是讯飞平台上的 WebSocket API地址m_SpeechRecognizeURL = "wss://iat-api.xfyun.cn/v2/iat";}#region 语音输入/// <summary>/// 语音输入的按钮/// </summary>[SerializeField] private Button m_VoiceInputBotton;/// <summary>/// 录音按钮的文本/// </summary>[SerializeField] private Text m_VoiceBottonText;/// <summary>/// 录音的提示信息/// </summary>[SerializeField] private Text m_RecordTips;/// <summary>/// 录制的音频长度/// </summary>public int m_RecordingLength = 5;/// <summary>/// 临时接收音频的片段/// </summary>private AudioClip recording;/// <summary>/// 注册按钮事件/// </summary>private void RegistButtonEvent(){if (m_VoiceInputBotton == null || m_VoiceInputBotton.GetComponent<EventTrigger>())return;EventTrigger _trigger = m_VoiceInputBotton.gameObject.AddComponent<EventTrigger>();//添加按钮按下的事件EventTrigger.Entry _pointDown_entry = new EventTrigger.Entry();_pointDown_entry.eventID = EventTriggerType.PointerDown;_pointDown_entry.callback = new EventTrigger.TriggerEvent();//添加按钮松开事件EventTrigger.Entry _pointUp_entry = new EventTrigger.Entry();_pointUp_entry.eventID = EventTriggerType.PointerUp;_pointUp_entry.callback = new EventTrigger.TriggerEvent();//添加委托事件_pointDown_entry.callback.AddListener(delegate { StartRecord(); });_pointUp_entry.callback.AddListener(delegate { StopRecord(); });_trigger.triggers.Add(_pointDown_entry);_trigger.triggers.Add(_pointUp_entry);}/// <summary>/// 开始录制/// </summary>public void StartRecord(){m_VoiceBottonText.text = "正在录音中...";StartRecordAudio();}/// <summary>/// 结束录制/// </summary>public void StopRecord(){m_VoiceBottonText.text = "按住按钮,开始录音";m_RecordTips.text = "录音结束,正在识别...";StopRecordAudio(AcceptClip);}/// <summary>/// 开始录制声音/// </summary>public void StartRecordAudio(){recording = Microphone.Start(null, true, m_RecordingLength, 16000);}/// <summary>/// 结束录制,返回audioClip/// </summary>/// <param name="_callback"></param>public void StopRecordAudio(Action<AudioClip> _callback){Microphone.End(null);_callback(recording);}/// <summary>/// 处理录制的音频数据/// </summary>/// <param name="_data"></param>public void AcceptClip(AudioClip _audioClip){m_RecordTips.text = "正在进行语音识别...";SpeechToText(_audioClip, DealingTextCallback);}/// <summary>/// 处理识别到的文本/// </summary>/// <param name="_msg"></param>private void DealingTextCallback(string _msg){//在此处处理接收到的数据,可以选择发送给大模型,或者打印测试,会在后续补充功能m_RecordTips.text = _msg;Debug.Log(_msg);}#endregion#region 获取鉴权Url/// <summary>/// 获取鉴权url/// </summary>/// <returns></returns>private string GetUrl(){//获取时间戳string date = DateTime.Now.ToString("r");//拼接原始的signaturestring signature_origin = string.Format("host: " + m_HostUrl + "\ndate: " + date + "\nGET /v2/iat HTTP/1.1");//hmac-sha256算法-签名,并转换为base64编码string signature = Convert.ToBase64String(new HMACSHA256(Encoding.UTF8.GetBytes(m_APISecret)).ComputeHash(Encoding.UTF8.GetBytes(signature_origin)));//拼接原始的authorizationstring authorization_origin = string.Format("api_key=\"{0}\",algorithm=\"hmac-sha256\",headers=\"host date request-line\",signature=\"{1}\"", m_APIKey, signature);//转换为base64编码string authorization = Convert.ToBase64String(Encoding.UTF8.GetBytes(authorization_origin));//拼接鉴权的urlstring url = string.Format("{0}?authorization={1}&date={2}&host={3}", m_SpeechRecognizeURL, authorization, date, m_HostUrl);return url;}#endregion#region 语音识别/// <summary>/// 语音识别/// </summary>/// <param name="_clip"></param>/// <param name="_callback"></param>public void SpeechToText(AudioClip _clip, Action<string> _callback){byte[] _audioData = ConvertClipToBytes(_clip);StartCoroutine(SendAudioData(_audioData, _callback));}/// <summary>/// 识别短文本/// </summary>/// <param name="_audioData"></param>/// <param name="_callback"></param>/// <returns></returns>public IEnumerator SendAudioData(byte[] _audioData, Action<string> _callback){yield return null;ConnetHostAndRecognize(_audioData, _callback);}/// <summary>/// 连接服务,开始识别/// </summary>/// <param name="_audioData"></param>/// <param name="_callback"></param>private async void ConnetHostAndRecognize(byte[] _audioData, Action<string> _callback){try{stopwatch.Restart();//建立socket连接m_WebSocket = new ClientWebSocket();m_CancellationToken = new CancellationToken();Uri uri = new Uri(GetUrl());await m_WebSocket.ConnectAsync(uri, m_CancellationToken);//开始识别SendVoiceData(_audioData, m_WebSocket);StringBuilder stringBuilder = new StringBuilder();while (m_WebSocket.State == WebSocketState.Open){var result = new byte[4096];await m_WebSocket.ReceiveAsync(new ArraySegment<byte>(result), m_CancellationToken);//去除空字节List<byte> list = new List<byte>(result); while (list[list.Count - 1] == 0x00) list.RemoveAt(list.Count - 1);string str = Encoding.UTF8.GetString(list.ToArray());//获取返回的jsonResponseData _responseData = JsonUtility.FromJson<ResponseData>(str);if (_responseData.code == 0){stringBuilder.Append(GetWords(_responseData));}else{PrintErrorLog(_responseData.code);}m_WebSocket.Abort();}string _resultMsg = stringBuilder.ToString();//识别成功,回调_callback(_resultMsg);stopwatch.Stop();if (_resultMsg.Equals(null) || _resultMsg.Equals("")){Debug.Log("语音识别为空字符串");}else{//识别的数据不为空 在此处做功能处理}Debug.Log("讯飞语音识别耗时:" + stopwatch.Elapsed.TotalSeconds);}catch (Exception ex){Debug.LogError("报错信息: " + ex.Message);m_WebSocket.Dispose();}}/// <summary>/// 获取识别到的文本/// </summary>/// <param name="_responseData"></param>/// <returns></returns>private string GetWords(ResponseData _responseData){StringBuilder stringBuilder = new StringBuilder();foreach (var item in _responseData.data.result.ws){foreach (var _cw in item.cw){stringBuilder.Append(_cw.w);}}return stringBuilder.ToString();}private void SendVoiceData(byte[] audio, ClientWebSocket socket){if (socket.State != WebSocketState.Open){return;}PostData _postData = new PostData(){common = new CommonTag(m_AppID),business = new BusinessTag(m_Language, m_Domain, m_Accent),data = new DataTag(2, m_Format, m_Encoding, Convert.ToBase64String(audio))};string _jsonData = JsonUtility.ToJson(_postData);//发送数据socket.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(_jsonData)), WebSocketMessageType.Binary, true, new CancellationToken());}#endregion#region 工具方法/// <summary>/// audioclip转为byte[]/// </summary>/// <param name="audioClip"></param>/// <returns></returns>public byte[] ConvertClipToBytes(AudioClip audioClip){float[] samples = new float[audioClip.samples];audioClip.GetData(samples, 0);short[] intData = new short[samples.Length];byte[] bytesData = new byte[samples.Length * 2];int rescaleFactor = 32767;for (int i = 0; i < samples.Length; i++){intData[i] = (short)(samples[i] * rescaleFactor);byte[] byteArr = new byte[2];byteArr = BitConverter.GetBytes(intData[i]);byteArr.CopyTo(bytesData, i * 2);}return bytesData;}/// <summary>/// 打印错误日志/// </summary>/// <param name="status"></param>private void PrintErrorLog(int status){if (status == 10005){Debug.LogError("appid授权失败");return;}if (status == 10006){Debug.LogError("请求缺失必要参数");return;}if (status == 10007){Debug.LogError("请求的参数值无效");return;}if (status == 10010){Debug.LogError("引擎授权不足");return;}if (status == 10019){Debug.LogError("session超时");return;}if (status == 10043){Debug.LogError("音频解码失败");return;}if (status == 10101){Debug.LogError("引擎会话已结束");return;}if (status == 10313){Debug.LogError("appid不能为空");return;}if (status == 10317){Debug.LogError("版本非法");return;}if (status == 11200){Debug.LogError("没有权限");return;}if (status == 11201){Debug.LogError("日流控超限");return;}if (status == 10160){Debug.LogError("请求数据格式非法");return;}if (status == 10161){Debug.LogError("base64解码失败");return;}if (status == 10163){Debug.LogError("缺少必传参数,或者参数不合法,具体原因见详细的描述");return;}if (status == 10200){Debug.LogError("读取数据超时");return;}if (status == 10222){Debug.LogError("网络异常");return;}}#endregion#region 数据定义/// <summary>/// 发送的数据/// </summary>[Serializable]public class PostData{[SerializeField] public CommonTag common;[SerializeField] public BusinessTag business;[SerializeField] public DataTag data;}[Serializable]public class CommonTag{[SerializeField] public string app_id = string.Empty;public CommonTag(string app_id){this.app_id = app_id;}}[Serializable]public class BusinessTag{[SerializeField] public string language = "zh_cn";[SerializeField] public string domain = "iat";[SerializeField] public string accent = "mandarin";public BusinessTag(string language, string domain, string accent){this.language = language;this.domain = domain;this.accent = accent;}}[Serializable]public class DataTag{[SerializeField] public int status = 2;[SerializeField] public string format = "audio/L16;rate=16000";[SerializeField] public string encoding = "raw";[SerializeField] public string audio = string.Empty;public DataTag(int status, string format, string encoding, string audio){this.status = status;this.format = format;this.encoding = encoding;this.audio = audio;}}[Serializable]public class ResponseData{[SerializeField] public int code = 0;[SerializeField] public string message = string.Empty;[SerializeField] public string sid = string.Empty;[SerializeField] public ResponcsedataTag data;}[Serializable]public class ResponcsedataTag{[SerializeField] public Results result;[SerializeField] public int status = 2;}[Serializable]public class Results{[SerializeField] public List<WsTag> ws;}[Serializable]public class WsTag{[SerializeField] public List<CwTag> cw;}[Serializable]public class CwTag{[SerializeField] public int sc = 0;[SerializeField] public string w = string.Empty;}#endregion}

4. 数据配置

在这里插入图片描述

  • 将APPid、ApiKey、SecretKey替换成自己讯飞平台上的 WebSocket 信息数据
  • 变量对应UI进行配置

5. 效果展示

在这里插入图片描述

  • 按住按钮进行录音,松开后进行识别,返回的结果会显示在UI界面上,就代表成功了。

在这里插入图片描述

  • 控制台会有打印结果的,也一样代表 API 接入成功。
  • 注意使用时,打开电脑麦克风权限

6. 问题反馈

  • 运行后有任何问题都可以在评论区进行讨论~
  • 代码写的不是很工整,多多指点,后续会进行整个系列的框架搭建
  • 下一期更新暂定:
    ① 其他平台ASR接入功能,例如:百度等
    ② 大模型LLM的接入,例如:讯飞、百度、GPT等
    二选一哦!
  • 评论告诉我,下一期更新什么

然后就,大功告成了!!!

在这里插入图片描述
比心啦 ❥(^_-)

在这里插入图片描述

总结

  • 提示: 大家根据需求来做功能,后续继续其他功能啦,不懂的快喊我。
  • 大家可以在评论区讨论其他系列下一期出什么内容,这个系列会继续更新的
  • 点赞收藏加关注哦~ 蟹蟹

相关文章:

Unity3D开发AI桌面精灵/宠物系列 【三】 语音识别 ASR 技术、语音转文本多平台 - 支持科大讯飞、百度等 C# 开发

Unity3D 交互式AI桌面宠物开发系列【三】ASR 语音识别 该系列主要介绍怎么制作AI桌面宠物的流程&#xff0c;我会从项目开始创建初期到最终可以和AI宠物进行交互为止&#xff0c;项目已经开发完成&#xff0c;我会仔细梳理一下流程&#xff0c;分步讲解。 这篇文章主要讲有关于…...

Qt -信号与槽

博客主页&#xff1a;【夜泉_ly】 本文专栏&#xff1a;【暂无】 欢迎点赞&#x1f44d;收藏⭐关注❤️ 目录 前言引入connect调用链模板类型的connectQObject::connectImplQObjectPrivate::connectImpl qobject_p_p.hconnect作用总结ai对信号与槽的模拟实现 前言 面向对象&am…...

深度解析新能源汽车研发测试中的关键信号采集技术

摘要 随着新能源汽车的快速发展&#xff0c;研发测试环节对信号采集的需求日益复杂。本文结合行业前沿技术方案&#xff0c;系统梳理了新能源汽车测试中需要关注的核心信号类型、采集方法及技术难点&#xff0c;涵盖高压电气、动力电池、热管理、智能驾驶、网络通信等全维度数据…...

Django中使用不同种类缓存的完整案例

Django中使用不同种类缓存的完整案例 推荐超级课程: 本地离线DeepSeek AI方案部署实战教程【完全版】Docker快速入门到精通Kubernetes入门到大师通关课AWS云服务快速入门实战目录 Django中使用不同种类缓存的完整案例步骤1:设置Django项目步骤2:设置URL路由步骤3:视图级别…...

Linux 高级命令与常见操作:文本处理、系统管理与网络调试

下面是一份针对已经熟悉 Linux 基础命令的用户所整理的「高级命令与常见操作」笔记&#xff0c;涵盖文本处理、系统管理、网络调试与其他常用的进阶技巧。请你审核下面笔记&#xff0c;检查是否有过时的内容&#xff0c;如有请进行替换&#xff0c;确保其符合现代化需求&#x…...

解锁健康密码,拥抱品质生活

在生活节奏不断加快的今天&#xff0c;健康养生已成为人们关注的焦点。它不仅关乎当下生活质量&#xff0c;更是对未来幸福的投资。从日常生活的点滴出发&#xff0c;掌握正确养生方法&#xff0c;我们就能轻松收获健康。​ 饮食是健康的基石。我们应当遵循 “食物多样&#x…...

TLS 1.2 握手过程,每个阶段如何保证通信安全?​​

TLS 1.2 握手是确保客户端和服务器之间安全通信的关键过程。它涉及多个步骤&#xff0c;包括身份验证、加密算法协商和会话密钥交换。 目录 TLS 1.2 握手是确保客户端和服务器之间安全通信的关键过程。它涉及多个步骤&#xff0c;包括身份验证、加密算法协商和会话密钥交换。…...

ABAP 新语法 - corresponding

在 ABAP 中&#xff0c;CORRESPONDING 操作符用于根据字段名称自动映射结构体&#xff08;Structure&#xff09;或内表&#xff08;Internal Table&#xff09;的字段值。它比传统的 MOVE-CORRESPONDING 语句更灵活&#xff0c;支持更多控制选项。 基础用法 data: begin of …...

C++ 中为什么构造函数不需要实现虚函数,而析构函数需要?

在C中&#xff0c;构造函数不需要是虚函数&#xff0c;而析构函数往往需要&#xff0c;原因如下&#xff1a; 构造函数 对象创建顺序&#xff1a;构造函数的主要任务是初始化对象的成员变量&#xff0c;创建对象时需要先调用基类的构造函数&#xff0c;再调用派生类的构造函数…...

vscode使用方式

一、常用快捷键与代码操作 注释与代码排版 行注释&#xff1a;Ctrl /&#xff1b;块注释&#xff1a;Shift Alt A。 代码缩进&#xff1a;选中代码段后按 Tab&#xff08;右移&#xff09;或 Shift Tab&#xff08;左移&#xff09;。 代码导航与编辑 快速跳转文件&…...

存储模块cache

参考&#xff1a;存储模块 --- Cache_cache模块-CSDN博客 一级缓存&#xff08;L1 Cache&#xff09; 和 二级缓存&#xff08;L2 Cache&#xff09; 都是处理器内的高速缓存&#xff0c;用来减少访问主内存的延迟&#xff0c;提高处理器的性能。它们在计算机体系结构中发挥着…...

HTML零基础入门笔记:狂神版

前言 本笔记是学习狂神的java教程&#xff0c;建议配合视频&#xff0c;学习体验更佳。 【狂神说Java】HTML5完整教学通俗易懂_哔哩哔哩_bilibili 第1-2章&#xff1a;Java零基础入门笔记&#xff1a;(1-2)入门&#xff08;简介、基础知识&#xff09;-CSDN博客 第3章&…...

java.util.Collections中常用api

在Java中&#xff0c;java.util.Collections 是一个工具类&#xff0c;提供了大量静态方法用于操作或返回集合&#xff08;如List、Set、Map等&#xff09;。以下是常用的API分类整理&#xff1a; 1. 排序与顺序操作 sort(List<T> list) 对List进行自然顺序排序&#xff…...

FreeRTOS移植笔记:让操作系统在你的硬件上跑起来

一、为什么需要移植&#xff1f; FreeRTOS就像一套"操作系统积木"&#xff0c;但不同硬件平台&#xff08;如STM32、ESP32、AVR等&#xff09;的CPU架构和外设差异大&#xff0c;需要针对目标硬件做适配配置。移植工作就是让FreeRTOS能正确管理你的硬件资源。 二、…...

c语言修炼秘籍 - - 禁(进)忌(阶)秘(技)术(巧)【第五式】动态内存管理

c语言修炼秘籍 - - 禁(进)忌(阶)秘(技)术(巧)【第五式】动态内存管理 【心法】 【第零章】c语言概述 【第一章】分支与循环语句 【第二章】函数 【第三章】数组 【第四章】操作符 【第五章】指针 【第六章】结构体 【第七章】const与c语言中一些错误代码 【禁忌秘术】 【第一式…...

树莓派超全系列教程文档--(22)使用外部存储设备的相关操作

使用外部存储设备的相关操作 外部存储设备相关操作安装存储设备设置自动挂载卸载存储设备处理 target is busy 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 外部存储设备相关操作 您可以将外部硬盘、SSD或U盘连接到Raspberry Pi上的任何USB端…...

MySQL表的增删改查基础版

这一部分内容比较多&#xff0c;请大家结合目录查看&#x1f440; 增删改查 这一部分内容比较多&#xff0c;请大家结合目录查看&#x1f440; 一、新增1.插入2.指定列插入3.一次插入多行记录 二、查询1.全列查询2.指定列查询3.查询字段为表达式4.别名5.去重6.多列去重7.排序8.…...

PDF预览-搜索并高亮文本

在PDF.js中实现搜索高亮功能可以通过自定义一些代码来实现。PDF.js 是一个通用的、基于Web的PDF阅读器&#xff0c;它允许你在网页上嵌入PDF文件&#xff0c;并提供基本的阅读功能。要实现搜索并高亮显示文本&#xff0c;你可以通过以下几个步骤来完成&#xff1a; 1. 引入PDF…...

【备赛】蓝桥杯嵌入式实现led闪烁

原理 由于蓝桥杯的板子带有锁存器&#xff0c;并且与lcd屏幕有冲突&#xff0c;所以这个就成了考点。 主要就是用定时器来实现&#xff0c;同时也要兼顾lcd的冲突。 一、处理LCD函数 首先来解决与lcd屏幕冲突的问题&#xff0c;把我们所有用到的lcd函数改装一下。 以下是基…...

【Python】贝叶斯,条件概率是怎么回事儿

【Python】贝叶斯&#xff0c;条件概率是怎么回事儿 一、原理简介1.1 贝叶斯定理1.2 朴素贝叶斯假设 二、算法实现过程2.1 数据准备与预处理2.2 模型训练与预测2.2.1 高斯朴素贝叶斯 - 对应连续型数据2.2.2 多项式朴素贝叶斯 - 离散型数据 2.3 模型评估 三、算法优缺点分析3.1 …...

Flink介绍——实时计算核心论文之Storm论文详解

引入 我们通过以下两篇文章&#xff0c;深入探索了S4是如何抽象流式计算模型&#xff0c;如何设计架构和系统&#xff0c;存在那些局限&#xff1a; 论文详解论文总结 Yahoo推出的S4 并没有在历史舞台上站稳脚跟&#xff0c;在S4的论文发表的同一年&#xff0c;我们今天的主…...

001 使用单片机实现的逻辑分析仪——吸收篇

本内容记录于韦东山老师的毕设级开源学习项目&#xff0c;含个人观点&#xff0c;请理性阅读。 个人笔记&#xff0c;没有套路&#xff0c;一步到位&#xff0c;欢迎交流&#xff01; 00单片机的逻辑分析仪与商业版FPGA的逻辑分析仪异同 对比维度自制STM32逻辑分析仪商业版逻…...

es基本概念

Elasticsearch 的架构与基本概念 Elasticsearch&#xff08;简称 ES&#xff09;是一个开源的分布式搜索和分析引擎&#xff0c;基于 Apache Lucene 构建。它被广泛用于全文搜索、日志分析、实时数据分析等场景。以下是其架构概述及其基本概念的详细解释。 Elasticsearch 的架…...

可以使用费曼学习法阅读重要的书籍

书本上画了很多线&#xff0c;回头看等于没画出任何重点。 不是所有的触动都是有效的。就像你曾经看过很多好文章&#xff0c;当时被触动得一塌糊涂&#xff0c;还把它们放进了收藏夹&#xff0c;但一段时间之后&#xff0c;你就再也记不起来了。如果让你在一本书上画出令自己…...

11-产品经理-创建产品

在“产品”-“仪表盘”内&#xff0c;可以查看系统中关于产品及相关需求的统计。 在“产品”-“产品列表”页面&#xff0c;可以按项目集、项目查看其关联产品。还可以添加产品、编辑产品线、或者导出产品列表。 产品看板&#xff0c;通过看板方式查看产品、产品计划和产品下的…...

JavaScript学习教程,从入门到精通,JavaScript 基础语法全面指南(5)

JavaScript 基础语法全面指南 一、JavaScript 基本概念 JavaScript 是一种轻量级的解释型或即时编译型的编程语言&#xff0c;主要用于网页开发&#xff0c;为网页添加交互功能。 1.1 JavaScript 的特点 解释型语言&#xff1a;不需要编译&#xff0c;由 JavaScript 引擎直…...

低代码开发平台:飞帆制作网页并集成到自己的网页中

应用场景&#xff1a; 有时&#xff0c;我们的网页使用了某个模版&#xff0c;或者自己写的 html、css、javascript 代码。只是网页中的一部分使用飞帆来制作。这样的混合网页如何实现呢&#xff1f; 其实很容易&#xff0c;来体验一下飞帆提供的功能&#xff01; 还记得这个…...

语法: result=log (x);

LOG( ) 语法: resultlog (x); 参数: x是一个浮点数; 返回值: result等于返回值,是一个浮点数; 功能: 该函数是用来计算浮点数x的自然对数(即ln x);如果x小于或等于0,或x太大,则行为没有定义; 注意:存在error挂起; 如果在编写程序里包含了errno.h头文件,则范围和等级…...

Hibernate核心方法总结

Session中的核心方法梳理 1、save方法 这个方法表示将一个对象保存到数据库中&#xff0c;可以将一个不含OID的new出来的临时对象转换为一个处于Session缓存中具有OID的持久化对象。 需要注意的是&#xff1a;在save方法前设置OID是无效的但是也不会报错&#xff0c;在save方…...

IntelliJ IDEA Maven 工具栏消失怎么办?

一、问题现象与背景 在使用 IntelliJ IDEA&#xff08;简称 IDEA&#xff09;开发 Maven 项目时&#xff0c;偶尔会遇到右侧或侧边栏的 Maven 工具栏&#xff08;显示依赖、生命周期等信息的窗口&#xff09;突然消失的情况。这可能影响开发者快速操作 Maven 构建、依赖管理等…...