-
-
Save je3kmz/1e53c81baafb820d9b18bf10be0840d2 to your computer and use it in GitHub Desktop.
簡易radiko録音ツール。要wget,ffmpeg,xmllint
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
pid=$$ | |
date=`env TZ=JST-09 date '+%Y-%m-%d-%H_%M'` | |
tmpdir=/tmp | |
####################################### | |
# Extract login JSON value | |
# Arguments: | |
# (pipe)Login result JSON | |
# Key | |
# Returns: | |
# None | |
####################################### | |
extract_login_value() { | |
name=$1 | |
# for gawk | |
#value=$(cat - | gawk -v "name=${name}" 'BEGIN { FS = "\n"; } { regex = "\""name"\"[ ]*:[ ]*(\"[0-9a-zA-Z]+\"|[0-9]*)"; if (!match($0, regex, v)) { exit 0; } val=v[1]; if (match(val, /\"([0-9a-zA-Z]*)\"/, v)) { val=v[1]; } print val; }') | |
value=$(cat - \ | |
| awk -v "name=${name}" ' | |
BEGIN { | |
FS = "\n"; | |
} | |
{ | |
# Extract key and value | |
regex = "\""name"\"[ ]*:[ ]*(\"[0-9a-zA-Z]+\"|[0-9]*)"; | |
if (!match($1, regex)) { | |
exit 0; | |
} | |
str = substr($0, RSTART, RLENGTH); | |
# Extract value | |
regex = "\""name"\"[ ]*:[ ]*"; | |
match(str, regex); | |
str = substr(str, RSTART + RLENGTH); | |
# String value | |
if (match(str, /^\"[0-9a-zA-Z]+\"/)) { | |
print substr(str, RSTART + 1, RLENGTH - 2); | |
exit 0; | |
} | |
# Numeric value | |
if (match(str, /^[0-9]*/)) { | |
print substr(str, RSTART, RLENGTH); | |
exit 0; | |
} | |
}') | |
echo "${value}" | |
return 0 | |
} | |
quit() | |
{ | |
echo authkey not found | |
logout | |
exit 1 | |
} | |
#_authkey=bcd151073c03b352e1ef2fd66c32209da9ca0afa | |
wget -q -O $tmpdir/playerCommon.js$pid https://radiko.jp/apps/js/playerCommon.js || quit | |
_authkey=`grep pc_html5 $tmpdir/playerCommon.js$pid | awk -F\' '{print$4}'` | |
unlink $tmpdir/playerCommon.js$pid | |
logout() | |
{ | |
wget --quiet -O /dev/null --post-data=radiko_session=${auth2_url_param} https://radiko.jp/v4/api/member/logout 2> /dev/null | |
} | |
channel=`echo $1 | tr '[[a-z]]' '[[A-Z]]'` | |
if [ $# -eq 1 ]; then | |
output=${channel}_${date}.aac | |
elif [ $# -eq 2 ]; then | |
output=$2 | |
elif [ $# -eq 3 ]; then | |
output=$2 | |
rectime="-t "$3 | |
elif [ $# -eq 4 ]; then | |
output=$2 | |
mail=$3 | |
pass=$4 | |
elif [ $# -eq 5 ]; then | |
output=$2 | |
mail=$3 | |
pass=$4 | |
rectime="-t "$5 | |
else | |
echo "usage : "`basename $0`" channel_name [outputfile] [mail] [pass] [recordingtime(sec)]" | |
exit 1 | |
fi | |
areafree=0 | |
if [ -n "$mail" ]; then | |
auth2_url_param="" | |
login=$(wget -O $tmpdir/login.$pid --server-response --post-data=mail=$mail\&pass=$pass https://radiko.jp/ap/member/webapi/member/login 2> /dev/stdout) | |
areafree=$(cat $tmpdir/login.$pid | extract_login_value "areafree") | |
radiko_session=$(cat $tmpdir/login.$pid | extract_login_value "radiko_session") | |
if [ -n "`echo $login | sed -n -e '/200 OK/p'`" ]; then | |
# ログイン確認 | |
if [ $areafree -eq 1 ]; then | |
auth2_url_param="?radiko_session=${radiko_session}" | |
fi | |
fi | |
rm -f $tmpdir/login.$pid | |
fi | |
# 認証 | |
AUTH1="$(wget -q -S -O /dev/null --header "X-Radiko-App: pc_html5" --header "X-Radiko-App-Version: 0.0.1" --header "X-Radiko-Device: pc" --header "X-Radiko-User: dummy_user" https://radiko.jp/v2/api/auth1 2> /dev/stdout)" | |
ret=$? | |
if test $ret -gt 0 | |
then | |
quit | |
fi | |
authtoken=$(echo "${AUTH1}" | awk 'tolower($0) ~/x-radiko-authtoken: / {print substr($0,23,length($0)-22)}') | |
offset=$(echo "${AUTH1}" | awk 'tolower($0) ~/x-radiko-keyoffset: / {print substr($0,23,length($0)-22)}') | |
length=$(echo "${AUTH1}" | awk 'tolower($0) ~/x-radiko-keylength: / {print substr($0,23,length($0)-22)}') | |
partialkey=`echo $_authkey | dd bs=1 skip=$offset count=$length 2> /dev/null | openssl base64` | |
wget --quiet --no-check-certificate --server-response\ | |
--header="X-Radiko-AuthToken: "$authtoken\ | |
--header="X-Radiko-PartialKey: "$partialkey\ | |
--header="X-Radiko-User: dummy_user"\ | |
--header="X-Radiko-Device: pc"\ | |
-O/dev/null\ | |
https://radiko.jp/v2/api/auth2${auth2_url_param} 2> /dev/null | |
urilist=$(wget -q -O - https://radiko.jp/v2/station/stream_smh_multi/${channel}.xml | xmllint --xpath "/urls/url[@areafree='${areafree}']/playlist_create_url/text()" -) | |
for x in `echo $urilist` | |
do | |
ffprobe -hide_banner -v error -headers 'X-Radiko-Authtoken: '${authtoken} ${x}?station_id=${channel} | |
ret=$? | |
if test 0 -eq $ret | |
then | |
URL=${x} | |
break | |
fi | |
done | |
#lsid=$(head -c 100 /dev/random | openssl base64 | tr -dc '0-9A-Fa-f' | tr '[:upper:]' '[:lower:]' | cut -c 1-32) | |
### live | |
ffmpeg -hide_banner -v error -headers 'X-Radiko-AuthToken: '${authtoken} \ | |
-i ${URL}\ | |
-metadata:s language=jpn \ | |
${rectime} -bsf:a aac_adtstoasc -acodec copy "${output}" | |
ret=$? | |
if test 1 -eq $ret | |
then | |
echo ffmpeg error | |
logout | |
exit 1 | |
fi | |
# ログアウト | |
logout | |
exit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
pid=$$ | |
date=`env TZ=JST-09 date '+%Y-%m-%d-%H_%M'` | |
tmpdir=/tmp | |
####################################### | |
# Extract login JSON value | |
# Arguments: | |
# (pipe)Login result JSON | |
# Key | |
# Returns: | |
# None | |
####################################### | |
extract_login_value() { | |
name=$1 | |
# for gawk | |
#value=$(cat - | gawk -v "name=${name}" 'BEGIN { FS = "\n"; } { regex = "\""name"\"[ ]*:[ ]*(\"[0-9a-zA-Z]+\"|[0-9]*)"; if (!match($0, regex, v)) { exit 0; } val=v[1]; if (match(val, /\"([0-9a-zA-Z]*)\"/, v)) { val=v[1]; } print val; }') | |
value=$(cat - \ | |
| awk -v "name=${name}" ' | |
BEGIN { | |
FS = "\n"; | |
} | |
{ | |
# Extract key and value | |
regex = "\""name"\"[ ]*:[ ]*(\"[0-9a-zA-Z]+\"|[0-9]*)"; | |
if (!match($1, regex)) { | |
exit 0; | |
} | |
str = substr($0, RSTART, RLENGTH); | |
# Extract value | |
regex = "\""name"\"[ ]*:[ ]*"; | |
match(str, regex); | |
str = substr(str, RSTART + RLENGTH); | |
# String value | |
if (match(str, /^\"[0-9a-zA-Z]+\"/)) { | |
print substr(str, RSTART + 1, RLENGTH - 2); | |
exit 0; | |
} | |
# Numeric value | |
if (match(str, /^[0-9]*/)) { | |
print substr(str, RSTART, RLENGTH); | |
exit 0; | |
} | |
}') | |
echo "${value}" | |
return 0 | |
} | |
quit() | |
{ | |
echo authkey not found | |
logout | |
exit 1 | |
} | |
#_authkey=bcd151073c03b352e1ef2fd66c32209da9ca0afa | |
wget -q -O $tmpdir/playerCommon.js$pid https://radiko.jp/apps/js/playerCommon.js || quit | |
_authkey=`grep pc_html5 $tmpdir/playerCommon.js$pid | awk -F\' '{print$4}'` | |
unlink $tmpdir/playerCommon.js$pid | |
logout() | |
{ | |
wget --quiet -O /dev/null --post-data=radiko_session=${auth2_url_param} https://radiko.jp/v4/api/member/logout 2> /dev/null | |
} | |
channel=`echo $1 | tr '[[a-z]]' '[[A-Z]]'` | |
if [ $# -eq 3 ]; then | |
output=${channel}_${2}-${3}.aac | |
start_time=$2 | |
end_time=$3 | |
elif [ $# -eq 4 ]; then | |
start_time=$2 | |
end_time=$3 | |
output=$4 | |
elif [ $# -eq 6 ]; then | |
start_time=$2 | |
end_time=$3 | |
output=$4 | |
mail=$5 | |
pass=$6 | |
else | |
echo "usage : "`basename $0`" channel_name starttime(YYYYMMDDHHMMSS) endingtime(YYYYMMDDHHMMSS) [outputfile] [mail] [pass]" | |
exit 1 | |
fi | |
areafree=0 | |
if [ -n "$mail" ]; then | |
auth2_url_param="" | |
login=$(wget -O $tmpdir/login.$pid --server-response --post-data=mail=$mail\&pass=$pass https://radiko.jp/ap/member/webapi/member/login 2> /dev/stdout) | |
areafree=$(cat $tmpdir/login.$pid | extract_login_value "areafree") | |
radiko_session=$(cat $tmpdir/login.$pid | extract_login_value "radiko_session") | |
if [ -n "`echo $login | sed -n -e '/200 OK/p'`" ]; then | |
# ログイン確認 | |
if [ $areafree -eq 1 ]; then | |
auth2_url_param="?radiko_session=${radiko_session}" | |
fi | |
fi | |
rm -f $tmpdir/login.$pid | |
fi | |
# 認証 | |
AUTH1="$(wget -q -S -O /dev/null --header "X-Radiko-App: pc_html5" --header "X-Radiko-App-Version: 0.0.1" --header "X-Radiko-Device: pc" --header "X-Radiko-User: dummy_user" https://radiko.jp/v2/api/auth1 2> /dev/stdout)" | |
ret=$? | |
if test $ret -gt 0 | |
then | |
quit | |
fi | |
authtoken=$(echo "${AUTH1}" | awk 'tolower($0) ~/x-radiko-authtoken: / {print substr($0,23,length($0)-22)}') | |
offset=$(echo "${AUTH1}" | awk 'tolower($0) ~/x-radiko-keyoffset: / {print substr($0,23,length($0)-22)}') | |
length=$(echo "${AUTH1}" | awk 'tolower($0) ~/x-radiko-keylength: / {print substr($0,23,length($0)-22)}') | |
partialkey=`echo $_authkey | dd bs=1 skip=$offset count=$length 2> /dev/null | openssl base64` | |
wget --quiet --no-check-certificate --server-response\ | |
--header="X-Radiko-AuthToken: "$authtoken\ | |
--header="X-Radiko-PartialKey: "$partialkey\ | |
--header="X-Radiko-User: dummy_user"\ | |
--header="X-Radiko-Device: pc"\ | |
-O/dev/null\ | |
https://radiko.jp/v2/api/auth2${auth2_url_param} 2> /dev/null | |
urilist=$(echo https://radiko.jp/v2/api/ts/playlist.m3u8 ; wget -q -O - https://radiko.jp/v2/station/stream_smh_multi/${channel}.xml | xmllint --xpath "/urls/url[@areafree='${areafree}']/playlist_create_url/text()" -) | |
for x in `echo $urilist` | |
do | |
ffprobe -hide_banner -v error -headers 'X-Radiko-Authtoken: '${authtoken} ${x}?station_id=${channel} | |
ret=$? | |
if test 0 -eq $ret | |
then | |
URL=${x} | |
break | |
fi | |
done | |
lsid=$(head -c 100 /dev/random | openssl base64 | tr -dc '0-9A-Fa-f' | tr '[:upper:]' '[:lower:]' | cut -c 1-32) | |
### timefree | |
ffmpeg -hide_banner -v error -headers 'X-Radiko-AuthToken: '${authtoken} \ | |
-i ${URL}?station_id=${channel}\&l=15\&ft=${start_time}\&to=${end_time}\&start_at=${start_time}\&end_at=${end_time}\&seek=${start_time}\&lsid=${lsid}\&type=c \ | |
-metadata:s language=jpn \ | |
-bsf:a aac_adtstoasc -acodec copy "${output}" | |
ret=$? | |
if test 1 -eq $ret | |
then | |
echo ffmpeg error | |
logout | |
exit 1 | |
fi | |
# ログアウト | |
logout | |
exit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment