轻松拥有整点报时功能
最近苏州疫情比较紧,人宅在家里就比较容易无聊。媳妇打发无聊的方法就是逛淘宝,逛小红书,逛阿里巴巴。不知道是被哪位博主种草了天猫精灵,打算拔草一个。
我是不太喜欢语音控制这类东西的。一是我更喜欢文字,不喜欢发语音,还有就是语音识别的准确性不太高,有很多误识别,需要重复说两三遍的时候就会觉得自己很蠢。身边监控我们日常的电子产品已经很多了,不想再多一个产品监听我的日常。所以我果断拒绝了这一想法。
媳妇又打起了感情牌,说是可以给娃播放早教音乐,放在柜子上看时间也比较方便。“有手机还要天猫精灵看时间么”,我当时就小声嘀咕了。至于放歌这一需求,手机电脑都好放的,家里也有蓝牙音箱。于是我决定自己动手做一下山寨低配简化的天猫精灵。
掏出几年前也是闲得无聊的时候买的蓝牙音箱。长这样,熄屏的时候,表面是一面镜子,可以照出我胡子拉碴的盛世美颜。
功能需求分为2块,整点报时和播放儿歌。播放功能基本不用做,蓝牙自带控制功能,主要解决整点报时。整点对于python来说太简单了,time模块和datetime模块都可以解决。1s获取一次最新的时间,约等于有个时钟。每次判断一下时钟和分钟的值是不是都是0就行了。接下来要解决报时,得有处理好的音频,还有用python播放语音。之前没有处理过音频文件,于是上网搜,小手一抖,找到个现成的。可以用pyaudio库来实现。于是整点报时的代码就变成了:
如果你要使用的话,只要创建个文件夹,里面放制作好的音频,同时修改第32行,filename即可。眼瞅着需求实现大差不差了,只见甲方爸爸刷着剧,丝毫没有要提供音频文件的意思。我说你见过哪个甲方不给钱提需求,连素材都不提供的么。媳妇淡淡来了一句,甲方不都是这么干的么。深谙需求管理,都怪我之前给她讲PM的故事讲太多了。没有困难的工作,只有勇敢的卷顺。python嘛,网上找找库先。果然找到一个,3行代码解决了音频剪辑的问题,其中还有一行是导入包。行啊。简洁优雅美丽大方。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)
实际试了一下,有点小问题,需要先安装一下FFmpeg工具。下载地址放这里https://ffmpeg.org/download.html#build-windows。下载到本地后,把bin文件所在目录添加到环境变量里,在命令行输入ffmpeg,没有报错则添加成功。from pydub import AudioSegment
song = AudioSegment.from_mp3("end_of_time.mp3")
song[33*1000:70*1000].export('end_of_time_slice.mp3')
再次运行上面的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 AudioSegment
import 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/')
一顿操作,儿歌就搞定了,欢快的播放起来。
再然后呢?因为使用的是自带的蓝牙功能,所以功能很有限,如果想实现更多的功能,那得解析蓝牙数据。比如长按,组合按键。当然也是有这样的库的,不过是基于v3.5的python实现的,我的是3.9版本,需要安装虚拟环境去解决。暂时就先这样对付甲方爸爸吧,毕竟咱也没打算做成产品级,而且甲方爸爸的新鲜劲儿也不会超过一星期。
想看更多python相关的骚操作,请持续关注,也欢迎提需求哦。
- https://blog.csdn.net/u010751000/article/details/106963850 Python 超方便超快速剪辑音乐
- https://www.yisu.com/zixun/155666.html Python 实现整点报时的方法
相关文章: