それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

automator で Radiko をバックグラウンド再生する

Radikoでいちいちブラウザ開くのも面倒

Radikoでブラウザ開くのは面倒ですね。まぁRadikoは広告費運営されてるから、サイト非表示で再生するのはRadikoそのものもを圧迫するかもしれないんだけど。iphoneとかで再生するのも面倒だしね。

ターミナルで再生するのも面倒だしね。。

ターミナルを普段使わないなら、ターミナルでコマンド叩いて再生するのもいんだけど、ターミナルをメインで使ってる時は、Radikoをうっかり閉じちゃうとか、プログラム切り替えで出てくるので面倒だしね。。

Automatorでコマンド実行することにした。

Automatorで、アプリ作成して、次のように設定した。

automator

  • ダイアログボックスでチャンル選んで
  • コマンドに引数渡し
  • コマンドを実行する

出来上がったapp がこれ

app

これを実行すると

引数入力

引数を入れて、OK

再生中は右上に出てくる。再生停止も

右上

再生中は、右上に実行中アイコンが出てくる。ここで閉じるボタンを押すと、再生が停止できる。

チャンネル変更は出来ないw。まぁ阪神戦の中継を流しっぱなしにするぐらいが一番用と大きいのでコレでいいかな。

radikoの再生プログラムはこれ。

#!/usr/bin/env python
# coding: utf-8
import pprint
pp = pprint.PrettyPrinter(indent=4)
pprint = pp.pprint
import os
import datetime
import sys
import urllib
import urllib2
import subprocess
import base64
LANG = "ja_JP.utf8"
pid = os.getpid()
date = datetime.datetime.strftime(datetime.datetime.now(),'%Y-%m-%d-%H_%M')
playerurl="http://radiko.jp/player/swf/player_3.0.0.01.swf"
playerfile="/tmp/player.%s.swf" % date
keyfile="/tmp/authkey.%s.png" % date
outdir="."
if len(sys.argv) < 2 :
print "Usage :"
print " %s channel_name duration(minuites) [outputdir] [prefix]" % sys.argv[0]
exit()
channel = sys.argv[1].upper()
DURATION = 60*60*3 # 3 時間
if len(sys.argv) > 2 :
DURATION = int(sys.argv[2]) * 60
if len(sys.argv) > 3 :
outdir=sys.argv[3]
PREFIX=channel
if len(sys.argv) > 4 :
PREFIX=sys.argv[4]
#
# get player
#
if os.path.exists( playerfile ) == False :
try :
body = urllib2.urlopen( playerurl ).read()
f = open( playerfile, "w" )
f.write(body)
f.close()
except URLError, e:
print e
exit()
#
# get keydata (need swftool)
#
if os.path.exists( keyfile ) == False :
cmd = "/usr/local/bin/swfextract -b 14 %s -o %s" % (playerfile, keyfile )
subprocess.call( cmd.strip().split(" ") )
if os.path.exists( keyfile ) == False :
print "failed get keydata"
exit(1)
# if [ -f auth1_fms_${pid} ]; then
# rm -f auth1_fms_${pid}
# fi
if os.path.exists( "auth1_fms_%s"%pid ) :
os.remove("auth1_fms_%s"%pid)
#
# access auth1_fms
#
auth_response = {}
url = "https://radiko.jp/v2/api/auth1_fms"
headers = {
"pragma":"no-cache",
"X-Radiko-App":"pc_1",
"X-Radiko-App-Version":"2.0.1",
"X-Radiko-User":"test-stream",
"X-Radiko-Device":"pc"
}
values = { "\r\n": "" }
data = urllib.urlencode(values)
try :
req = urllib2.Request(url, "\r\n" ,headers )
res = urllib2.urlopen(req)
auth_response["body"] = res.read()
auth_response["headers"] = res.info().dict
#f = open( "auth1_fms_%s"%pid , "w" )
#f.write(body)
except :
print "failed auth1 process"
exit()
#
# get partial key
#
authtoken = auth_response["headers"]["x-radiko-authtoken"]
offset = auth_response["headers"]["x-radiko-keyoffset"]
length = auth_response["headers"]["x-radiko-keylength"]
offset = int(offset)
length = int(length)
f = open(keyfile, 'rb+')
f.seek(offset)
data = f.read(length)
partialkey = base64.b64encode(data)
print "authtoken: %s \noffset: %s length: %s \npartialkey: %s" % (authtoken,offset,length,partialkey)
#partialkey=`dd if=$keyfile bs=1 skip=${offset} count=${length} 2> /dev/null | base64`
#
# access auth2_fms
#
auth_success_response ={}
url = "https://radiko.jp/v2/api/auth2_fms"
headers ={
"pragma":"no-cache",
"X-Radiko-App":"pc_1",
"X-Radiko-App-Version":"2.0.1",
"X-Radiko-User":"test-stream",
"X-Radiko-Device":"pc",
"X-Radiko-Authtoken":authtoken,
"X-Radiko-Partialkey":partialkey ,
}
try :
req = urllib2.Request(url, "\r\n" ,headers )
res = urllib2.urlopen(req)
#print res.read()
auth_success_response["body"] = res.read()
auth_success_response["headers"] = res.info().dict
except URLError, e:
print e
exit()
print "--------------------------"
print "authentication success"
area = auth_success_response["body"].strip().split(",")
areaid = area[0]
print "--------------------------"
print "areaid :%s" % areaid
print "channel program list url http://radiko.jp/v2/api/program/today?area_id=%s" % areaid
print "--------------------------"
print "list of channels "
channels = subprocess.check_output( "curl -s http://radiko.jp/v2/api/program/today?area_id=%s " % areaid+
"| xmllint --format --xpath //station/@id - "+
" | ruby -ne 'puts $_.split ' " ,
shell=True)
print channels
print "--------------------------"
print " your choice : %s " % channel
if not channel in channels :
print "station %s is not available. " % channel
exit(1)
#
# get stream-url
#
if os.path.exists( "%s.xml" % channel ) :
os.remove("%s.xml" % channel)
try :
channel_url = "http://radiko.jp/v2/station/stream/%s.xml" % channel
body = urllib2.urlopen( channel_url ).read()
f = open("%s.xml" % channel, "w")
f.write( body )
f.close()
except :
print "error in to get %s.xml " % channel
cmd = "xmllint %s.xml --xpath /url/item[1]/text() " % channel
stream_url = subprocess.check_output(cmd.strip().split(" "))
print stream_url
cmd = "echo '%s' | perl -pe 's!^(.*)://(.*?)/(.*)/(.*?)$/!$1://$2 $3 $4!'" % stream_url
print cmd
ret = subprocess.check_output(cmd, shell=True)
url_parts = ret.split(" ")
os.remove("%s.xml" % channel)
play_cmd = '/usr/local/bin/rtmpdump -v \
-r %s \
--app %s\
--playpath %s \
-W %s \
-C S:"" -C S:"" -C S:"" -C S:%s \
--live \
--stop %s ' % (url_parts[0],url_parts[1],url_parts[2], playerurl,authtoken,DURATION)
print play_cmd
print " " * 10
print "\n"
p1 = subprocess.Popen(play_cmd.strip().split(" "), stdout=subprocess.PIPE)
p2 = subprocess.Popen(["/usr/local/bin/mplayer", "-"], stdin=p1.stdout)
p1.stdout.close()
output = p2.communicate()[0]

play_radiko_by_mplayer.py

関連記事

Radikoの再生&録音スクリプトをPythonで書きなおした - それマグで!