轻松拥有整点报时功能

ZhouFall

共 1520字,需浏览 4分钟

 · 2022-03-06

最近苏州疫情比较紧,人宅在家里就比较容易无聊。媳妇打发无聊的方法就是逛淘宝,逛小红书,逛阿里巴巴。不知道是被哪位博主种草了天猫精灵,打算拔草一个。

我是不太喜欢语音控制这类东西的。一是我更喜欢文字,不喜欢发语音,还有就是语音识别的准确性不太高,有很多误识别,需要重复说两三遍的时候就会觉得自己很蠢。身边监控我们日常的电子产品已经很多了,不想再多一个产品监听我的日常。所以我果断拒绝了这一想法。

媳妇又打起了感情牌,说是可以给娃播放早教音乐,放在柜子上看时间也比较方便。“有手机还要天猫精灵看时间么”,我当时就小声嘀咕了。至于放歌这一需求,手机电脑都好放的,家里也有蓝牙音箱。于是我决定自己动手做一下山寨低配简化的天猫精灵

97bace5ec4141dadbe7567d3d3862235.webp

掏出几年前也是闲得无聊的时候买的蓝牙音箱。长这样,熄屏的时候,表面是一面镜子,可以照出我胡子拉碴的盛世美颜。

功能需求分为2块,整点报时和播放儿歌。播放功能基本不用做,蓝牙自带控制功能,主要解决整点报时。整点对于python来说太简单了,time模块和datetime模块都可以解决。1s获取一次最新的时间,约等于有个时钟。每次判断一下时钟和分钟的值是不是都是0就行了。
接下来要解决报时,得有处理好的音频,还有用python播放语音。之前没有处理过音频文件,于是上网搜,小手一抖,找到个现成的。可以用pyaudio库来实现。于是整点报时的代码就变成了:
import time  # 获取时间import wave  # 波形处理import pyaudio  # 播放器

def play_sound(filename): f = wave.open(filename, 'rb') # 加载音频文件(wav) pms = f.getparams() # 获取音频的属性参数 nchannels, sampwidth, framerate, nframes = pms[:4] # 单独提取出各参数的值,并加以定义 p = pyaudio.PyAudio() # 创建一个播放器 s = p.open(format=p.get_format_from_width(sampwidth), channels=nchannels, rate=framerate, output=True) # 将音频转换为音频流 while True: data = f.readframes(1024) # 按照1024大小的块,读取音频数据,得到一系列二进制编码 if data == b'': break s.write(data) # 开始按照音频的参数,播放音频 s.close() p.terminate()

if __name__ == '__main__': while True: t = time.strftime("%H:%M:%S", time.localtime()) print(t) time_list = t.split(':') # time_list[0] 小时 # time_list[1] 分钟 # time_list[2] 秒 if time_list[1] == '00' and time_list[2] == '00': hour = int(time_list[0]) if 6 <= hour < 23: filename = "baoshi/{}.wav".format(hour) # 找到对应的wav文件路径 play_sound(filename) # 播放声音 time.sleep(1)
 如果你要使用的话,只要创建个文件夹,里面放制作好的音频,同时修改第32行,filename即可。眼瞅着需求实现大差不差了,只见甲方爸爸刷着剧,丝毫没有要提供音频文件的意思。我说你见过哪个甲方不给钱提需求,连素材都不提供的么。媳妇淡淡来了一句,甲方不都是这么干的么。深谙需求管理,都怪我之前给她讲PM的故事讲太多了。没有困难的工作,只有勇敢的卷顺。python嘛,网上找找库先。果然找到一个,3行代码解决了音频剪辑的问题,其中还有一行是导入包。行啊。简洁优雅美丽大方。
from pydub import AudioSegmentsong = AudioSegment.from_mp3("end_of_time.mp3")song[33*1000:70*1000].export('end_of_time_slice.mp3'
实际试了一下,有点小问题,需要先安装一下FFmpeg工具。下载地址放这里https://ffmpeg.org/download.html#build-windows。下载到本地后,把bin文件所在目录添加到环境变量里,在命令行输入ffmpeg,没有报错则添加成功。f4d1f64cca278270b06a34ab5c6b524c.webp

再次运行上面的3行代码就没有问题。其中33*1000:70*1000就是提取33s到70s这一段音频。于是网上找了个报时的音频,开始欢快的截起歌来。

按照以往的合作模式,甲方爸爸一直是要源码研究的,虽然我说过要源码得加钱,但是并没有用。出于码农的职业道德,我还是把这段代码封装一下,再加上中文注释,方便甲方爸爸阅读。

from pydub import AudioSegment
def edit_music_signle(name, new_name, start, end=0): # 打开文件名是name的文件 song = AudioSegment.from_mp3(name) # 如果没有输入结束时长 if end == 0: # 就使用歌曲的默认长度 end = len(song) # 歌曲从start到end这部分导出为new_name的文件,格式是wav    song[start:end].export(new_name, format="wav")    edit_music_signle('报时.mp3', '23.wav', 207000, 217500)

把整点报时的分钟和秒钟改成现在时间再多几十秒,简单测试了一下,整点报时功能可以正常运行。

接下来是播放儿歌的问题了。云村一搜儿歌,出来XX巴士,点开听,每个歌开头都有个软广。接下来就是批量剪辑掉开头的这个广告了,python处理批量操作很方便。

先是云村一键下载歌单里的歌,然后批量重命名,因为名字中间有空格,文件读取的时候会出错。然后就是剪掉前2s的声音,再转换成wav格式。pyaudio可以播放wav,能不能播放MP3还没研究,先转换成wav使用起来,后面再找MP3的库。

from pydub import AudioSegmentimport os
def edit_music(filepath): filenames = os.listdir(filepath) for file in filenames: if file.endswith('mp3'): if ' ' in file: new_name = file.split(' ')[2] else: new_name = file os.rename(filepath+file, filepath+new_name) song = AudioSegment.from_mp3(filepath+new_name) new_name = new_name.split('.')[0] song[2*1000:len(song)].export('music_cut/{}.wav'.format(new_name), format="wav")            edit_music('music/')

一顿操作,儿歌就搞定了,欢快的播放起来。fb6adae25218401a981fc7cdded73161.webp

再然后呢?因为使用的是自带的蓝牙功能,所以功能很有限,如果想实现更多的功能,那得解析蓝牙数据。比如长按,组合按键。当然也是有这样的库的,不过是基于v3.5的python实现的,我的是3.9版本,需要安装虚拟环境去解决。暂时就先这样对付甲方爸爸吧,毕竟咱也没打算做成产品级,而且甲方爸爸的新鲜劲儿也不会超过一星期。

想看更多python相关的骚操作,请持续关注,也欢迎提需求哦。


参考网站:
  1. https://blog.csdn.net/u010751000/article/details/106963850  Python 超方便超快速剪辑音乐
  2. https://www.yisu.com/zixun/155666.html  Python 实现整点报时的方法

相关文章:
浏览 129
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报