YeAudio音频工具的介绍和使用

news/2024/9/15 1:07:27/ 标签: 音视频, 语音识别, python, ffmpeg

夜雨飘零音频工具

这款Python音频处理工具功能强大,支持读取多种格式的音频文件。它不仅能够对音频进行裁剪、添加混响、添加噪声等多种处理操作,还广泛应用于语音识别、语音合成、声音分类以及声纹识别等多个项目领域。

安装

使用pip安装。

pip install yeaudio -U -i https://pypi.tuna.tsinghua.edu.cn/simple

(推荐) 使用源码安装。

git clone https://github.com/yeyupiaoling/YeAudio.git
cd YeAudio
pip install . -i https://pypi.tuna.tsinghua.edu.cn/simple

快速使用

读取普通音频:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file('data/test.wav')
print(f'音频长度:{audio_segment.duration}')
print(f'音频采样率:{audio_segment.sample_rate}')
print(f'音频数据:{audio_segment.samples}')

读取视频中的音频:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file('data/test.mp4')
print(f'音频长度:{audio_segment.duration}')
print(f'音频采样率:{audio_segment.sample_rate}')
print(f'音频数据:{audio_segment.samples}')

API文档


def __init__(self, samples, sample_rate):

创建单通道音频片段实例

参数:

  • samples(ndarray.float32): 频数据,维度为[num_samples x num_channels]
  • sample_rate(int): 音频的采样率

示例代码:

python">import soundfile
from yeaudio.audio import AudioSegmentsamples, sample_rate = soundfile.read("data/test.wav")
audio_segment = AudioSegment(samples, sample_rate)
print(audio_segment.samples)


def __eq__(self, other):

返回两个对象是否相等

参数:

  • other(AudioSegment): 比较的另一个音频片段实例

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment1 = AudioSegment.from_file("data/test.wav")
audio_segment2 = AudioSegment.from_file("data/test.wav")
print(audio_segment1 == audio_segment2)


def __ne__(self, other):

返回两个实例是否不相等

参数:

  • other(AudioSegment): 比较的另一个音频片段实例

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment1 = AudioSegment.from_file("data/test.wav")
audio_segment2 = AudioSegment.from_file("data/test.wav")
print(audio_segment1 != audio_segment2)


def __str__(self):

返回该音频的信息

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
print(str(audio_segment))


@classmethod
def from_file(cls, file):

从音频文件创建音频段,支持wav、mp3、mp4等多种音频格式

参数:

  • file(str|BufferedReader): 件路径,或者文件对象

返回:

  • AudioSegment:音频片段实例

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file('data/test.wav')
print(audio_segment.samples)


@classmethod
def slice_from_file(cls, file, start=None, end=None):

只加载一小段音频,而不需要将整个文件加载到内存中,这是非常浪费的。

参数:

  • file(str|file): 输入音频文件路径或文件对象
  • start(float): 开始时间,单位为秒。如果start是负的,则它从末尾开始计算。如果没有提供,这个函数将从最开始读取。
  • end(float): 结束时间,单位为秒。如果end是负的,则它从末尾开始计算。如果没有提供,默认的行为是读取到文件的末尾。

返回:

  • AudioSegment:AudioSegment输入音频文件的指定片的实例

异常:

  • ValueError:如果开始或结束的设定不正确,则会抛出ValueError异常

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.slice_from_file('data/test.wav', start=1, end=2)
print(audio_segment.samples)


@classmethod
def from_bytes(cls, data):

从wav格式的音频字节创建音频段

参数:

  • data(bytes): 包含音频样本的字节

返回:

  • AudioSegment:音频片段实例

示例代码:

python">from yeaudio.audio import AudioSegmentwith open('data/test.wav', 'rb') as f:data = f.read()audio_segment = AudioSegment.from_bytes(data)print(audio_segment.samples)


@classmethod
def from_pcm_bytes(cls, data, channels=1, samp_width=2, sample_rate=16000):

从包含无格式PCM音频的字节创建音频

参数:

  • data(bytes): 包含音频样本的字节
  • channels(int): 音频的通道数
  • samp_width(int): 频采样的宽度,如np.int16为2
  • sample_rate(int): 音频样本采样率

返回:

  • AudioSegment:音频片段实例

示例代码:

python">from yeaudio.audio import AudioSegmentwith open('data/test.wav', 'rb') as f:data = f.read()audio_segment = AudioSegment.from_pcm_bytes(data[44:], channels=1, samp_width=2, sample_rate=16000)print(audio_segment.samples)


@classmethod
def from_ndarray(cls, data, sample_rate=16000):

从numpy.ndarray创建音频段

参数:

  • data(bytes): numpy.ndarray类型的音频数据
  • sample_rate(int): 音频样本采样率

返回:

  • AudioSegment:音频片段实例

示例代码:

python">import soundfilefrom yeaudio.audio import AudioSegmentsamples, sample_rate = soundfile.read('data/test.wav')
audio_segment = AudioSegment.from_ndarray(samples, sample_rate=16000)
print(audio_segment.samples)


@classmethod
def concatenate(cls, *segments):

将任意数量的音频片段连接在一起

参数:

  • segments(AudioSegment): 输入音频片段被连接

返回:

  • AudioSegment:音频片段实例

异常:

  • ValueError:如果音频实例列表为空或者采样率不一致,则会抛出ValueError异常
  • TypeError:如果输入的片段类型不一致,则会抛出TypeError异常

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment1 = AudioSegment.from_file('data/test.wav')
audio_segment2 = AudioSegment.from_file('data/test.wav')
audio_segment = AudioSegment.concatenate(audio_segment1, audio_segment2)
print(audio_segment.samples)


@classmethod
def make_silence(cls, duration, sample_rate):

创建给定持续时间和采样率的静音音频段

参数:

  • duration(float): 静音的时间,以秒为单位
  • sample_rate(int): 音频采样率

返回:

  • AudioSegment:给定持续时间的静音AudioSegment实例

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.make_silence(duration=10, sample_rate=16000)
print(audio_segment.samples)


def to_wav_file(self, filepath, dtype=‘float32’):

保存音频段到磁盘为wav文件

参数:

  • filepath(str|file): WAV文件路径或文件对象,以保存音频段
  • dtype(str): 音频数据类型,可选: ‘int16’, ‘int32’, ‘float32’, ‘float64’

异常:

  • TypeError:如果类型不支持,则会抛出TypeError异常

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.to_wav_file("output.wav")


def superimpose(self, other):

将另一个段的样本添加到这个段的样本中(以样本方式添加,而不是段连接)。

参数:

  • other(AudioSegments): WAV文件路径或文件对象,以保存音频段
  • dtype(str): 音频数据类型,可选: ‘int16’, ‘int32’, ‘float32’, ‘float64’

异常:

  • ValueError:如果两段音频采样率或者长度不一致,则会抛出ValueError异常
  • TypeError:如果两个片段的类型不匹配,则会抛出TypeError异常

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
other_segment = AudioSegment.from_file("data/test.wav")
audio_segment.superimpose(other_segment)


def to_bytes(self, dtype=‘float32’):

创建包含音频内容的字节字符串

参数:

  • dtype(str): 导出样本的数据类型。可选: ‘int16’, ‘int32’, ‘float32’, ‘float64’

返回:

  • str:包含音频内容的字节字符串

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
print(audio_segment.to_bytes())


def to(self, dtype=‘int16’):

类型转换

参数:

  • dtype(str): 导出样本的数据类型。可选: ‘int16’, ‘int32’, ‘float32’, ‘float64’

返回:

  • str:转换后的数据

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
print(audio_segment.to(dtype='int16'))


def gain_db(self, gain):

对音频施加分贝增益。

参数:

  • gain(float|1darray): 用于样品的分贝增益

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.gain_db(gain=-20)
print(audio_segment.samples)


def change_speed(self, speed_rate):

通过线性插值改变音频速度。

参数:

  • speed_rate(float): 修改的音频速率: speed_rate > 1.0, 加快音频速度; speed_rate = 1.0, 音频速度不变; speed_rate < 1.0, 减慢音频速度; speed_rate <= 0.0, 错误数值.

异常:

  • ValueError:如果速度速率小于或等于0,则引发ValueError

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.change_speed(speed_rate=1.2)
print(audio_segment.samples)


def normalize(self, target_db=-20, max_gain_db=300.0):

将音频归一化,使其具有所需的有效值(以分贝为单位)。

参数:

  • target_db(float): 目标均方根值,单位为分贝。这个值应该小于0.0,因为0.0是全尺寸音频。
  • max_gain_db(float): 最大允许的增益值,单位为分贝,这是为了防止在对全0信号进行归一化时出现Nan值。

异常:

  • ValueError:如果所需的增益大于max_gain_db,则引发ValueError

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.normalize(target_db=-20)
print(audio_segment.samples)


def resample(self, target_sample_rate, filter=‘kaiser_best’):

按目标采样率重新采样音频。

参数:

  • target_sample_rate(int): 目标均方根值,单位为分贝。这个值应该小于0.0,因为0.0是全尺寸音频。
  • filter(str): 使用的重采样滤波器,支持’kaiser_best’、‘kaiser_fast’

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.resample(target_sample_rate=8000)
print(audio_segment.samples)


def pad_silence(self, duration, sides=‘both’):

在这个音频样本上加一段静音。

参数:

  • duration(float): 静默段的持续时间(以秒为单位)
  • sides(str): 添加的位置: ‘beginning’ - 在开始位置前增加静音段; ‘end’ - 在结束位置增加静音段; ‘both’ - 在开始和结束位置都增加静音段.。

异常:

  • ValueError:如果sides的值不是beginning、end或both,则引发ValueError

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.pad_silence(duration=2, sides='end')
print(audio_segment.samples)


def pad(self, pad_width, mode=‘wrap’, **kwargs):

在这个音频样本上加一段音频,等同numpy.pad。

参数:

  • pad_width(sequence|array_like|int): 填充宽度
  • sides(str|function|optional): 填充模式

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.pad(pad_width=(0, 16000 * 2), mode='wrap')
print(audio_segment.samples)


def shift(self, shift_ms):

音频偏移。如果shift_ms为正,则随时间提前移位;如果为负,则随时间延迟移位。填补静音以保持持续时间不变。

参数:

  • shift_ms(float): 偏移时间。如果是正的,随时间前进;如果负,延时移位。

异常:

  • ValueError:如果shift_ms的绝对值大于音频持续时间,则引发ValueError

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.shift(shift_ms=1000)
print(audio_segment.samples)


def subsegment(self, start_sec=None, end_sec=None):

在给定的边界之间切割音频片段。

参数:

  • start_sec(float): 开始裁剪的位置,以秒为单位,默认为0。
  • end_sec(float): 结束裁剪的位置,以秒为单位,默认为音频长度。

异常:

  • ValueError:如果start_sec或end_sec的值越界,则引发ValueError

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.subsegment(start_sec=1, end_sec=3)
print(audio_segment.samples)


def random_subsegment(self, duration):

随机剪切指定长度的音频片段。

参数:

  • duration(float): 随机裁剪的片段长度,以秒为单位

异常:

  • ValueError:如果片段长度大于原始段,则引发ValueError

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.random_subsegment(duration=2)
print(audio_segment.samples)


def reverb(self, reverb_file, allow_resample=True):

使音频片段混响。

参数:

  • reverb_file(str): 混响音频的路径
  • allow_resample(bool): 指示是否允许在两个音频段具有不同的采样率时重采样

异常:

  • ValueError:如果两个音频段之间的采样率不匹配,则引发ValueError

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.reverb(reverb_file='data/reverb.wav')
print(audio_segment.samples)


def reverb_and_normalize(self, reverb_file, allow_resample=True):

使音频片段混响,然后归一化。

参数:

  • reverb_file(str): 混响音频的路径
  • allow_resample(bool): 指示是否允许在两个音频段具有不同的采样率时重采样

异常:

  • ValueError:如果两个音频段之间的采样率不匹配,则引发ValueError

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.reverb_and_normalize(reverb_file='data/reverb.wav')
print(audio_segment.samples)


def add_noise(self, noise_file, snr_dB, max_gain_db=300.0, allow_resample=True):

以特定的信噪比添加给定的噪声段。如果噪声段比该噪声段长,则从该噪声段中采样匹配长度的随机子段。

参数:

  • noise_file(str): 噪声音频的路径
  • snr_dB(float): 信噪比,单位为分贝
  • max_gain_db(float): 最大允许的增益值,单位为分贝,这是为了防止在对全0信号进行归一化时出现Nan
  • allow_resample(bool): 指示是否允许在两个音频段具有不同的采样率时重采样

异常:

  • ValueError:如果两个音频段之间的采样率不匹配,则引发ValueError

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.add_noise(noise_file='data/noise.wav', snr_dB=10)
print(audio_segment.samples)


def crop(self, duration, mode=‘eval’):

根据模式裁剪指定的音频长度,如果为’train’模式,则随机剪切,否则从末尾剪切。

参数:

  • duration(float): 裁剪的音频长度,以秒为单位
  • mode(str): 裁剪的模型,‘train’或’eval’

异常:

  • ValueError:如果两个音频段之间的采样率不匹配,则引发ValueError

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
audio_segment.crop(duration=3, mode='train')
print(audio_segment.samples)


def vad(self, return_seconds=False, **kwargs):

创建给定持续时间和采样率的静音音频段

参数:

  • return_seconds(bool): 指示是否返回秒数而不是样本索引
  • kwargs(dict): 传递给Silero VAD模型的参数

返回:

  • List[Dict]:语音活动时间戳列表

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file("data/test.wav")
speech_timestamps = audio_segment.vad(return_seconds=True)
for speech_timestamp in speech_timestamps:print(speech_timestamp)


@property
def samples(self):

返回音频样本

返回:

  • float:返回音频样本

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file('data/test.wav')
print(audio_segment.samples)


@property
def sample_rate(self):

返回音频采样率

返回:

  • int:返回音频采样率

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file('data/test.wav')
print(audio_segment.sample_rate)


@property
def num_samples(self):

返回样品数量

返回:

  • int:返回样品数量

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file('data/test.wav')
print(audio_segment.num_samples)


@property
def duration(self):

返回音频持续时间,以秒为单位

返回:

  • float:返回音频持续时间,以秒为单位

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file('data/test.wav')
print(audio_segment.duration)


@property
def rms_db(self):

返回以分贝为单位的音频均方根能量

返回:

  • float:返回以分贝为单位的音频均方根能量

示例代码:

python">from yeaudio.audio import AudioSegmentaudio_segment = AudioSegment.from_file('data/test.wav')
print(audio_segment.rms_db)


http://www.ppmy.cn/news/1518761.html

相关文章

设计模式-结构型模式-享元模式

1.享元模式定义 摒弃了在每个对象中保存所有数据的方式&#xff0c;通过共享多个对象所共有的相同状态&#xff0c;从而让我们能在有限的内存容量中载入更多对象&#xff1b; 1.1 享元模式优缺点 优点 极大减少内存中相似或相同对象数量&#xff0c;节约系统资源&#xff0c…

window下kafka3启动多个

准备工作 我们先安装好kafka&#xff0c;并保证启动成功&#xff0c;可参考文章Windows下安装Kafka3-CSDN博客 复制kafka安装文件 kafka3已经内置了zookeeper&#xff0c;所以直接复制就行了 修改zookeeper配置文件 这里我们修改zookeeper配置文件&#xff0c;主要是快照地址…

前端的面试题

Class 与 Style 如何动态绑定&#xff1f; 对象语法&#xff1a; <div v-bind:class"{ active: isActive, text-danger: hasError }"></div> data: {isActive: true,hasError: false }数组语法&#xff1a; <div v-bind:class"[isActive ? acti…

使用tinyxml向xml文件中插入数据

目前已有一个xml文件&#xff0c;内容如下所示。想要在这个文件中间插入一个数据。tinyxml库比较好用。 1.下载tinyxml库文件并添加进工程 在网上下载好tinyxml的库文件&#xff0c;然后放入项目目录中 在qt工程中点击【添加现有文件】&#xff0c;把这6个文件添加进来 2.使…

【WPF】WPF学习之【二】布局学习

WPF布局学习 常用布局Grid网格布局StackPanel 布局CanvasDockPanel布局WrapPanel布局 常用布局 1、StackPanel: 学习如何使用StackPanel进行垂直和水平布局。 2、Grid: 掌握Grid的网格布局技术。 3、Canvas: 了解Canvas的绝对定位布局。 4、DockPanel: 学习DockPanel的停靠…

python基础(15多线程编程介绍)

python系列文章目录 python基础&#xff08;01变量&数据类型&运算符&#xff09; python基础&#xff08;02序列共性&#xff09; python基础(03列表和元组) python基础&#xff08;04字符串&字典&#xff09; python基础&#xff08;05集合set&#xff09; pytho…

滚雪球学MyBatis-Plus(02):环境准备

环境准备 本地开发环境参考如下&#xff1a; 开发工具&#xff1a;IntelliJ IDEA 2021.3.2JDK版本&#xff1a; JDK 1.8Spring Boot版本&#xff1a;2.3.1.RELEASEMaven版本&#xff1a;Apache Maven 3.8.2MySQL&#xff1a;5.6 前言 在上期内容中&#xff0c;我们系统地介绍了…

【UE5】UMG C++父类绑定蓝图子类属性

有时我们在设计UMG时可能会使用到C父类来处理一些通用逻辑&#xff0c;如果我们想要在C父类中获取其派生子类的某个属性&#xff0c;如Image或Button等&#xff0c;我们可以通过使用UE提供的BindWidget元数据标签的方式来获取。 BindWidget BindWidget元数据标签在官方文档中…

【GIS系列】多源异构原始影像解析:策略模式与规则引擎的应用

作者&#xff1a;后端小肥肠 &#x1f347; 我写过的文章中的相关代码放到了gitee&#xff0c;地址&#xff1a;xfc-fdw-cloud: 公共解决方案 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 1. 前言 在遥感技术和地球观测领域&#…

学习记录——day37 C++ 基础概念 字符串 命名空间

目录 一、C相关概念 二、面向对象 三、C框架 四、输出流对象&#xff1a;cout 五、输入流对象 cin 六、输入流对象 输出流对象 示例 1、大小写转换 2、输出斐波那契数列 3、进制转换 宽度 精度 七、命名空间 namespace 1、命名空间的意义 2、程序中的标识符&#xff0…

【学习笔记】第三章深度学习基础——Datawhale X李宏毅苹果书 AI夏令营

局部极小值与鞍点 梯度为0的点我们统称为临界点&#xff0c;包括局部极小值、鞍点等 局部极小值和鞍点的梯度都为0&#xff0c;那如何判断呢&#xff1f; 先请出我们损失函数&#xff1a;L(θ)&#xff0c;θ是模型中的参数的取值&#xff0c;是一个向量。 由于网络的复杂性&a…

React基础面试题

React 面试题 以下是面试官最有可能问到的 50 个 React 面试题和答案。为方便你学习&#xff0c;我对它们进行了分类&#xff1a; 基本知识React 组件React ReduxReact 路由 基本知识 1. 区分Real DOM和Virtual DOM Real DOMVirtual DOM1. 更新缓慢。1. 更新更快。2. 可以…

那么多编程语言,先学哪个?

简单介绍一下几种主要的语言&#xff1a; C&#xff0c;是一种面向对象的编程语言&#xff0c;常用于开发游戏、操作系统和嵌入式系统等性能要求比较高的场景。如果你对这些领域感兴趣&#xff0c;C是一个很好的选择。 Java&#xff0c;也是面向对象的编程语言&#xff0c;特点…

前端宝典二十三:Array最常用的34个方法

这里列举了Array最常用的34个方法 其中静态方法两个、实例方法32个&#xff0c;对他们进行了分类比较&#xff0c;有助于更好的掌握。 一、前言&#xff1a;手写一个深拷贝 以下是一个用 JavaScript 手写的深拷贝方法&#xff0c;考虑了正则表达式、日期对象、数组和普通对象…

12 对话模型微调2

1 P-Tuning P-Tuning 是在 Prompt-Tuning的基础上&#xff0c;通过新增 LSTM 或 MLP 编码模块来加速模型的收敛&#xff1b; 之前的实验也看到了使用prompt训练速度很慢&#xff0c;那么P-Tuning呢 参数占比&#xff1a; trainable params: 5,267,456 || all params: 1,308,37…

Windows服务器应急响应(下)

目录 介绍步骤 介绍 进程&#xff08;Process&#xff09;是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的基本单位&#xff0c;是操作系统结构的基础。在早期面向进程设计的计算机结构中&#xff0c;进程是程序的基本执行实体&#x…

sql 优化,提高查询速度

文章目录 一、前言二、建议2.1 使用索引2.2 避免使用select *2.3. 使用表连接代替子查询2.4. 优化WHERE子句&#xff0c;减少返回结果集的大小2.5 用union all代替union2.6 使用合适的聚合策略2.7 避免在WHERE子句中使用函数2.8 使用EXPLAIN分析查询2.9 小表驱动大表2.10 使用窗…

PHP程序设计教案

文章目录&#xff1a; 一&#xff1a;前言 1.什么是PHP 2.环境安装 3. 语法规范 3.1 注释 3.2 分隔符 3.3 其他规范 二&#xff1a;基础语法 1.输出 1.1 echo 1.2 print 1.3 var_dump类型和值 1.4 print_r()易读 2.常量变量 2.1 常量 2.1.1 define()/const…

vue前端实现登录页面的验证码(新手版)

一、搭建vue前端登录页面 <template><div style"width: 800px; margin: 5px auto; background-color: #17ecf3"><div align"center"><h2>用户登录</h2></div><div style"width: 60%; margin: 1px auto"…

如何解决`.gitignore`规则不生效或已提交相关文件的问题

前言 在使用Git进行版本控制时&#xff0c;.gitignore文件是一个非常有用的工具&#xff0c;它可以帮助我们排除不需要跟踪的文件或目录。然而&#xff0c;在实际开发过程中&#xff0c;有时我们会遇到.gitignore规则不生效的情况&#xff0c;或者是不小心将不应提交的文件提交…