【Streamlit学习】关于Streamlit和Python多线程(1)

stop_or_rec_confirm = False
try:
    while stop_or_rec is False or stop_or_rec_confirm is False:
        with sd.InputStream(fs, channels=1) as stream:
            global duration
            audio_data.extend(stream.read(int(duration * fs)))  # 读取一定数量的音频数据
            time.sleep(0.001)  # 等待一小段时间,避免过快的循环
        if stop_or_rec:
            stop_or_rec_confirm = True
    if stop_or_rec_confirm:
        try:
            sd.stop()
            st.info("正在停止录音")  #这里的写法是不对的
            audio_data[:] = [item for item in audio_data if not isinstance(item, bool)]
            combined_array = np.vstack(audio_data)
            sf.write(filename, combined_array, fs, subtype='PCM_16')
            print("录音完成!已保存为 {}".format(filename))
        except:
            print("保存出错")
finally:
    mutex.release()  # 释放互斥锁

这里的st.info("正在停止录音")是不对的,会导致以下问题:



Thread ‘Thread-14 (record_audio_thread)’: missing ScriptRunContext


因此,想要停止录音线程,只能使用全局变量(上面代码中的stop\_or\_rec)。


## 第二坑:不限制录音时长,随时结束录音。


我使用的是sounddevice库,但是它有个问题,就是需要将录制的数据长度作为参数输入,才可以记录数据。比如这段代码:



with sd.InputStream(fs, channels=1) as stream:
global duration
audio_data.extend(stream.read(int(duration * fs))) # 读取一定数量的音频数据
time.sleep(0.001) # 等待一小段时间,避免过快的循环


读取音频流时,需要定义好duration(时长,秒)和fs(采样率),由此计算出读取的样本点数。但是问题来了,如果我并不确定需要录制多久,而是想随时停止录制,这该怎么办呢?


目前采用的方法是将duration设置为5s,每录制5秒就向总的录音数据变量audio\_data中添加一次。这引出了另一个问题,就是当我点击停止录制的按钮时,可能刚好在读取新一轮5秒片段中的第2秒,此时如果立即停止就会导致这最后读的2秒数据没能加入到audio\_data中。


因此,我有设置了一个局部变量stop\_or\_rec\_confirm,当stop\_or\_rec变量被置为True时(即停止录音信号),此时继续让程序把正在读的这5秒数据读完,之后再将stop\_or\_rec\_confirm置为True。当检测到stop\_or\_rec\_confirm为True时,便不再录音,而是保存数据,接收录音。下面是录音线程的完整代码:



def record_audio_thread(fs, filename):
mutex.acquire()
global stop_or_rec, audio_data
stop_or_rec_confirm = False
try:
while stop_or_rec is False or stop_or_rec_confirm is False:
with sd.InputStream(fs, channels=1) as stream:
global duration
audio_data.extend(stream.read(int(duration * fs))) # 读取一定数量的音频数据
time.sleep(0.001) # 等待一小段时间,避免过快的循环
if stop_or_rec:
stop_or_rec_confirm = True
if stop_or_rec_confirm:
try:
sd.stop()
print(“正在停止录音”)
audio_data[:] = [item for item in audio_data if not isinstance(item, bool)]
combined_array = np.vstack(audio_data)
sf.write(filename, combined_array, fs, subtype=‘PCM_16’)
print(“录音完成!已保存为 {}”.format(filename))
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注Python)

img
  • 14
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL可以通过链接分析、站点地图、搜索引擎等方式获取。 请求网页: 爬虫使用HTTP或其他协议向目标URL发起请求,获取网页的HTML内容。这通常通过HTTP请求库实现,如Python中的Requests库。 解析内容: 爬虫对获取的HTML进行解析,提取有用的信息。常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标数据,如文本、图片、链接等。 数据存储: 爬虫将提取的数据存储到数据库、文件或其他存储介质中,以备后续分析或展示。常用的存储形式包括关系型数据库、NoSQL数据库、JSON文件等。 遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施,如验证码、IP封锁等。爬虫工程师需要设计相应的策略来应对这些挑战。 爬虫在各个领域都有广泛的应用,包括搜索引擎索引、数据挖掘、价格监测、新闻聚合等。然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。
Python多线程是一种并发编程技术,可以同时执行多个线程,以提高程序的运行效率。在Python中,可以使用`threading`模块来实现多线程。 下面是一个简单的Python多线程示例: ```python import threading def worker(): print("Worker is running") # 创建线程对象 thread1 = threading.Thread(target=worker) thread2 = threading.Thread(target=worker) # 启动线程 thread1.start() thread2.start() # 等待所有线程结束 thread1.join() thread2.join() ``` 在上面的示例中,我们定义了一个`worker`函数,它会在控制台输出一条消息。然后我们创建了两个线程对象,并使用`start()`方法启动它们。最后,我们使用`join()`方法等待所有线程结束。 需要注意的是,多线程Python中并不一定能够实现真正的并行执行,因为Python的GIL(全局解释器锁)机制限制了多线程的执行效率。这意味着即使在多个线程中同时执行相同的代码,也只有一个线程可以获得CPU资源进行执行。但是,Python多线程对于某些特定的任务仍然是非常有用的,例如I/O密集型任务或者使用多核CPU的系统。 在Python学习多线程时,需要了解以下几点: 1. 线程的创建和启动:需要使用`Thread`类来创建线程对象,并使用`start()`方法来启动线程。 2. 线程的同步:由于GIL机制的存在,Python多线程并不能实现真正的并行执行。因此,需要使用锁、条件变量等机制来保证线程之间的同步和通信。 3. 线程池:可以使用线程池来管理多个线程,以提高程序的运行效率。Python中的`queue`模块提供了线程安全的队列,可以用于实现线程池。 4. 多进程:如果需要更高效的并发编程,可以使用Python的多进程模块`multiprocessing`。它可以更好地利用多核CPU的优势,并避免GIL的影响。 5. 锁的使用:在使用多线程时,需要使用锁来保证线程之间的同步和通信。需要注意避免死锁和竞争条件等问题。 6. 死锁问题:死锁是线程之间相互等待资源导致的问题,可以通过适当的调度策略和使用锁来避免死锁问题的发生。 7. 多线程的优点和缺点:多线程适用于I/O密集型任务和需要并发执行的任务。但是,它也存在一些缺点,如性能开销、资源竞争等问题。需要根据具体的应用场景来选择是否使用多线程。 总之,Python多线程是一种重要的并发编程技术,可以用于提高程序的运行效率。在学习Python多线程时,需要了解其基本原理和常见问题,并根据具体的应用场景来选择是否使用多线程

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值