Skip to content

Instantly share code, notes, and snippets.

@takuya
Last active April 17, 2020 12:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takuya/66897434dbd71b155de1 to your computer and use it in GitHub Desktop.
Save takuya/66897434dbd71b155de1 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# coding: utf-8
#/*
# * This program is free software: you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation, either version 3 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program. If not, see <http://www.gnu.org/licenses/>.
# */
import pprint
pp = pprint.PrettyPrinter(indent=4)
pprint = pp.pprint
import os
import datetime
import sys
import urllib
import urllib2
import subprocess
import base64
import ssl
#ssl._create_default_https_context = ssl._create_unverified_context
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"
playerurl="http://radiko.jp/player/swf/player_4.1.0.00.swf"
playerurl="http://radiko.jp/apps/js/flash/myplayer-release.swf "
playerfile="/tmp/player.%s.swf" % date
keyfile="/tmp/authkey.%s.png" % date
swfextract=subprocess.check_output("which swfextract", shell=True).strip()
rtmpdump=subprocess.check_output("which rtmpdump", shell=True).strip()
mplayer=subprocess.check_output("which mplayer", shell=True).strip()
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 = "%s -b 12 %s -o %s" % (swfextract, playerfile, keyfile )
subprocess.call( cmd.strip().split(" ") )
if os.path.exists( keyfile ) == False :
print "failed get keydata"
print "this command failed. "
print "%s" % cmd
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_ts",
"X-Radiko-App-Version":"4.0.0",
"X-Radiko-User":" test-stream",
"X-Radiko-Device":"pc"
}
values = { "\r\n": "" }
data = urllib.urlencode(values)
try :
req = urllib2.Request(url, data ,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_ts",
"X-Radiko-App-Version":"4.0.0",
"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 = '%s -v \
-r %s \
--app %s\
--playpath %s \
-W %s \
-C S:"" -C S:"" -C S:"" -C S:%s \
--live \
--stop %s ' % (rtmpdump, 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([mplayer, "-"], stdin=p1.stdout)
p1.stdout.close()
output = p2.communicate()[0]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment