昔我往矣

使用树莓派播放bbc新闻

2016年11月23日

家里有个树莓派,而且又是个起床困难户。总想改善下起床效率,于是用树莓派做了自动报时,自动放网易云音乐的起床歌单,但是还是起不来(悲伤)。

bbc_news_logo.png

突发奇想每天早上播放英文广播,BBC,VOA什么的都可以。最后发现有人做了基于BBC的播放器,比较粗陋,稍微看了下源码,了解流程之后,自己写了个简单的。

实现过程

第一步、下载BBC4的播放列表(http://www.radiofeeds.co.uk/bbcradio4fm.pls
第二步、从播放列表中解析音频流URL
第三步、使用mpc播放URL。

如果你没有安装mpc,使用vlc播放器也是可以的,但是使用vlc需要自己实现start,stop方法,而mpc我一直在树莓派上用,而且手机端控制也很容易。

原理分析

原始的播放列表文件bbcradio4fm.pls如下:

[playlist]
File1=http://bbcmedia.ic.llnwd.net/stream/bbcmedia_radio4fm_mf_p?s=1479905001&e=1479919401&h=bd3a5626588fdd75eac6ca2d02cfc689
Title1=BBC Radio 4 (DAB)
Length1=-1
Numberofentries=1
Version=2

File1这行就是我们需要的音频流路径。把这个url放入mpc播放列表就可以了。

第一版代码

从上面看一切都很简单,事实也是如此,代码如下:

import requests
import subprocess


radio_list = "http://www.radiofeeds.co.uk/bbcradio4fm.pls"
pls_content = requests.get(radio_list).content
mpc_exec = "/usr/bin/mpc"

for line in pls_content.split():
    line_list = line.split("=")
    if "File1" == line_list[0]:
        line_list.remove("File1")
        radio_url = "=".join(line_list)

subprocess.check_output("{mpc_exec} -q clear && {mpc_exec} -q add {radio_url} && {mpc_exec} volume 80 && {mpc_exec} -q play".format(
    mpc_exec=mpc_exec, radio_url=radio_url), shell=True)

以上就是完整的播放BBC4实时广播的python脚本,我可以通过安卓手机上的mpc客户端控制他的播放。check_output函数中是mpc的命令。

将上面这个脚本放在crontab里,每天7点运行就可以了。

问题出现

在使用顺利运行两天之后,每天早上忽然没有声音了。于是登上树莓派去排查,发现在获取pls文件的时候,发生了超时。无法访问到http://www.radiofeeds.co.uk/bbcradio4fm.pls文件

于是考虑加上一个代理,正好我的树莓派上就有一个连上我在美国的vps。于是我改进了代码,为脚本加上代理。在requests文档中给定了设置代理的example,如下:

import requests

proxies = {
  "http": "socks5://user:pass@host:port",
  "https": "socks5://user:pass@host:port",
}

requests.get("http://example.org", proxies=proxies)

第二版代码

在第二版的代码中,我加入了socks5代理,如下:

import requests
import subprocess

proxies = {
    'http': 'socks5://pi.xnow.me:1082',
    'https': 'socks5://pi.xnow.me:1082'
}

radio_list = "http://www.radiofeeds.co.uk/bbcradio4fm.pls"

try:
    pls_content = requests.get(radio_list, timeout=5).content
except requests.exceptions.Timeout:
    pls_content = requests.get(radio_list, proxies=proxies).content

mpc_exec = "/usr/bin/mpc"

for line in pls_content.split():
    line_list = line.split("=")
    if "File1" == line_list[0]:
        line_list.remove("File1")
        radio_url = "=".join(line_list)

subprocess.check_output("{mpc_exec} -q clear && {mpc_exec} -q add {radio_url} && {mpc_exec} volume 80 && {mpc_exec} -q play".format(
    mpc_exec=mpc_exec, radio_url=radio_url), shell=True)

proxies 是我的代理地址:pi.xnow.me:1082,另外加入了异常检查,如果5s没有下载到播放列表,则使用代理再次请求下载播放列表。

最后的问题

在运行第二版代码的时候收到了另外的异常:

Missing dependencies for SOCKS support.

显然是requests不支持socks5代理,所以要升级requests。使用pip中,,默认官方源经常出现如下的报错:

ReadTimeoutError: HTTPSConnectionPool(host='pypi.python.org', port=443): Read timed out.

所以我们通过-i参数指定使用使用douban的pip源,基本秒装:

pi@raspberrypi:~ $  sudo pip install -U requests[socks] -i http://pypi.doubanio.com/simple

到此脚本完成了,暂时完美运行。不要问我每天有没有早起。

当前暂无评论 »

添加新评论 »