查看: 927|回复: 13

[项目] 【2020】树莓派——语音播报新冠疫情实时数据

[复制链接]
logo.jpg


【演示视频】

(为视频效果,使用循环播报方式)

    此次新型冠状病毒感染的肺炎疫情,不仅给全民造成身体上的危机,还带来心理层面的考验。
    疫情本身属于应激性事件。适当的应激反应是必要的,然而,应激不足和应激过度对身心健康和社会情绪稳定都不利。应激不足,表现为思想麻痹大意、反应迟缓,进不了警觉期。而应激过度则表现为应对措施过猛、公众恐慌等。
    对于大众而言,如果长时间宅在家中,以及过度暴露在负面信息之下,会出现替代性创伤的现象。铺天盖地的疫情信息会对心理造成一些创伤影响,进而影响个人行为。其中一个表现为,持续不断地看手机,心理会出现紧张、担心、焦虑等情绪,“大家会担心疫情数据是多少,到底什么时候过去等等。”
     这是一种对于不可预期事件的焦虑,焦虑的情绪会引发一系列生活问题。情绪和行为相互交织,如果不进行积极的干预,容易形成恶性循环。

     所以,我们应该适度关注疫情,不是不关注,也不是一直关注。
    为了宅在家里为社会做贡献,适当关注疫情,少看手机,宅在家里为武汉加油!今天我使用树莓派获取实时数据,并定时用语音进行播报。(创意来自Shuuei 大神 )


【完整程序代码】python2
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
import urllib2
import time
from datetime import datetime
import pygame  # pip install pygame
from aip import AipSpeech
"""
你的 APPID AK SK 
均可在百度云语音技术服务控制台中的应用列表中查看。
"""
APP_ID = '百度申请的APP_ID '
API_KEY = '百度申请的API_KEY '
SECRET_KEY = '百度申请的SECRET_KEY '
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

def playMusic(filename, loops=0, start=0.0, value=1):
    """
    :param filename: 文件名
    :param loops: 循环次数
    :param start: 从多少秒开始播放
    :param value: 设置播放的音量,音量value的范围为0.0到1.0
    :return:
    """
    flag = False  # 是否播放过
    pygame.mixer.init()  # 音乐模块初始化
    while 1:
        if flag == 0:
            pygame.mixer.music.load(filename)
            # pygame.mixer.music.play(loops=0, start=0.0) loops和start分别代表重复的次数和开始播放的位置。
            pygame.mixer.music.play(loops=loops, start=start)
            pygame.mixer.music.set_volume(value)  # 来设置播放的音量,音量value的范围为0.0到1.0。
        if pygame.mixer.music.get_busy() == True:
            flag = True
        else:
            if flag:
                pygame.mixer.music.stop()  # 停止播放
                break
 

def speak(content):
  result  = client.synthesis(content, 'zh', 3, {
    'vol': 5,
})
# 识别正确返回语音二进制 错误则返回dict 参照下面错误码
  if not isinstance(result, dict):
    with open('auido.mp3', 'wb') as f:
        f.write(result)
        f.close()
        playMusic('auido.mp3')
def timer(n):
 while True:
  a = int(time.time())    #当前时间
  c = datetime.fromtimestamp(a+86400).strftime('%H:%M')    #格式转换
  '''#定时播报
  if c>'08:05':
   l=0
  if c=='08:00' and l==0:
   l=1'''
  if 1:#循环播报
   response=urllib2.urlopen("https://news.163.com/special/epidemic/")
   html=response.read()
   a=html.find('cover_con')
   b=html.find('map_block mb')
   html=html[a:b]
   html=html.decode('gbk','ignore')
   title=html[html.find('cover_li')+10:html.find('/span')-1]
   title1=title[:title.find('<span>')]
   title2=title[title.find('<span>')+6:]
   if title2[7]=='0':
    month=title2[8]
   else:
    month=title2[7:9]
   if title2[10]=='0':
    day=title2[11]
   else:
    day=title2[10:12]
   if title2[13]=='0':
    hour=title2[14]
   else:
    hour=title2[13:15]
   minute=title2[16:]
   title2=title2[:6]+'年'.decode('utf-8')+month+'月'.decode('utf-8')+day+'日'.decode('utf-8')+hour+'时'.decode('utf-8')+minute+'分'.decode('utf-8')

   html=html[html.find('确诊'.decode('utf-8')):]
   quezheng=html[html.find('number')+8:html.find('</div>')]

   html=html[html.find('疑似'.decode('utf-8')):]
   yisi=html[html.find('number')+8:html.find('</div>')]

   html=html[html.find('较昨日'.decode('utf-8')):]
   added=html[html.find('<span>')+6:html.find('</span>')]
   if added[0]=='+':
      added='增加'.decode('utf-8')+added[1:]
   if added[0]=='-':
      added='减少'.decode('utf-8')+added[1:]

   html=html[html.find('死亡'.decode('utf-8')):]
   siwang=html[html.find('number')+8:html.find('</div>')]

   html=html[html.find('治愈'.decode('utf-8')):]
   zhiyu=html[html.find('number')+8:html.find('</div>')]
   print (html)
   print (title1)

   print (title2)
   print (quezheng)
   print (added)
   print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
   speak(title1)
   speak(title2)
   speak('确诊人数'.decode('utf-8')+quezheng)
   speak('疑似人数'.decode('utf-8')+yisi)
   speak('较昨日'.decode('utf-8')+added)
   speak('死亡人数'.decode('utf-8')+siwang)
   speak('治愈人数'.decode('utf-8')+zhiyu)
   time.sleep(n)
timer(5)   


1、寻找恰当网站获取实时数据
找到网易:https://news.163.com/special/epidemic/
2.jpg
因查看其源码,发现数据比较好获取。
3.jpg

2、获取网页源码
[Python] 纯文本查看 复制代码
   response=urllib2.urlopen("https://news.163.com/special/epidemic/")
   html=response.read()

3、针对数据特点,进行截取
[Python] 纯文本查看 复制代码
   a=html.find('cover_con')
   b=html.find('map_block mb')
   html=html[a:b]
   html=html.decode('gbk','ignore')
   title=html[html.find('cover_li')+10:html.find('/span')-1]
   title1=title[:title.find('<span>')]
   title2=title[title.find('<span>')+6:]
   if title2[7]=='0':
    month=title2[8]
   else:
    month=title2[7:9]
   if title2[10]=='0':
    day=title2[11]
   else:
    day=title2[10:12]
   if title2[13]=='0':
    hour=title2[14]
   else:
    hour=title2[13:15]
   minute=title2[16:]
   title2=title2[:6]+'年'.decode('utf-8')+month+'月'.decode('utf-8')+day+'日'.decode('utf-8')+hour+'时'.decode('utf-8')+minute+'分'.decode('utf-8')

   html=html[html.find('确诊'.decode('utf-8')):]
   quezheng=html[html.find('number')+8:html.find('</div>')]

   html=html[html.find('疑似'.decode('utf-8')):]
   yisi=html[html.find('number')+8:html.find('</div>')]

   html=html[html.find('较昨日'.decode('utf-8')):]
   added=html[html.find('<span>')+6:html.find('</span>')]
   if added[0]=='+':
      added='增加'.decode('utf-8')+added[1:]
   if added[0]=='-':
      added='减少'.decode('utf-8')+added[1:]

   html=html[html.find('死亡'.decode('utf-8')):]
   siwang=html[html.find('number')+8:html.find('</div>')]

   html=html[html.find('治愈'.decode('utf-8')):]
   zhiyu=html[html.find('number')+8:html.find('</div>')]

4、利用百度云语音技术对数据转语音mp3,并使用pygame进行朗读
[Python] 纯文本查看 复制代码
import pygame  # pip install pygame

from aip import AipSpeech
"""
你的 APPID AK SK 
均可在百度云语音技术服务控制台中的应用列表中查看。
"""
APP_ID = '百度申请的APP_ID '
API_KEY = '百度申请的API_KEY '
SECRET_KEY = '百度申请的SECRET_KEY '
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

def playMusic(filename, loops=0, start=0.0, value=1):
    """
    :param filename: 文件名
    :param loops: 循环次数
    :param start: 从多少秒开始播放
    :param value: 设置播放的音量,音量value的范围为0.0到1.0
    :return:
    """
    flag = False  # 是否播放过
    pygame.mixer.init()  # 音乐模块初始化
    while 1:
        if flag == 0:
            pygame.mixer.music.load(filename)
            # pygame.mixer.music.play(loops=0, start=0.0) loops和start分别代表重复的次数和开始播放的位置。
            pygame.mixer.music.play(loops=loops, start=start)
            pygame.mixer.music.set_volume(value)  # 来设置播放的音量,音量value的范围为0.0到1.0。
        if pygame.mixer.music.get_busy() == True:
            flag = True
        else:
            if flag:
                pygame.mixer.music.stop()  # 停止播放
                break


def speak(content):
  result  = client.synthesis(content, 'zh', 3, {
    'vol': 5,
})
# 识别正确返回语音二进制 错误则返回dict 参照下面错误码
  if not isinstance(result, dict):
    with open('auido.mp3', 'wb') as f:
        f.write(result)
        f.close()
        playMusic('auido.mp3')




【2020年3月19日修正】
因获取数据的网站进行了数据显示调整,致使以上代码不能再实时播报。现将代码更正如下:
[AppleScript] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
import urllib2
from aip import AipSpeech
import pygame  # pip install pygame
import time
from datetime import datetime
import requests
import json
"""
你的 APPID AK SK 
均可在服务控制台中的应用列表中查看。
"""
APP_ID = '14778722'
API_KEY = 'BFoXqkmh5ow7iyYt7A8EWMDo'
SECRET_KEY = 'ZfETPvdqpABOgwlTwQRrohFdZRcT4U6N'
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)

def playMusic(filename, loops=0, start=0.0, value=1):
    """
    :param filename: 文件名
    :param loops: 循环次数
    :param start: 从多少秒开始播放
    :param value: 设置播放的音量,音量value的范围为0.0到1.0
    :return:
    """
    flag = False  # 是否播放过
    pygame.mixer.init()  # 音乐模块初始化
    while 1:
        if flag == 0:
            pygame.mixer.music.load(filename)
            # pygame.mixer.music.play(loops=0, start=0.0) loops和start分别代表重复的次数和开始播放的位置。
            pygame.mixer.music.play(loops=loops, start=start)
            pygame.mixer.music.set_volume(value)  # 来设置播放的音量,音量value的范围为0.0到1.0。
        if pygame.mixer.music.get_busy() == True:
            flag = True
        else:
            if flag:
                pygame.mixer.music.stop()  # 停止播放
                break
 

def speak(content):
  result  = client.synthesis(content, 'zh', 3, {
    'vol': 5,
})
# 识别正确返回语音二进制 错误则返回dict 参照下面错误码
  if not isinstance(result, dict):
    with open('auido.mp3', 'wb') as f:
        f.write(result)
        f.close()
        playMusic('auido.mp3')
def get_data():
    url = 'https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback=jQuery341001657575837432268_1581070969707&_=1581070969708'
    headers = {'user-agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Mobile Safari/537.36'}
    res = requests.get(url, headers=headers).text
    a = res.split('jQuery341001657575837432268_1581070969707(')[1].split(')')[0]
    c = json.loads(a)
    data = json.loads(c['data'])
    return data

def print_data_china():
    data = get_data()
    speak('最新疫情实时数据报告'.decode('utf-8'))
    speak('统计截至时间:'.decode('utf-8')+str(data['lastUpdateTime']))
    speak('全国确诊人数:'.decode('utf-8')+str(data['chinaTotal']['confirm']))
    if int(data['chinaAdd']['confirm'])<0:
        speak('相较于昨天确诊人数:减少'.decode('utf-8')+str(abs(int(data['chinaAdd']['confirm']))))
    else:
        speak('相较于昨天确诊人数:增加'.decode('utf-8')+str(data['chinaAdd']['confirm']))
    speak('全国疑似病例:'.decode('utf-8')+str(data['chinaTotal']['suspect']))
    if int(data['chinaAdd']['suspect'])<0:
        speak('相较于昨天疑似人数:减少'.decode('utf-8')+str(abs(int(data['chinaAdd']['suspect']))))
    else:
        speak('相较于昨天疑似人数:增加'.decode('utf-8')+str(data['chinaAdd']['suspect']))
    speak('全国治愈人数:'.decode('utf-8')+str(data['chinaTotal']['heal']))
    if int(data['chinaAdd']['heal'])<0:
        speak('相较于昨天治愈人数:减少'.decode('utf-8')+str(abs(int(data['chinaAdd']['heal']))))
    else:
        speak('相较于昨天治愈人数:增加'.decode('utf-8')+str(data['chinaAdd']['heal']))
    
    speak('全国死亡人数:'.decode('utf-8')+str(data['chinaTotal']['dead']))
    if int(data['chinaAdd']['dead'])<0:
        speak('相较于昨天死亡人数:减少'.decode('utf-8')+str(abs(int(data['chinaAdd']['dead']))))
    else:
        speak('相较于昨天死亡人数:增加'.decode('utf-8')+str(data['chinaAdd']['dead']))
def print_data_path_china():
    data = get_data()['areaTree'][0]['children']
    path_data = []
    path_china = []
   

    for i in data:

        name=i['name']
        today = i['today']
        total = i['total']
        shiji="湖北".decode('utf-8')
        if name==shiji:
            huibei='累计确诊人数'.decode('utf-8')+str(total['confirm'])+',相较于昨日确诊人数'.decode('utf-8')+str(today['confirm'])+',累计疑似病例'.decode('utf-8')+str(total['suspect'])+',累计治愈人数'.decode('utf-8')+str(total['heal'])+',累计死亡人数'.decode('utf-8')+str(total['dead'])
        shiji="上海".decode('utf-8')
        if name==shiji:
            shanghai='累计确诊人数'.decode('utf-8')+str(total['confirm'])+',相较于昨日确诊人数'.decode('utf-8')+str(today['confirm'])+',累计疑似病例'.decode('utf-8')+str(total['suspect'])+',累计治愈人数'.decode('utf-8')+str(total['heal'])+',累计死亡人数'.decode('utf-8')+str(total['dead'])
        path_china.append(i['name'])
        path_data.append(i['children'])
    path = '湖北'.decode('utf-8')
    if path in path_china:
        num = path_china.index(path)
        data_path = path_data[num]
        #print('{:^10}{:^10}{:^10}{:^10}{:^10}{:^10}{:^10}{:^10}{:^10}'.format('地区','累计确诊人数','相较于昨日确诊人数','累计疑似病例','相较于昨日疑似病例','累计治愈人数','相较于昨日治愈人数','累计死亡人数','相较于昨日死亡人数'))
        for i in data_path:
            name = i['name']
            today = i['today']
            total = i['total']
            #a = '{:^10}{:^15}{:^15}{:^15}{:^15}{:^15}{:^15}'
            #print(a.format(name, str(total['confirm']), str(today['confirm']), str(total['confirm']), str(total['suspect']), str(total['heal']),  str(total['dead'])))
            #print(name)
            shiji="武汉".decode('utf-8')
            if name==shiji:
                wuhan='累计确诊人数'.decode('utf-8')+str(total['confirm'])+',相较于昨日确诊人数'.decode('utf-8')+str(today['confirm'])+',累计疑似病例'.decode('utf-8')+str(total['suspect'])+',累计治愈人数'.decode('utf-8')+str(total['heal'])+',累计死亡人数'.decode('utf-8')+str(total['dead'])
    speak('湖北'.decode('utf-8'))
    speak(huibei)
    speak("武汉".decode('utf-8'))
    speak(wuhan)
    speak("上海".decode('utf-8'))
    speak(shanghai)        
def timer(n):
 while True:
  a = int(time.time())    #当前时间
  c = datetime.fromtimestamp(a+86400).strftime('%H:%M')    #格式转换
  '''#定时在早8点,为演示需要每1分钟播报一次
  if c>'08:05':
   l=0
  if c=='08:00' and l==0:
   l=1'''
  if 1:#
   print_data_china()
   print_data_path_china()
   time.sleep(n)
time.sleep(60)  
timer(60)   

Shuuei  中级技师 来自手机

发表于 2020-2-5 22:51:33

云天 发表于 2020-2-5 21:32
【演示视频】

(为视频效果,使用循环播报方式)

nice!我也想加入语音播报!
回复

使用道具 举报

DFrJ5KYVQaH  初级技匠

发表于 2020-2-6 09:52:38

不错的实例
回复

使用道具 举报

RRoy  高级技师

发表于 2020-2-11 13:52:31

很棒!在周星星项目的基础上改进了哈哈
回复

使用道具 举报

gray6666  高级技匠 来自手机

发表于 2020-2-12 12:07:32

云天 发表于 2020-2-5 21:32
【演示视频】

(为视频效果,使用循环播报方式)

经典案例,学习了
回复

使用道具 举报

且歌且行  中级技师

发表于 2020-2-15 20:22:33

树莓派还能这么玩~
回复

使用道具 举报

kylinpoet  中级技匠

发表于 2020-2-18 03:22:27

楼主强大,多谢分享。
回复

使用道具 举报

gada888  版主

发表于 2020-2-21 16:52:10

好分享
回复

使用道具 举报

盛祺科技  学徒

发表于 2020-3-26 14:17:11

能实现跟随网站数据的更新,实时播放吗? 类似支付宝商家收款的那个语音,商家收到一笔款,就能实时播报出来。呵呵
回复

使用道具 举报

DFBkZn8KTI8  学徒

发表于 2020-3-29 13:53:10

为什么我报错了
只播报了第一句话,到第二句话的时候就报错
202003292318..png
回复

使用道具 举报

DFBkZn8KTI8  学徒

发表于 2020-3-29 14:11:18


我感觉是pygame仍然占用mp3文件,导致无法修改
回复

使用道具 举报

云天  初级技匠
 楼主|

发表于 2020-3-30 10:44:57

修改后,我的一直没有问题,是不是因为网络问题,产生的。
回复

使用道具 举报

DFBkZn8KTI8  学徒

发表于 2020-4-1 14:01:07

我的问题已经解决了
此外,我想问一个问题。
https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&callback=jQuery341001657575837432268_1581070969707&_=1581070969708
以上这个URL是怎么获取?
回复

使用道具 举报

云天  初级技匠
 楼主|

发表于 2020-4-1 15:18:54

DFBkZn8KTI8 发表于 2020-4-1 14:01
我的问题已经解决了
此外,我想问一个问题。
https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5&ca ...

从网上参考的,直接拿来用。
回复

使用道具 举报

高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2020 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail