Python树莓派播放MP3并实时获取振幅教程

python树莓派播放mp3并实时获取振幅教程

本教程旨在解决在Python树莓派环境中播放MP3文件时实时获取音频振幅的挑战。文章详细介绍了如何利用pydub库将MP3文件实时转换为WAV字节流,并结合pyaudio库进行低延迟音频播放和逐帧数据处理。通过处理音频数据块,可以实现振幅的实时监测和可视化,避免了直接处理MP3文件的复杂性,同时解决了传统方法中无法获取播放文件振幅的问题。

实时获取Python中播放MP3文件的振幅

在Python中,尤其是在资源有限的Raspberry Pi上,直接在播放MP3文件的同时获取其实时振幅是一个常见的需求,但标准库如pygame.mixer通常不提供此功能。本文将介绍一种通过结合pydub和pyaudio库,将MP3文件转换为WAV字节流并在播放过程中实时分析振幅的方法。

1. 环境准备与库安装

为了实现MP3的实时转换和音频流处理,我们需要安装以下Python库:

pydub: 用于处理音频文件,包括MP3到WAV的转换。pyaudio: 提供Python绑定,用于PortAudio,实现低延迟的音频输入/输出。

您可以通过pip安装这些库:

pip install pydub pyaudio

此外,pydub依赖于ffmpeg或libav来处理MP3文件。在Raspberry Pi上,您可能需要安装:

立即学习“Python免费学习笔记(深入)”;

sudo apt-get updatesudo apt-get install ffmpeg libav-tools

2. 核心思路:MP3到WAV的内存流转换

MP3是一种压缩格式,直接处理其原始数据以获取振幅较为复杂。WAV文件则是一种无损的未压缩格式,其数据结构更适合直接进行振幅分析。为了避免将MP3文件先保存为WAV文件再读取的磁盘I/O开销,我们可以使用pydub将MP3文件在内存中转换为WAV格式的字节流。

pydub的AudioSegment对象可以加载MP3文件,并使用export方法将其转换为WAV格式的BytesIO对象。这个BytesIO对象可以像文件一样被wave模块读取,从而实现内存中的流处理。

from pydub import AudioSegmentimport ioimport wave# 加载MP3文件mp3_file_path = "kimi_no_shiranai.mp3"audio_segment = AudioSegment.from_mp3(mp3_file_path)# 将AudioSegment导出为WAV格式的BytesIO对象wav_buffer = io.BytesIO()audio_segment.export(wav_buffer, format="wav")wav_buffer.seek(0) # 将缓冲区指针重置到开头# 现在可以使用wave模块打开这个内存中的WAV流wf = wave.open(wav_buffer, 'rb')

3. 使用PyAudio进行音频播放与振幅提取

pyaudio库允许我们打开音频流,将音频数据块写入声卡进行播放,并同时从这些数据块中提取振幅信息。

振幅计算说明:原始问题中提到了一个Amplitude类(例如来自GitHub上的VU meter项目)。这个类通常会封装从原始音频数据(字节)中计算振幅(如RMS,即均方根值)的逻辑,并可能包含显示功能。由于该类的具体实现未提供,在以下示例中,我们将假设存在一个名为Amplitude的类,它有一个静态方法from_data(data)可以从音频数据块中计算振幅。在实际应用中,您需要实现或引入一个这样的类。一个简单的RMS振幅计算示例如下:

import structimport numpy as npdef calculate_rms_amplitude(data, sample_width):    """    从原始音频数据中计算RMS振幅。    data: 字节串形式的音频数据。    sample_width: 每个样本的字节数 (e.g., 2 for 16-bit audio)。    """    if not data:        return 0    # 根据样本宽度解析数据    # 'h' for short (2 bytes), 'i' for int (4 bytes)    fmt = f'{len(data) // sample_width}{"h" if sample_width == 2 else "i"}'    # 解包字节数据为整数数组    try:        samples = struct.unpack(fmt, data)        # 计算RMS        rms = np.sqrt(np.mean(np.array(samples, dtype=np.int64)**2))        return rms    except struct.error:        # 数据可能不完整,返回0或处理错误        return 0

在下面的完整示例中,为了与原问题答案保持一致,我们仍将使用Amplitude.from_data(data)作为振幅计算的占位符。

4. 完整代码示例

以下代码整合了MP3到WAV的内存转换、pyaudio的音频流播放以及实时振幅获取的逻辑。

import pyaudioimport waveimport iofrom pydub import AudioSegmentimport structimport numpy as npimport time # For sleep# 假设的Amplitude类,用于演示振幅计算和显示# 在实际应用中,您需要实现此类的from_data方法,# 或使用上面提供的calculate_rms_amplitude函数。class Amplitude:    def __init__(self, value=0):        self.value = value    @staticmethod    def from_data(data, sample_width=2): # 默认16位音频        # 实际的振幅计算逻辑,这里使用RMS作为示例        return Amplitude(calculate_rms_amplitude(data, sample_width))    def __gt__(self, other):        return self.value > other.value    def display(self, scale=100, mark=None):        # 简单的文本振幅显示        normalized_amp = min(int(self.value / 32767 * scale), scale) # 假设16位最大值32767        bar = '#' * normalized_amp        mark_str = ""        if mark and mark.value > 0:            normalized_mark = min(int(mark.value / 32767 * scale), scale)            if normalized_mark > normalized_amp:                bar = bar + '-' * (normalized_mark - normalized_amp)            mark_str = f" Max: {mark.value:.2f}"        print(f"[{bar.ljust(scale)}] Current: {self.value:.2f}{mark_str}r", end="")# RMS振幅计算函数def calculate_rms_amplitude(data, sample_width):    if not data:        return 0    fmt = f'{len(data) // sample_width}{"h" if sample_width == 2 else "i"}'    try:        samples = struct.unpack(fmt, data)        rms = np.sqrt(np.mean(np.array(samples, dtype=np.int64)**2))        return rms    except struct.error:        return 0def main():    mp3_file_path = "sound.mp3" # 替换为您的MP3文件路径    chunk = 1024 # 每次读取的音频帧数    audio = pyaudio.PyAudio()    stream = None # 初始化stream为None    try:        # 1. MP3文件转换为WAV字节流        print(f"Converting {mp3_file_path} to WAV in memory...")        audio_segment = AudioSegment.from_mp3(mp3_file_path)        wav_buffer = io.BytesIO()        audio_segment.export(wav_buffer, format="wav")        wav_buffer.seek(0)        # 2. 打开内存中的WAV流        wf = wave.open(wav_buffer, 'rb')        # 3. 初始化PyAudio输出流        stream = audio.open(format=audio.get_format_from_width(wf.getsampwidth()),                            channels=wf.getnchannels(),                            rate=wf.getframerate(),                            output=True)        print("Playing audio and monitoring amplitude...")        data = wf.readframes(chunk)        maximal_amplitude = Amplitude(0) # 记录最大振幅        while data:            # 写入流以播放声音            stream.write(data)            # 获取当前数据块的振幅            # 注意:wf.getsampwidth() 返回的是每个样本的字节数            current_amplitude = Amplitude.from_data(data, wf.getsampwidth())            # 更新最大振幅            if current_amplitude > maximal_amplitude:                maximal_amplitude = current_amplitude            # 显示振幅(可选)            current_amplitude.display(scale=50, mark=maximal_amplitude)            # 读取下一个数据块            data = wf.readframes(chunk)        print("nAudio playback finished.")    except FileNotFoundError:        print(f"Error: MP3 file '{mp3_file_path}' not found.")    except Exception as e:        print(f"An error occurred: {e}")    finally:        # 确保关闭音频流和终止PyAudio        if stream:            stream.stop_stream()            stream.close()        audio.terminate()        if 'wf' in locals() and wf:            wf.close() # 关闭wave文件对象        if 'wav_buffer' in locals() and wav_buffer:            wav_buffer.close() # 关闭BytesIO对象if __name__ == "__main__":    main()

5. 注意事项与优化

性能开销: pydub的MP3到WAV转换操作,尤其是在Raspberry Pi上,可能会有一定的CPU开销。对于长时间或高质量的MP3文件,这可能导致轻微的延迟或资源占用。如果性能成为瓶颈,可以考虑预先将MP3文件转换为WAV格式。Amplitude类实现: 示例中的Amplitude类是一个简化版本,仅用于演示。在实际的VU meter项目中,这个类会包含更复杂的逻辑,例如平滑处理、峰值保持、颜色编码等,以提供更专业的视觉反馈。您可以根据需求完善calculate_rms_amplitude函数或引入更专业的音频处理库。缓冲与同步: pyaudio的stream.write()是阻塞的,它会等待数据被写入声卡。这有助于播放和振幅分析之间的同步。然而,如果数据处理(如振幅计算或显示)耗时过长,可能会导致音频播放卡顿。错误处理: 代码中包含了try…finally块,以确保在程序结束或发生错误时正确关闭pyaudio流和终止pyaudio实例,防止资源泄露。Raspberry Pi特定考量: 确保Raspberry Pi的音频输出配置正确。如果遇到播放问题,可以检查alsamixer设置或PulseAudio/ALSA配置。

总结

通过将pydub用于MP3到WAV的内存转换,并结合pyaudio进行低级音频流处理,我们成功实现了在Python中播放MP3文件时实时获取其振幅的功能。这种方法绕过了pygame.mixer的限制,提供了对音频数据的直接访问,为音频可视化、音量监测等应用场景提供了可能。虽然需要额外的库和一些性能考量,但它提供了一个灵活且强大的解决方案。

以上就是Python树莓派播放MP3并实时获取振幅教程的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1375610.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
Python函数输出捕获:深入理解返回值与标准输出重定向
上一篇 2025年12月14日 15:10:30
Python 包管理与虚拟环境最佳实践
下一篇 2025年12月14日 15:10:38

相关推荐

  • Chrome浏览器怎么阻止网站在后台同步_禁止网站后台同步操作设置

    Chrome浏览器怎么阻止网站在后台同步_禁止网站后台同步操作设置Chrome浏览器怎么阻止网站在后台同步_禁止网站后台同步操作设置Chrome浏览器怎么阻止网站在后台同步_禁止网站后台同步操作设置Chrome浏览器怎么阻止网站在后台同步_禁止网站后台同步操作设置

    可通过禁用后台同步权限、移除已授权站点、启用节电模式及使用扩展程序四种方法阻止Chrome网站后台同步。首先在设置中进入“隐私和安全”→“网站设置”→“后台同步”,关闭全局功能或屏蔽特定网站;其次在“已获权限的网站”中删除目标站点的同步权限;然后通过访问chrome://settings/perfo…

    2026年9月24日 用户投稿
    800
  • 使用 Java 获取 ISO 8601 格式的日期和时间

    使用 Java 获取 ISO 8601 格式的日期和时间使用 Java 获取 ISO 8601 格式的日期和时间使用 Java 获取 ISO 8601 格式的日期和时间使用 Java 获取 ISO 8601 格式的日期和时间

    本文介绍了如何使用 Java 获取符合 ISO 8601 标准的日期和时间字符串,例如 2022-10-03T19:45:47.844Z。我们将探讨使用 java.time.Instant 类来获取 UTC 时间,并将其格式化为所需的字符串表示形式。同时,我们还会讨论时间精度以及如何避免使用过时的日…

    2026年9月24日 用户投稿
    000
  • 腾讯专有云企业版 TCE Terraform Provider 开源

    腾讯专有云企业版 TCE Terraform Provider 开源腾讯专有云企业版 TCE Terraform Provider 开源腾讯专有云企业版 TCE Terraform Provider 开源腾讯专有云企业版 TCE Terraform Provider 开源

    腾讯专有云企业版 (tce) 正式宣布开源其 tce terraform provider。该插件基于广受欢迎的基础设施即代码(infrastructure as code)工具 terraform 构建,致力于为 tce 用户提供高效、灵活的自动化资源编排能力。 据悉,TCE Terraform …

    2026年9月24日 用户投稿
    000
  • 快手视频如何增加点赞_快手视频增加点赞的实用方法

    快手视频如何增加点赞_快手视频增加点赞的实用方法快手视频如何增加点赞_快手视频增加点赞的实用方法快手视频如何增加点赞_快手视频增加点赞的实用方法快手视频如何增加点赞_快手视频增加点赞的实用方法

    提升快手视频点赞量需优化封面标题、参与热门话题、使用粉条推广、加强观众互动、注重内容质量。1. 选用精彩画面作封面,标题用疑问句或数字吸引点击;2. 参与“挑战榜”等热门活动并添加话题标签;3. 通过快手粉条设置推广目标为点赞评论,提升曝光;4. 视频结尾提问并及时回复评论,增强粉丝粘性;5. 保证…

    2026年9月24日 用户投稿
    000
  • php-gd怎么销毁图像资源_php-gd释放内存中的图像

    使用imagedestroy()函数销毁PHP-GD图像资源以避免内存泄漏。创建的资源如$image需在处理后调用imagedestroy($image)释放,尤其在循环中应每轮结束前销毁资源,推荐结合is_resource()判断有效性,遵循“谁创建,谁销毁”原则,确保内存高效管理。 在使用 PH…

    2026年9月24日
    000
  • 小鹏汽车累计交付量突破80万台!上半年交付近20万台

    小鹏汽车累计交付量突破80万台!上半年交付近20万台小鹏汽车累计交付量突破80万台!上半年交付近20万台小鹏汽车累计交付量突破80万台!上半年交付近20万台小鹏汽车累计交付量突破80万台!上半年交付近20万台

    7月11日,小鹏汽车通过官方微博宣布,其累计新车交付量已成功突破80万台大关。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ 小鹏G7 数据显示,今年6月份小鹏汽车共交付新车34611台,同比增长高达224%,连续第8个月单月交付量突破3万…

    2026年9月24日 用户投稿
    200
  • 如何通过BIOS调整CPU防掉压(Load-Line Calibration)实现稳定超频?

    如何通过BIOS调整CPU防掉压(Load-Line Calibration)实现稳定超频?如何通过BIOS调整CPU防掉压(Load-Line Calibration)实现稳定超频?如何通过BIOS调整CPU防掉压(Load-Line Calibration)实现稳定超频?如何通过BIOS调整CPU防掉压(Load-Line Calibration)实现稳定超频?

    LLC设置需平衡稳定性与安全性,通过BIOS中CPU防掉压功能减少高负载电压波动,避免系统崩溃;应从中间档位开始测试,配合电压设定调整,使满载时电压略降、轻载不过冲,并结合关闭多核增强、优化VCCIN等设置提升整体稳定性。 实现稳定超频时,CPU防掉压(Load-Line Calibration, …

    2026年9月24日 用户投稿
    000
  • 京东plus月卡能领双11券吗?京东plus有月卡吗

    京东plus月卡能领双11券吗?京东plus有月卡吗京东plus月卡能领双11券吗?京东plus有月卡吗京东plus月卡能领双11券吗?京东plus有月卡吗京东plus月卡能领双11券吗?京东plus有月卡吗

    京东PLUS月卡用户可领双11大额券,需在优惠期内保持会员有效,通过“我的-PLUS会员”进入领券中心,按时领取满减券并结合红包口令提升优惠。 如果您想在短时间内享受京东PLUS会员的专属优惠,但又不想长期付费,可能会考虑月卡服务。关于京东PLUS月卡是否能领取双11大额优惠券的问题,以下是相关信息…

    2026年9月24日 用户投稿
    000
  • Java中实现PDF文档并排对比及差异高亮显示:使用pdfcompare库

    Java中实现PDF文档并排对比及差异高亮显示:使用pdfcompare库Java中实现PDF文档并排对比及差异高亮显示:使用pdfcompare库Java中实现PDF文档并排对比及差异高亮显示:使用pdfcompare库Java中实现PDF文档并排对比及差异高亮显示:使用pdfcompare库

    本文介绍了如何在Java环境中,利用开源库pdfcompare实现两个PDF文档的并排对比,并独立高亮显示其差异。针对传统方案合并PDF的痛点,pdfcompare提供了一种优雅的解决方案,确保原始文档结构不变,仅在各自副本中标记出不同之处,满足特定业务需求。 1. 背景与挑战 在处理文档版本控制或…

    2026年9月24日 用户投稿
    1100
  • 地平线RoboTransfer:几何一致视频世界模型,突破机器人操作泛化边界丨开发者说

    地平线RoboTransfer:几何一致视频世界模型,突破机器人操作泛化边界丨开发者说地平线RoboTransfer:几何一致视频世界模型,突破机器人操作泛化边界丨开发者说地平线RoboTransfer:几何一致视频世界模型,突破机器人操作泛化边界丨开发者说地平线RoboTransfer:几何一致视频世界模型,突破机器人操作泛化边界丨开发者说

    近年来,随着人工智能从感知智能向决策智能演进,世界模型 (world models) 逐渐成为机器人领域的重要研究方向。世界模型旨在让智能体对环境进行建模并预测未来状态,从而实现更高效的规划与决策。 与此同时,具身数据也迎来了爆发式关注。因为目前具身算法高度依赖于大规模的真实机器人演示数据,而这些数…

    2026年9月24日 用户投稿
    100
  • Debian系统如何实现GitLab的高可用性

    Debian系统如何实现GitLab的高可用性Debian系统如何实现GitLab的高可用性Debian系统如何实现GitLab的高可用性Debian系统如何实现GitLab的高可用性

    在debian系统上实现gitlab的高可用性可以通过以下几种方法: 通过Kubernetes进行部署 安装Redis:利用Helm部署Redis,并配置持久化存储以确保数据的持久性。安装PostgreSQL:同样通过Helm部署PostgreSQL,并设置主从复制或集群模式,以确保数据的高可用性。…

    2026年9月24日 用户投稿
    700
  • Java 正则表达式非贪婪匹配替换:精准替换字符串中的特定部分

    Java 正则表达式非贪婪匹配替换:精准替换字符串中的特定部分Java 正则表达式非贪婪匹配替换:精准替换字符串中的特定部分Java 正则表达式非贪婪匹配替换:精准替换字符串中的特定部分Java 正则表达式非贪婪匹配替换:精准替换字符串中的特定部分

    本文旨在解决 Java 中使用正则表达式进行字符串替换时,如何避免过度匹配,实现对特定字符串的精准替换。通过使用单词边界 ,我们可以确保只替换独立的 $c 字符串,而不会影响到 $c_new 等包含 $c 的其他字符串。本文将提供详细的代码示例和解释,帮助开发者掌握这一技巧。 在 Java 中,使用…

    2026年9月24日 用户投稿
    1000
  • 如何在Debian 10(Buster)Linux上安装MySQL

    了解如何在debian 10(buster)linux上安装mysql。本指南将引导您完成在最新版本的debian系统上安装mysql 8或mysql 5.7的步骤。 第1步 – 准备工作 首先,确保您拥有Debian 10系统的shell访问权限。如果是远程系统,可以通过SSH连接。W…

    2026年9月24日
    1000
  • 对话非遗簪花传承人,华硕a豆携豆叮寻香泉州 国庆假期与未来香遇

    对话非遗簪花传承人,华硕a豆携豆叮寻香泉州 国庆假期与未来香遇对话非遗簪花传承人,华硕a豆携豆叮寻香泉州 国庆假期与未来香遇对话非遗簪花传承人,华硕a豆携豆叮寻香泉州 国庆假期与未来香遇对话非遗簪花传承人,华硕a豆携豆叮寻香泉州 国庆假期与未来香遇

    即日起至10月8日,时尚数码潮创先锋华硕a豆于福建泉州限时开启「与未来香遇」 “豆叮的寻香之旅”集章打卡活动,围绕茶桌仔、泉州鲤物、有鲤天台咖啡等三处特色地标打造沉浸式城市寻香狂欢;旗下ip豆叮以头戴非遗簪花的泉州限定皮肤萌力“占领”西街,延续上海安福路街区花车巡游派对的浪漫繁花景象,以“科技与非遗…

    2026年9月24日 用户投稿
    900
  • 铁路12306电子发票下载失败怎么解决_铁路12306电子发票下载问题解决方案

    铁路12306电子发票下载失败怎么解决_铁路12306电子发票下载问题解决方案铁路12306电子发票下载失败怎么解决_铁路12306电子发票下载问题解决方案铁路12306电子发票下载失败怎么解决_铁路12306电子发票下载问题解决方案铁路12306电子发票下载失败怎么解决_铁路12306电子发票下载问题解决方案

    首先检查网络连接并重新尝试下载电子发票,若失败可联系12306客服重发,同时查看邮箱垃圾文件夹,最后可通过个人所得税App等工具同步管理发票。 如果您在尝试下载铁路12306电子发票时遇到失败情况,可能是由于网络连接、系统状态或权限设置等问题导致。以下是针对该问题的多种解决方案。 本文运行环境:iP…

    2026年9月24日 用户投稿
    100
  • AI音频工具有哪些_好用的AI音频工具大全

    AI音频工具有哪些_好用的AI音频工具大全AI音频工具有哪些_好用的AI音频工具大全AI音频工具有哪些_好用的AI音频工具大全AI音频工具有哪些_好用的AI音频工具大全

    ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ 魔音工坊:AI配音神器,轻松打造媲美真人声线 讯飞智作:科大讯飞出品的语音转换与配音利器 听脑AI:智能语音记录助手 Suno:高品质AI音乐创作平台 海绵音乐:字节旗下免费AI音乐创作与探索平…

    2026年9月24日 用户投稿
    300
  • 手机淘宝中如何收藏店铺?手机淘宝中如何收藏店铺信息

    手机淘宝中如何收藏店铺?手机淘宝中如何收藏店铺信息手机淘宝中如何收藏店铺?手机淘宝中如何收藏店铺信息手机淘宝中如何收藏店铺?手机淘宝中如何收藏店铺信息手机淘宝中如何收藏店铺?手机淘宝中如何收藏店铺信息

    1、可通过店铺主页、客服聊天窗口或“我的收藏”反向添加三种方式收藏淘宝店铺。进入店铺主页点击“+店铺”,或从聊天界面点店铺头像后关注,也可在收藏的商品页进店并收藏,操作后可在收藏夹随时访问该店铺。 如果您想在浏览商品时将心仪的商家店铺保存下来以便日后快速访问,可以通过手机淘宝的收藏功能来实现。将店铺…

    2026年9月24日 用户投稿
    400
  • NVIDIA GeForce RTX 4090 液氮超频世界纪录挑战全程

    NVIDIA GeForce RTX 4090 液氮超频世界纪录挑战全程NVIDIA GeForce RTX 4090 液氮超频世界纪录挑战全程NVIDIA GeForce RTX 4090 液氮超频世界纪录挑战全程NVIDIA GeForce RTX 4090 液氮超频世界纪录挑战全程

    RTX 4090液氮超频突破4090MHz,成为首款破4GHz的消费级显卡,七彩虹iGame LAB显卡在液氮冷却下创下3DMark多项世界纪录,展现AD102核心极限性能潜力。 RTX 4090 液氮超频破纪录,不只是频率数字的突破,更是硬件极限与技术操作的集中体现。德国超频高手 CENS 使用七…

    2026年9月24日 用户投稿
    000
  • Java正则表达式:利用词边界实现精确的非贪婪字符串替换

    Java正则表达式:利用词边界实现精确的非贪婪字符串替换Java正则表达式:利用词边界实现精确的非贪婪字符串替换Java正则表达式:利用词边界实现精确的非贪婪字符串替换Java正则表达式:利用词边界实现精确的非贪婪字符串替换

    本教程探讨如何在Java中使用正则表达式精确替换字符串中的特定部分,特别是在目标字符串不应消耗后续字符的场景。通过分析常见错误,文章详细介绍了词边界的原理与应用,展示了如何利用它实现非贪婪且不破坏原字符串结构的替换,确保匹配的精确性与替换结果的完整性。 在处理字符串替换时,我们经常面临需要精确匹配特…

    2026年9月24日 用户投稿
    700
  • ubuntu如何mount一个远程目录

    在ubuntu中挂载一个远程目录,通常可以使用nfs(network file system)或者sshfs(ssh filesystem)。以下是两种方法的步骤: 方法一:使用NFS挂载远程目录 安装NFS客户端(如果尚未安装): sudo apt updatesudo apt install n…

    2026年9月24日
    700

发表回复

登录后才能评论
关注微信