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

PyAudio库基本知识详解——为自制PCM音频播放器做准备

前言

结合前段时间我们做的音频编解码器,这样我们就可以将获取到的ADPCM数据,转换成PCM数据,然后播放出来,得到一个完整的音频数据,因此,接下来几篇文章中,我们想做一个播放PCM格式的音频播放器。待到音频编解码器完成,播放器完成,或许我们就能做一个语音识别功能模块,通过一个小收音器的BLE蓝牙连接,连接到电脑上,实时完成音频传输,解码,以及识别的整套流程。可以完成语音写入文本,不仅彻底解放双手,还能解放双脚,让你离开电脑桌也能输入文本(不过也是作者的美好幻想, 先挖个坑,距离实现遥遥无期,尽请期待!)

在此之前呢,我们先脚踏实地的,了解一下我们必要的第三方库,PyAudio

前置知识

在介绍PyAudio库之前我们需要先了解一点点前置内容

  • 采样率:采样率是指机器每秒采样的次数,是音频处理中的重要参数。如:采样率为44100,即1秒钟采样44100次,常见的采样率为44100、48000,在小型设备中,如只专注语音的识别,不在乎音质,通常会选用更小的采样率,如8000、16000等,换取硬件设备的成本优势
  • 音频格式:指的是每个采样点的长度,如:paInt16,表示每个采样点为16比特,一次采样获取的数据为16比特,常见的采样点大小为8、16、32等。单位为比特。通常采样率与采样点大小即可确定一定时间内,采样获取的数据大小,如:当音频格式为paInt16,采样率为8KHz,那么1s中,将采样到 8000 * 16bit = 128kb的数据。
  • 通道:指的是声道,麦克风拾音的过程。分为单声道,多声道,立体声,联合立体声等。
  • 块:块是指数据块,在PyAudio可以实时处理动态音频数据,也就是音频流,而处理音频流实际上也是将连续的(实际上并非连续)输入以数据块的形式处理,并不是来一个字节处理一个字节,可以理解为缓冲区buffer的概念。

稍稍理解这些概念,以便后续阅读中看懂PyAudio的参数,如果没懂,可以返回来反复阅读。

PyAudio

PyAudio 是一个用于在 Python 中进行音频处理的库,它为我们提供了跨平台的接口,用于录音、播放和处理音频流。PyAudio 封装了 PortAudio 库,PortAudio 是一个跨平台的音频库,支持多种操作系统(如 Windows、macOS、Linux)。

PyAudio的常见用途

  1. 录音(Recording Audio):可以从麦克风获取音频数据。
  2. 播放音频(Playing Audio):可以播放 WAV 或其他格式的音频文件。
  3. 实时音频处理:处理音频数据流(例如,分析麦克风输入,实时音效等)。

安装 PyAudio

首先需要安装 PyAudio。可以使用 pip 来安装:

pip install pyaudio

PyAudio的核心概念

  1. 流(Stream): PyAudio 的核心概念是“流”(Stream)。流是数据的一个持续流动的通道,用于音频输入或输出。你可以创建一个输入流(录音)或输出流(播放音频),然后使用流来传输音频数据。
  2. 音频格式和数据: PyAudio 支持多种音频格式,例如 paInt16(16 位整数格式)和 paFloat32(32 位浮点格式)。音频数据通常是原始的字节流数据,可以通过 NumPy 数组或其他方式进行处理。
  3. 回调函数: 在实时音频流的场景中,通常使用回调函数来处理音频数据。回调函数会在每次采集到一块音频数据时被调用。

主要功能

  1. 录音示例: 以下是一个使用 PyAudio 录音的简单示例:

    import pyaudio
    import wave# 设置录音参数
    FORMAT = pyaudio.paInt16  # 音频格式
    CHANNELS = 1              # 单声道
    RATE = 44100              # 采样率
    CHUNK = 1024              # 每次读取的数据块大小
    RECORD_SECONDS = 5        # 录音时长
    OUTPUT_FILENAME = "output.wav"  # 输出文件p = pyaudio.PyAudio()# 开启输入流
    stream = p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=CHUNK)print("开始录音...")frames = []# 录制数据
    for _ in range(0, int(RATE * RECORD_SECONDS / CHUNK)):data = stream.read(CHUNK)frames.append(data)print("录音结束...")# 停止流并关闭
    stream.stop_stream()
    stream.close()
    p.terminate()# 将录音保存为WAV文件
    wf = wave.open(OUTPUT_FILENAME, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(p.get_sample_size(FORMAT))
    wf.setframerate(RATE)
    wf.writeframes(b''.join(frames))
    wf.close()
    

    这里有值得一提的一个点:

    # 录制数据
    for _ in range(0, int(RATE * RECORD_SECONDS / CHUNK)):data = stream.read(CHUNK)frames.append(data)
    

    这个循环的主要目的是从流中读取数据,并添加到frams列表中,可以看到RATE * RECORD_SECONDS采样率 * 录音时长,这可以得到在本次录音中一共采样的次数,/ CHUNK表明采样的数据被分块读取并写入frames。这里其实隐式的处理了采样格式,即paInt16

  2. 播放音频示例: 以下是一个播放 WAV 文件的简单示例:

    import pyaudio
    import wave# 打开WAV文件
    wf = wave.open('output.wav', 'rb')p = pyaudio.PyAudio()# 打开输出流
    stream = p.open(format=pyaudio.paInt16,channels=wf.getnchannels(),rate=wf.getframerate(),output=True)# 读取文件并播放
    chunk = 1024
    data = wf.readframes(chunk)
    while data:stream.write(data)data = wf.readframes(chunk)# 关闭流
    stream.stop_stream()
    stream.close()
    p.terminate()
    

PyAudio的高级功能

  • 回调模式(Callback Mode): PyAudio 提供了回调模式来处理音频流。在这种模式下,你可以通过定义回调函数来实时处理录制或播放的音频数据。例如,你可以实时对音频数据进行处理或应用某些效果(如滤波、增益等)。

    示例:

    import pyaudiodef callback(in_data, frame_count, time_info, status):# 处理音频数据print("Recording...")return (in_data, pyaudio.paContinue)p = pyaudio.PyAudio()# 打开输入流
    stream = p.open(format=pyaudio.paInt16,channels=1,rate=44100,input=True,frames_per_buffer=1024,stream_callback=callback)stream.start_stream()# 等待流结束
    while stream.is_active():passstream.stop_stream()
    stream.close()
    p.terminate()
    

PyAudio的应用场景

  1. 音频录制与播放:用来创建简单的音频应用程序,进行声音的录制和回放。
  2. 语音识别:结合其他语音识别库(如 speech_recognition)可以实现语音识别功能。
  3. 实时音频处理:可以实时分析、修改或增强音频数据。
  4. 声音特效处理:可以在录制或播放过程中加入音效,如回声、变调等。

PyAudio与其他音频库对比

  • vs. wave: wave 模块主要用于处理静态的音频文件,而 PyAudio 支持音频流,能够进行实时录音与播放。
  • vs. soundfile: soundfile 更适用于处理已保存的音频文件的读写操作,而 PyAudio 更擅长实时音频流的处理。

注意事项

  • 在不同平台上安装 PyAudio 可能需要额外的步骤。例如,Windows 上可能需要安装 PortAudio 的依赖项。
  • PyAudio 并不支持直接播放 MP3 等压缩音频格式。如果需要播放其他格式的音频,可能需要使用其他库如 pygamepydub

小结

总的来说,PyAudio 是一个非常强大的库,适合用于音频处理和实时音频应用,尤其在需要直接与麦克风或扬声器交互时,提供了非常简洁的接口。

stop_stream与start_stream

可能会有同学好奇,在上面的示例代码中,为什么只看见stream.stop_stream而没有看见stream.start_stream呢,如果只有停止流的操作,为什么没有开启流的操作,流在哪里被开启了呢?

PyAudio 中的 stream.start_stream()stream.stop_stream() 是两个重要的流控制方法,用于控制音频流的开始和停止。

PyAudio 的流(Stream)中,start_stream()stop_stream() 方法实际上是可选的,它们的行为是与音频流的实际使用场景有关的。让我们详细解释一下这两个方法,以及为什么在某些情况下,可能看不到显式调用 start_stream()

1. stream.start_stream() 的作用

start_stream() 方法用于启动音频流,开始录制或播放音频。它是用来显式告诉程序 “现在开始处理音频数据”。

2. stream.stop_stream() 的作用

stop_stream() 方法用于停止音频流,表示录制或播放过程结束。这对于需要显式控制音频流的结束时机的程序非常有用。

为什么 start_stream() 有时没被显式调用

  1. 回调模式(Callback Mode): 如果使用了回调模式(即通过设置 stream_callback 参数来传递回调函数),那么在调用 open() 方法时,音频流已经自动开始了。回调机制会在后台处理音频数据的输入和输出。因此,在这种模式下,start_stream() 是不必要的,因为流会自动启动。

    例如:

    import pyaudiodef callback(in_data, frame_count, time_info, status):# 处理音频数据print("Recording...")return (in_data, pyaudio.paContinue)p = pyaudio.PyAudio()# 打开输入流并设置回调函数
    stream = p.open(format=pyaudio.paInt16,channels=1,rate=44100,input=True,frames_per_buffer=1024,stream_callback=callback)# 注意: 这里不需要显式调用 start_stream()
    stream.start_stream()  # 这行可以省略,回调模式会自动启动# 等待流结束
    while stream.is_active():passstream.stop_stream()
    stream.close()
    p.terminate()
    

    在这个例子中,start_stream() 虽然可以显式调用,但在使用回调模式时,可以省略,因为 PyAudio 会在底层自动处理流的启动和停止。

  2. 默认自动启动(在非回调模式下): 在非回调模式(例如通过 stream.read()stream.write() 进行音频数据的读取和写入)中,start_stream() 也是隐式调用的。在创建音频流时,open() 方法会自动启动流,并开始数据的录制或播放。

    import pyaudiop = pyaudio.PyAudio()# 设置流参数
    stream = p.open(format=pyaudio.paInt16,channels=1,rate=44100,input=True,frames_per_buffer=1024)# 此时,流已经自动启动
    data = stream.read(1024)  # 录音
    stream.stop_stream()
    stream.close()
    p.terminate()
    

    在这个例子中,open() 已经自动启动了流,调用 stream.read() 只是触发音频数据的读取过程,而不需要显式调用 start_stream()

小结

  • 回调模式:当你使用回调函数时,PyAudio 会自动管理音频流的开始和停止。因此,通常不需要显式调用 start_stream(),而只需要设置 stream_callback 并开始流的处理。
  • 非回调模式:即便是非回调模式,open() 方法有时也会自动开始音频流,尤其是在调用 stream.read()stream.write() 时,不需要显式调用 start_stream()

但是,在一些场景下,尤其是自定义更复杂的音频控制时,start_stream()stop_stream() 还是很有用的,特别是当你需要手动控制音频流的启动与停止时。

谁开启的麦克风或扬声器

在上面的示例代码中,敏锐的读者可能会发现,似乎没有发现那里调用了麦克风或扬声器,合理猜测,直接告诉我们,应该是PyAudio库调用了硬件设备,但真是如此吗,如果是,那么又是怎么调用的呢?

我们以上面的代码为例,究竟是谁调用了麦克风,开启了录音

音频的录制是通过 pyaudio 库来实现的,调用麦克风硬件的部分是由 pyaudio 库中的 PyAudio 类和它的 open() 方法来完成的。具体的过程是这样的:

调用麦克风硬件的关键步骤:

  1. pyaudio.PyAudio(): 这个步骤创建了一个 PyAudio 对象。这个对象是与音频硬件交互的主要接口,它会管理音频流(包括录音流和播放流),并负责配置音频设备。

  2. p.open(): open() 方法是用来打开一个音频流的,这个流可以是输入流(例如录音)或者输出流(例如播放音频)。在上面的代码中,p.open() 被用来打开一个输入流,用于录制音频。

    stream = p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=CHUNK)
    

    关键参数:

    • format=FORMAT:指定音频数据的格式,通常为 16 位 PCM 编码(pyaudio.paInt16)。
    • channels=CHANNELS:指定录音的通道数,1 表示单声道,2 表示立体声。
    • rate=RATE:指定采样率,通常选择 44100 Hz,这是 CD 音质的标准采样率。
    • input=True:这告诉 pyaudio 创建一个输入流,也就是通过麦克风录音。如果将其设置为 False,则会创建输出流,用于播放音频。
    • frames_per_buffer=CHUNK:指定每次读取的音频块的大小,通常是 1024 或 2048。

    此时,pyaudio 会通过系统的音频接口与麦克风硬件进行连接,并开始接收音频数据。具体而言,pyaudio 会通过操作系统调用音频驱动程序来访问麦克风硬件。操作系统(如 Windows、Linux、macOS)会提供接口给 pyaudio 来处理与硬件的交互。

  3. stream.read(CHUNK): stream.read(CHUNK) 方法是用来从音频流中读取音频数据的。这里的 CHUNK 表示每次读取的音频数据的大小,也就是说它会以一定的时间间隔(根据 CHUNK 的大小)从麦克风捕捉音频数据。

    通过连续调用 stream.read(),程序不断地从麦克风获取音频数据,并将这些数据存储到 frames 列表中。

总结:

  • 谁调用了麦克风硬件?
    实际上是 pyaudio 库调用了麦克风硬件。pyaudio 作为一个高层的音频处理库,封装了与操作系统音频接口的交互。操作系统的音频驱动程序在幕后管理与麦克风硬件的连接和数据传输。
  • 如何调用的?
    • 通过 pyaudio.PyAudio() 创建的 PyAudio 实例。
    • 使用 p.open() 方法创建音频输入流(input=True),并通过该流接收来自麦克风的音频数据。
    • 最终使用 stream.read() 不断地从麦克风获取音频样本。

这样,pyaudio 库就可以通过操作系统和驱动程序,控制麦克风硬件进行录音了。

相关文章:

PyAudio库基本知识详解——为自制PCM音频播放器做准备

前言 结合前段时间我们做的音频编解码器,这样我们就可以将获取到的ADPCM数据,转换成PCM数据,然后播放出来,得到一个完整的音频数据,因此,接下来几篇文章中,我们想做一个播放PCM格式的音频播放器…...

微信小程序 覆盖组件cover-view

wxml 覆盖组件 <video src"../image/1.mp4" controls"{{false}}" event-model"bubble"> <cover-view class"controls"> <cover-view class"play" bind:tap"play"> <cover-image class"…...

实战案例——ZooKeeper集群部署(新手教程超详细)

案例目标 了解ZooKeeper分布式应用程序协调服务使用3台机器搭建ZooKeeper集群使用ZooKeeper集群 案例分析 规划节点 ZooKeeper集群节点规划 Ip 主机名 节点 192.168.110.10 zookeeper1 集群节点 192.168.110.20 zookeeper2 集群节点 192.168.110.30 zookeeper3 …...

LeetCode 326 3的幂

如何判断一个整数是否为 3 的幂次方 在编程中&#xff0c;我们经常会遇到各种有趣的数学问题&#xff0c;今天就来探讨一个看似简单却又很有技巧性的问题&#xff1a;如何判断一个给定的整数是否是 3 的幂次方。 一、问题描述 给定一个整数 n&#xff0c;我们需要编写一个函数…...

智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之5

本文要点 前端 问题描述语言 本文继续完善 “描述” ---现在我们应该可以将它称为 “问题problem描述语言 ”。 它 通过对话框的question 引发 表征的issue 的“涌现” 最终 厘清应用程序的“problem”。即它合并了 ISO七层模型中的上面三层&#xff0c;通过将三层 分别形成…...

flink-1.16 table sql 消费 kafka 数据,指定时间戳位置消费数据报错:Invalid negative offset 问题解决

请移步至最后的&#xff1a;2024-12-27日调整实现方式&#xff0c;26日实现的有bug&#xff0c;但是可以作为参考。 2024-12-27日调整实现方式 1.上边的方案&#xff0c;可以实现topic中每个分区都正常有数据的情况&#xff0c;但是如果部分分区没有数据&#xff0c;或者指定的…...

【服务器】上传文件到服务器并训练深度学习模型下载服务器文件到本地

前言&#xff1a;本文教程为&#xff0c;上传文件到服务器并训练深度学习模型&#xff0c;与下载服务器文件到本地。演示指令输入&#xff0c;完整的上传文件到服务器&#xff0c;并训练模型过程&#xff1b;并演示完整的下载服务器文件到本地的过程。 本文使用的服务器为云服…...

MyBatis如何处理延迟加载?

大家好&#xff0c;我是锋哥。今天分享关于【MyBatis如何处理延迟加载&#xff1f;】面试题。希望对大家有帮助&#xff1b; MyBatis如何处理延迟加载&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 MyBatis 中&#xff0c;延迟加载&#xff08;Laz…...

制造BOM的应用思考

一、制造BOM的作用 制造BOM(Manufacturing BOM,MBOM)在制造过程中的应用非常广泛,具体包括以下几个方面: 1. 生产计划和调度: 制造BOM提供了生产过程中所需的所有输入及输出间的关系,包括材料、部品的数量、结构以及制程等信息。这些信息是生产拉动物料需求计划以及成本…...

基于earthSDK三维地图组件开发

上效果 功能点 测量分析相机位置切换geojson数据加载地图打点&#xff0c;显示信息点击回传数据二三位切换 这里二三维切换通上篇openlayers分享&#xff0c;技术交流V:bloxed <template><div class"h100 w100"><div style"width:100%; heig…...

Mono里运行C#脚本5—mono_file_map_open

前面介绍了mono_jit_init初始化,这个函数非常长,要理解起来还是比较困难。因此改变另外一种方式,先从底层的函数开始,再慢慢来探索mono的底层实现,以及它的实现原理,运行的细节。 Mono要运行exe文件,这里是运行test-embed.exe文件,那么就得认识这个文件,解释这个文件的…...

Node.js使用教程

Node.js使用教程 Node.js是一个基于Chrome V8引擎的JavaScript运行环境&#xff0c;它让JavaScript运行在服务器端。以下是一个简单的Node.js使用教程&#xff1a; 一、 Node.js开发环境和编译 1.1 安装Node.js 访问Node.js官网下载并安装适合您操作系统的Node.js版本。 1…...

UniApp 组件的深度运用

一、引言 在当今的移动应用开发领域&#xff0c;跨平台开发已成为主流趋势&#xff0c;而 UniApp 作为其中的佼佼者&#xff0c;备受开发者青睐。UniApp 的强大之处很大程度上源于其丰富且功能多样的组件体系&#xff0c;这些组件宛如精巧的积木&#xff0c;能够帮助开发者快速…...

期末算法分析程序填空题

目录 5-1 最小生成树&#xff08;普里姆算法&#xff09; 5-2 快速排序&#xff08;分治法&#xff09; 输入样例&#xff1a; 输出样例&#xff1a; 5-3 归并排序(递归法) 输入样例&#xff1a; 输出样例&#xff1a; 5-4 求解编辑距离问题&#xff08;动态规划法&#xff09;…...

【机器学习】 卷积神经网络 (CNN)

文章目录 1. 为什么需要 CNN2. CNN 的架构3. 卷积层4. 池化层5. CNN 的应用 1. 为什么需要 CNN 前提&#xff1a;利用前置知识&#xff0c;去掉全连接神经网络中的部分参数&#xff0c;提升学习效率。本质&#xff1a;在 DNN 之前加上 CNN&#xff0c;先去除不必要的参数&…...

LeetCode热题100-字母异位词分组【JavaScript讲解】

题目&#xff1a; 根据题目想思路&#xff1a; 模式识别: 一旦需要根据特征进行归类的&#xff0c;就应该利用散列表。【散列表又叫哈希表】 我们遍历数组中的每一项&#xff0c;将每一项字符串拆分成一个一个的字符&#xff0c;并返回成数组的形式&#xff0c;并且进行排序后…...

面试241228

面试可参考 1、cas的概念 2、AQS的概念 3、redis的数据结构 使用场景 不熟 4、redis list 扩容流程 5、dubbo 怎么进行服务注册和调用&#xff0c;6、dubbo 预热 7如何解决cos上传的安全问题kafka的高并发高吞吐的原因ES倒排索引的原理 spring的 bean的 二级缓存和三级缓存 spr…...

AI界的拼多多:DeepSeek

AI界的拼多多:DeepSeek DeepSeek是一家位于中国杭州的人工智能基础技术研究公司,由杭州幻方量化投资管理合伙企业投资成立于2023年5月,专注于研究人工智能基础技术,其官网为deepseek.com.以下是关于DeepSeek的一些具体介绍及举例: 模型发布 DeepSeek Coder:2023年11月…...

备战春招 | 数字IC FPGA笔试题

在数字电路设计的领域&#xff0c;无论是数字IC&#xff08;集成电路&#xff09;还是FPGA&#xff08;现场可编程门阵列&#xff09;的设计&#xff0c;都需要对一系列核心概念有深刻的理解和掌握。随着科技的快速发展&#xff0c;这些领域的面试题目也在不断更新&#xff0c;…...

微服务-Sentinel新手入门指南

微服务为什么要使用流控降级组件 为了提高系统运行期间的稳定性和可用性 在微服务环境下&#xff0c;服务之间存在复杂的调用关系&#xff0c;单个服务的故障或过载可能会迅速影响到整个系统&#xff0c;导致服务雪崩效应。流控组件可以限制进入系统的流量&#xff0c;防止系…...

git clone 超时

git clone 超时 参考 https://blog.csdn.net/qq_45906972/article/details/142214187?utm_mediumdistribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-142214187-blog-137158358.235v43pc_blog_bottom_relevance_base8&spm1001.2101.3001.…...

java的bio、nio、aio 以及操作系统的select、poll、epoll

在 Java 和其他编程语言中&#xff0c;I/O 模型的选择对网络应用的性能和可扩展性有着重要影响。以下是 BIO&#xff08;Blocking I/O&#xff09;、NIO&#xff08;Non-blocking I/O&#xff09;、AIO&#xff08;Asynchronous I/O&#xff09;&#xff0c;以及操作系统级别的…...

Redis——数据过期策略

文章目录 1. 引入2. 数据过期策略2.1 策略一&#xff1a;惰性删除2.1.1 原理2.1.2 优点2.1.3 缺点 2.2 策略二&#xff1a;定期删除2.2.1 原理2.2.2 模式2.2.3 优点2.2.4 缺点 2.3 两种策略的比较 3. 总结 1. 引入 Redis 是一个 高性能 的非关系型数据库&#xff0c;由于 Redi…...

kubernetes Gateway API-1-部署和基础配置

文章目录 1 部署2 最简单的 Gateway3 基于主机名和请求头4 重定向 Redirects4.1 HTTP-to-HTTPS 重定向4.2 路径重定向4.2.1 ReplaceFullPath 替换完整路径4.2.2 ReplacePrefixMatch 替换路径前缀5 重写 Rewrites5.1 重写 主机名5.2 重写 路径5.2.1 重新完整路径5.2.1 重新部分路…...

二、SQL语言,《数据库系统概念》,原书第7版

文章目录 一、概览SQL语言1.1 SQL 语言概述1.1.1 SQL语言的提出和发展1.1.2 SQL 语言的功能概述 1.2 利用SQL语言建立数据库1.2.1 示例1.2.2 SQL-DDL1.2.2.1 CREATE DATABASE1.2.2.2 CREATE TABLE 1.2.3 SQL-DML1.2.3.1 INSERT INTO 1.3 用SQL 语言进行简单查询1.3.1 单表查询 …...

【postgresql 物化视图】自动刷新物化视图2种方法

普通视图就是一个虚拟表&#xff0c;不占内存。而物化视图是存在的&#xff0c;占内存。 物化视图&#xff0c;默认是手动刷新。下面是手动刷新的例子。我们来创建一个物化视图。 create MATERIALIZED VIEW dnh_analasis_view as select cjsj,a,b,c,d from table_1; REFRESH …...

1 数据库(下):多表设计 、多表查询 + SQL中的with查询语法(MySQL8.0以后版本才支持这种新语法)+ 数据库优化(索引优化)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、多表设计1 多表设计-概述2 三种多表关系一对多&#xff08;多对一&#xff09;&#xff08;1&#xff09;无外键约束&#xff08;逻辑外键&#xff09;&…...

CPT203 Software Engineering 软件工程 Pt.2 敏捷方法和需求工程(中英双语)

文章目录 3. Aglie methods&#xff08;敏捷方法&#xff09;3.1 Aglie methods&#xff08;敏捷方法&#xff09;3.1.1 特点3.1.2 优点3.1.3 缺点3.1.4 原则3.1.5 计划驱动与敏捷方法的对比 3.2 Scrum3.2.1 Scrum roles3.2.2 Scrum Activities and Artifacts3.2.2.1 Product B…...

【Linux】进度条

本文中&#xff0c;我们来写一个进度条。 本文大纲&#xff1a; 写一个命令行版的进度条。 1.回车换行 2.缓冲区问题&#xff08;本文不深究&#xff09; ​ 2.1测试代码 3.写一个什么样的进度条&#xff1f; ​ version1 ​ version2 回车换行 这俩不是一个概念&…...

期权懂|个股期权的流动性如何?

锦鲤三三每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 个股期权的流动性如何&#xff1f; 个股期权作为场外交易工具&#xff0c;具有较高的灵活性。场外交易意味着交易双方可以直接协商交易条款&#xff0c;这有助于满足不同投资者的…...

U盘格式化工具合集:6个免费的U盘格式化工具

在日常使用中&#xff0c;U盘可能会因为文件系统不兼容、数据损坏或使用需求发生改变而需要进行格式化。一个合适的格式化工具不仅可以清理存储空间&#xff0c;还能解决部分存储问题。本文为大家精选了6款免费的U盘格式化工具&#xff0c;并详细介绍它们的功能、使用方法、优缺…...

Java学习-Redis

简介 Redis诞生于2009年全称是Remote Dictionary Server&#xff0c;远程词典服务器&#xff0c;是一个基于内存的键值型NoSQL数据库。 特征 特征&#xff1a; 键值&#xff08;key-value&#xff09;型&#xff0c;value支持多种不同数据结构&#xff0c;功能丰富 单线程&a…...

Java处理视频思路

1.首先实现断点续传功能。 断点续传实现思路&#xff1a; 前端对文件分块。前端使用多线程一块一块上传&#xff0c;上传前给服务端发一个消息校验该分块是否上传&#xff0c;如果已上传则不再上传。如果从该断点处断网了&#xff0c;下次上传时&#xff0c;前面的分块已经存在…...

Python入门:8.Python中的函数

引言 在编写程序时&#xff0c;函数是一种强大的工具。它们可以将代码逻辑模块化&#xff0c;减少重复代码的编写&#xff0c;并提高程序的可读性和可维护性。无论是初学者还是资深开发者&#xff0c;深入理解函数的使用和设计都是编写高质量代码的基础。本文将从基础概念开始…...

计算机网络 (8)物理层的传输方式

一、串行传输与并行传输 串行传输 定义&#xff1a;串行传输是一种数据传输方式&#xff0c;指的是逐位地按照顺序传输数据。在串行传输中&#xff0c;数据位逐个按照一定的顺序进行传输&#xff0c;可以通过单条线路或信道进行。特点&#xff1a; 逐位传输&#xff1a;串行传输…...

3.微服务灰度发布落地实践(组件灰度增强)

文章目录 前言调用链示图dubbo服务之间的的调链cloud 服务之间的调用链 网关servlet容器: 标签续传1.定义插件2.实现灰度增强拦截 线程池: 标签续传1.拦截Runnable或Callable,接口增强实现标签续传;Callable 插件定义Runnable 插件定义拦载Callabl或Runnable构造(可共用)拦载ru…...

每天40分玩转Django:Django Email

Django Email 一、知识要点总览表 类别知识点基础配置SMTP设置、Email配置项发送方式同步发送、异步发送邮件类型纯文本、HTML邮件、带附件邮件异步任务Celery集成、任务队列高级特性邮件模板、批量发送 二、Email基础配置 1. 配置settings.py # settings.py EMAIL_BACKEN…...

ipad如何直连主机(Moonlight Sunshine)

Windows 被连接主机&#xff08;Windows&#xff09; 要使用的话需要固定ip&#xff0c;不然ip会换来换去&#xff0c;固定ip方法本人博客有记载Github下载Sunshine Sunshine下载地址除了安装路径需要改一下&#xff0c;其他一路点安装完成后会打开Sunshine的Web UI&#xff…...

linux 网络安全不完全笔记

一、安装Centos 二、Linux网络网络环境设置 a.配置linux与客户机相连通 b.配置linux上网 三、Yum详解 yum 的基本操作 a.使用 yum 安装新软件 yum install –y Software b.使用 yum 更新软件 yum update –y Software c.使用 yum 移除软件 yum remove –y Software d.使用 yum …...

一、Hadoop概述

文章目录 一、Hadoop是什么二、Hadoop发展历史三、Hadoop三大发行版本1. Apache Hadoop2. Cloudera Hadoop3. Hortonworks Hadoop 四、Hadoop优势1. 高可靠性2. 高扩展性3. 高效性4. 高容错性 五、Hadoop 组成1. Hadoop1.x、2.x、3.x区别2. HDFS 架构概述3. YARN 架构概述4. Ma…...

Android 转场动画合集

项目背景&#xff1a;mvvm组件化&#xff0c;然后由于领导要求&#xff0c;使用MainActivity为主界面&#xff0c;各种业务使用Fragment处理。所以~ 由于单独ActivityN Fragment 的方式&#xff0c;经过十多天的试错&#xff0c;我确认一件事情。再确认过架构方式后一定要了解下…...

STM32 软件I2C读写

单片机学习&#xff01; 目录 前言 一、软件I2C读写代码框架 二、I2C初始化 三、六个时序基本单元 3.1 引脚操作的封装和改名 3.2 起始条件执行逻辑 3.3 终止条件执行逻辑 3.4 发送一个字节 3.5 接收一个字节 3.5 发送应答&接收应答 3.5.1 发送应答 3.5.2 接…...

MySQL数据导出导出的三种办法(1316)

数据导入导出 基本概述 目前常用的有3中数据导入与导出方法&#xff1a; 使用mysqldump工具&#xff1a; 优点&#xff1a; 简单易用&#xff0c;只需一条命令即可完成数据导出。可以导出表结构和数据&#xff0c;方便完整备份。支持过滤条件&#xff0c;可以选择导出部分数据…...

三层交换机配置

✍作者&#xff1a;柒烨带你飞 &#x1f4aa;格言&#xff1a;生活的情况越艰难&#xff0c;我越感到自己更坚强&#xff1b;我这个人走得很慢&#xff0c;但我从不后退。 &#x1f4dc;系列专栏&#xff1a;网路安全入门系列 目录 一&#xff0c;三层交换二&#xff0c;实验案…...

odoo中@api.model, @api.depends和@api.onchange 装饰器的区别

文章目录 1. api.model用途特点示例 2. api.depends用途特点示例 3. api.onchange用途特点示例 总结 在 Odoo 中&#xff0c;装饰器&#xff08;decorators&#xff09;用于修饰方法&#xff0c;以指定它们的行为和触发条件。api.model、api.depends 和 api.onchange 是三个常用…...

Mysql的事务隔离机制

文章目录 事务基础概念隔离性与隔离机制的重要性四种隔离级别读未提交读已提交可重复读串行化 隔离级别设置与查看 事务基础概念 事务是一组数据库操作&#xff0c;这些操作要么全部成功执行&#xff0c;要么全部不执行。在 MySQL 中&#xff0c;事务通常以START TRANSACTION开…...

鸿蒙项目云捐助第二十八讲云捐助项目首页组件云数据库加载轮播图

鸿蒙项目云捐助第二十八讲云捐助项目首页组件云数据库加载轮播图 在前面的章节中实现了云捐赠项目的底部导航和分类导航&#xff0c;本讲继续使用云技术丰富首页组件中的功能。这里使用云数据库进行首页组件轮播图的加载。 一、云数据库进行首页组件轮播图的加载 在云捐助项…...

vue项目搭建规范

项目搭建规范 一. 代码规范1.1. 集成editorconfig配置1.2. 使用prettier工具1.3. 使用ESLint检测1.4. git Husky和eslint1.5. git commit规范1.5.1. 代码提交风格1.5.2. 代码提交验证 二. 第三方库集成2.1. vue.config.js配置2.2. vue-router集成2.3. vuex集成2.4. element-plu…...

Spring Boot的开发工具(DevTools)模块中的热更新特性导致的问题

问题&#xff1a; java.lang.ClassCastException: class cn.best.scholarflow.framework.system.domain.entity.SysUser cannot be cast to class cn.best.scholarflow.framework.system.domain.entity.SysUser (cn.best.scholarflow.framework.system.domain.…...

Unity Shader TexelSize的意义

TexelSize在制作玻璃折射效果时会用到。 // Get the normal in tangent space fixed3 bump UnpackNormal(tex2D(_BumpMap, i.uv.zw)); // Compute the offset in tangent space float2 offset bump.xy * _Distortion * _RefractionTex_TexelSize.xy; i.scrPos.xy offset * i…...