继续折腾树莓派,上篇讲语音觉醒,为下一步开发新功能奠定了基础。从今天开始开发通过语音交互控制的音乐播放器。请大致整理一下这个播放器的实现过程。
首先,这个播放器是网络播放器,是使用百度音乐的API实现的,现在这个界面是免费的,所以很容易实现。当然,也可以尝试其他音乐API接口,或者用爬虫技术实现,但可能不稳定,但练习者还是可以的。百度音乐提供了详细的音乐分类列表。可以通过此链接访问。打开这个页面就知道这是词典。提供hash code、channellist和音乐频道列表,提取一个元素进行分析。每个元素都是词典。例如:
{ ' channel _ id ' ' public _ tuijian _ spring '#通道名称
channel _ name ' ' \ u 6 f 2 b \ u 6 b 65 \ u 6625 \ u 5929 '# utf-8编码格式的通道名称
Channel_order'0,#通道序列号
Cate_id''tuijian '#类-推荐
cate ' ' \ u 63 a 8 \ u 8350 \ u 9891 \ u 9053 '#类-utf-8格式
Cate_order'1,#分类序号
Source_type'1,#源类型
Source_id'0,#源标识号
Pv_order'11} #歌曲分类顺序
是的,在解释完这个channel_list后,需要通过python进行解释,实现歌曲的下载和播放。直接上传代码的话,代码已经做了详细的注释,所以读起来应该比较容易。
#-*-代码: utf-8-*-
Import JSON
Import threading
Import re
Import OS
Import urllib
Import requests
Import urllib2
Import随机
From voice import Voice
Import voiceAPI
Voice=Voice()
BaiduAPI=voiceAPI。BaiDuAPI()
# turling API=voice API . turling API()
BaiduAPI.getToken()
Import插槽
(10)
Def CNNError():
Url='音频;#语音播放连接错误蜂鸣音,录制预先制作的音频
Os.sys('mpg123 '%s''%url) #调用mpg123程序播放音频文件
Return
Def dialogue(text): #合成并播放一段话
tree :
Url=百度api.voicesynthesis(文本)
Except:
Url1='音频;
Os.system('mpg123 '%s''%url1)
Return
Voice.playVoice(url)
#
defget _ channel _ list(page _ URL): #获取通道列表函数
tree :
htmldoc=urllib 2 . urlopen(page _ URL)。read()。decode ('utf8 ')
Except:
Return {}
With open('模式=' w') asfile:
(htmlDoc)
file=open(' c;)。
内容=j(文件)
channel _ list=content[' channel _ list ']
单击“”
#output the channel_list:
For channel in channel_list:
Print(channel['channel_name'])
单击“”
Return channel_list
defget _ song _ list(channel _ URL): #获取该频道的歌曲列表函数
tree :
htmldoc=urllib 2 . urlopen(channel _ URL)。read()。decode ('utf8 ')
Except:
Return{}
#with open('mode=' w 'encoding=' utf-8 ')as file : # python 3
With o
pen(".;,mode = 'w') as file: #python2 (htmlDoc) file = open(';) content = j(file) song_id_list = content['list'] #for song in song_id_list: #print(song['id']) return song_id_list def get_song_real_url(song_url): #获取特定歌曲的链接函数 try: htmlDoc = urllib2.urlopen(song_url).read().decode('utf8') #print(htmlDoc) except: return(None, None, 0) with open(".;, mode = 'w') as file: (htmlDoc) file = open(';) content = j(file) #print(content['data']['songList']) try: song_link = content['data']['songList'][0]['songLink'] song_name = content['data']['songList'][0]['songName'] song_size = int(content['data']['songList'][0]['size']) except: print('get real link failed') return(None, None, 0) #print(song_name + ':' + song_link) return song_name, song_link, song_size def donwn_mp3_by_link(song_link, song_name, song_size): #通过歌曲链接下载歌曲 #file_name = song_name + ".mp3" file_name = "; #save the song as temp base_dir = os.(__file__) file_full_path = os.(base_dir, file_name) if os.(file_full_path): return #print("begin DownLoad %s, size = %d" % (song_name, song_size)) mp3 = urllib2.urlopen(song_link) block_size = 8192 down_loaded_size = 0 #download_success = True file = open(file_full_path, "wb") while True: try: buffer = m(block_size) down_loaded_size += len(buffer) if(len(buffer) == 0): if down_loaded_size < song_size: if os.(file_full_path): os.remove(file_full_path) print('download time out, file deleted') with open('log.txt', 'a') as log_file: log_("time out rm %s\n" % file_name) break #print('%s %d of %d' % (song_name, down_loaded_size, song_size))#show the progress of downloading (buffer) if down_loaded_size >= song_size: print('%s download finshed' % file_full_path) #download_success = True break except: if os.(file_full_path) < song_size: if os.(file_full_path): os.remove(file_full_path) print('download time out, file deleted') with open('log.txt', 'a') as log_file: log_("time out rm %s\n" % file_name) #download_success = False break () #return download_success def downViaMutiThread(song_info_list): #通过多线程下载歌曲本例中未采用 task_threads = [] #存储线程 for song_name, song_link, song_size in song_info_list: t = (target = donwn_mp3_by_link, args = (song_link, song_name, song_size)) (t) for task in task_threads: () for task in task_threads: () # talk to robot to get the song what you like to listen. def conversation(): #通过对话控制播放歌曲 dialogue("需要我帮你推荐吗?") voice.recordVoice() try: recognition_result = baiduAPI.voiceRecognition() except: CNNError() #print(recognition_result) while recognition_result: if "推荐" in recognition_result: channel_selected = "public_tuijian_"+random.choice(["spring","autumn","winter","rege","ktv","billboard","chengmingqu","wangluo","kaiche","yingshi","suibiantingting"]) return channel_selected else: dialogue("请告诉我你喜欢的类型,比如:风格,时光,心情,语种") voice.recordVoice() try: recognition_result = baiduAPI.voiceRecognition() except: CNNError() continue while recognition_result: if "经典" in recognition_result or "老歌" in recognition_result or "老哥" in recognition_result: channel_selected = "public_shiguang_"+"jingdianlaoge" return channel_selected elif "70后" in recognition_result or "七十" in recognition_result or "其实" in recognition_result or "七零" in recognition_result: channel_selected = "public_shiguang_"+"70hou" return channel_selected elif "80后" in recognition_result or "八十" in recognition_result or "八零" in recognition_result: channel_selected = "public_shiguang_"+"80hou" return channel_selected elif "90后" in recognition_result or "九十" in recognition_result or "九零" in recognition_result: channel_selected = "public_shiguang_"+"90hou" return channel_selected elif "儿歌" in recognition_result: channel_selected = "public_shiguang_"+"erge" return channel_selected elif "旅行" in recognition_result or "履行" in recognition_result: channel_selected = "public_shiguang_"+"lvxing" return channel_selected elif "夜店" in recognition_result: channel_selected = "public_shiguang_"+"yedian" return channel_selected elif "流行" in recognition_result: channel_selected = "public_fengge_"+"liuxing" return channel_selected elif "摇滚" in recognition_result: channel_selected = "public_fengge_"+"yaogun" return channel_selected elif "民谣" in recognition_result: channel_selected = "public_fengge_"+"minyao" return channel_selected elif "音乐" in recognition_result: channel_selected = "public_fengge_"+"qingyinyue" return channel_selected elif "小清新" in recognition_result: channel_selected = "public_fengge_"+"xiaoqingxin" return channel_selected elif "中国风" in recognition_result or "中国" in recognition_result: channel_selected = "public_fengge_"+"zhongguofeng" return channel_selected elif "无趣" in recognition_result or "舞曲" in recognition_result or "误区" in recognition_result: channel_selected = "public_fengge_"+"dj" return channel_selected elif "电影原声" in recognition_result or "电影" in recognition_result: channel_selected = "public_fengge_"+"dianyingyuansheng" return channel_selected elif "轻松假日" in recognition_result or "轻松" in recognition_result or "假日" in recognition_result: channel_selected = "public_xinqing_"+"qingsongjiari" return channel_selected elif "欢快" in recognition_result: channel_selected = "public_xinqing_"+"huankuai" return channel_selected elif "甜蜜" in recognition_result: channel_selected = "public_xinqing_"+"tianmi" return channel_selected elif "寂寞" in recognition_result: channel_selected = "public_xinqing_"+"jimo" return channel_selected elif "情歌" in recognition_result: channel_selected = "public_xinqing_"+"qingge" return channel_selected elif "舒缓" in recognition_result: channel_selected = "public_xinqing_"+"shuhuan" return channel_selected elif "慵懒午后" in recognition_result or "慵懒" in recognition_result or "午后" in recognition_result: channel_selected = "public_xinqing_"+"yonglanwuhou" return channel_selected elif "伤感" in recognition_result or "伤" in recognition_result: channel_selected = "public_xinqing_"+"shanggan" return channel_selected elif "华语" in recognition_result or "话语" in recognition_result or "花语" in recognition_result: channel_selected = "public_yuzhong_"+"huayu" return channel_selected elif "欧美" in recognition_result or "英语" in recognition_result: channel_selected = "public_yuzhong_"+"oumei" return channel_selected elif "日语" in recognition_result: channel_selected = "public_yuzhong_"+"riyu" return channel_selected elif "韩语" in recognition_result: channel_selected = "public_yuzhong_"+"hanyu" return channel_selected elif "粤语" in recognition_result or "业余" in recognition_result or "揶揄" in recognition_result: channel_selected = "public_yuzhong_"+"yueyu" return channel_selected else: channel_selected = "public_tuijian_"+random.choice(["spring","autumn","winter","rege","ktv","billboard","chengmingqu","wangluo","kaiche","yingshi","suibiantingting"]) return channel_selected else: channel_selected = "public_tuijian_"+random.choice(["spring","autumn","winter","rege","ktv","billboard","chengmingqu","wangluo","kaiche","yingshi","suibiantingting"]) return channel_selected # to play music 主函数调用上面的函数实现 def Music(): # 第一步,获取频道列表channel page_url = '' channel_list = get_channel_list(page_url) #channel_name_select = input("Please input the channel name: ") channel_name_select = conversation() print(channel_name_select) # 获取歌曲列表 #channel_url = ';format=json&id=%s' % 'public_yuzhong_yueyu' channel_url = ';format=json&id=%s' % channel_name_select #print(channel_url) song_id_list = get_song_list(channel_url) print(song_id_list) song_id_sum = [] for song_id in song_id_list: (song_id['id']) while True: song_choose = random.choice(song_id_sum)#randonly choose a song to download song_url = ";rate=320&songIds=%s" % song_choose song_name, song_link, song_size = get_song_real_url(song_url) if song_size != 0: #single thread way #最后下载歌曲 try: donwn_mp3_by_link(song_link, song_name, song_size) if os.(';): dialogue("这首歌的名字叫:"+song_name+",你想听吗?") voice.recordVoice() try: recognition_result = baiduAPI.voiceRecognition() except: CNNError() continue while recognition_result: if "不" in recognition_result or "换" in recognition_result: break elif "退出" in recognition_result: return else: os.system('mpg123 ;)#play the song. os.system('rm -f ;)#song completed then delete it. break else: os.system('mpg123 ;)#play the song. os.system('rm -f ;)#song completed then delete it. #break # exit the function else: CNNError() break except: CNNError() break else: continueyu 语音识别使用了一些容错处理,但是使用容错要小心,可能会出现误识别的情况。不过这种情况很难避免,确保80%的识别率就很好了。 代码的确长了一点,不过没有特别难理解的地方。暂时还没有想到好的办法实现中断,就是当歌曲播放过程中,如果你不想听了,想换首歌,这个时候用到多线程,目前程序中没有定义主线程和子线程的切换,所以这个功能暂时不能用,只能等播放的歌曲播完,才可以接收语音命令,播放过程中不接受指令。希望你能解决这个问题。 好了,简单的互动网络播放器基本搭建好了,只需要在主程序中调用这个主函数即可。下一篇将介绍新闻播报功能。