持续实时获取当前在 Spotify 上播放的歌曲
Posted
技术标签:
【中文标题】持续实时获取当前在 Spotify 上播放的歌曲【英文标题】:Continuously real-time fetching currently playing song on Spotify 【发布时间】:2019-05-15 20:57:53 【问题描述】:我编写了将 Spotify 用户当前正在播放的歌曲置于 vk.com 上的状态的脚本。现在就像一次性的事情。当您运行脚本时 - 它会设置正确的状态。但是要更新它,您显然需要再次运行该脚本。
我想知道是否有可能让它动态工作?当新歌开始时更新状态。我只能考虑设置运行脚本的时间表或发送请求以检查歌曲是否已更改。但我想它只有在用户的 PC 始终处于开启状态并且脚本已准备好运行时才会起作用。
另一个问题是 spotify 令牌持续一小时,但我读到了 the refresh token is practically valid forever, or until it has been manually revoked。 Vk 令牌具有使令牌永久有效的官方选项。
import config
import webbrowser
import requests
import furl
import secrets
import string
import time
import os
import simplejson as json
URL_CODE_BASE_VK = 'https://oauth.vk.com/authorize'
URL_CODE_BASE_SP = 'https://accounts.spotify.com/authorize'
URL_TOKEN_VK = 'https://oauth.vk.com/access_token'
URL_TOKEN_SP = 'https://accounts.spotify.com/api/token'
URL_TRACK = 'https://api.spotify.com/v1/me/player/currently-playing'
URL_STATUS = 'https://api.vk.com/method/status.set'
EXP_IN_TOKEN_SP = 3400
EXP_IN_TOKEN_VK = 86400
FILE_TOKEN_VK = 'vk_token.json'
FILE_TOKEN_SP = 'sp_token.json'
def get_auth_code_vk():
url_code_params =
'client_id': config.CLIENT_ID_VK,
'response_type': 'code',
'redirect_uri': 'https://oauth.vk.com/blank.html',
'v': 5.92,
'scope': 'status',
'state': gen_state(),
'display': 'page'
code = url_open(URL_CODE_BASE_VK, url_code_params)
return parse_code(code)
def get_auth_code_sp():
url_code_params =
'client_id': config.CLIENT_ID_SP,
'response_type': 'code',
'redirect_uri': 'https://www.spotify.com/',
'scope': 'user-read-currently-playing',
'state': gen_state()
code = url_open(URL_CODE_BASE_SP, url_code_params)
return parse_code(code)
def gen_state():
symbols = string.ascii_lowercase + string.digits
return ''.join(secrets.choice(symbols) for _ in range(12))
def url_open(url_base, url_params):
url_code_full = furl.furl(url_base).add(url_params).url
webbrowser.open_new_tab(url_code_full)
input_url = input('Enter the whole URL, that you have been redirected on: ')
return input_url
def parse_code(url):
return (url.split("code=")[1]).split("&state=")[0]
def get_token_vk():
data =
'grant_type': 'authorization_code',
'code': get_auth_code_vk(),
'redirect_uri': 'https://oauth.vk.com/blank.html',
'client_id': 6782333,
'client_secret': config.CLIENT_SECRET_VK
response = requests.post(url=URL_TOKEN_VK, data=data).json()
write_file(FILE_TOKEN_VK, response)
def get_token_sp():
data =
'grant_type': 'authorization_code',
'code': get_auth_code_sp(),
'redirect_uri': 'https://www.spotify.com/',
'client_id': config.CLIENT_ID_SP,
'client_secret': config.CLIENT_SECRET_SP
response = requests.post(url=URL_TOKEN_SP, data=data).json()
write_file(FILE_TOKEN_SP, response)
def write_file(tkn_file, response):
dict =
dict['token'] = response["access_token"]
dict['time'] = time.time()
with open(tkn_file, 'w') as file:
file.write(json.dumps(dict))
def load_file(tkn_file):
with open(tkn_file) as file:
data = json.load(file)
return data
def set_status():
params =
'v': 5.92,
'access_token': load_file(FILE_TOKEN_VK)['token'],
'text': current_track()
set_status = requests.get(url=URL_STATUS, params=params)
def track_data():
tkn_file = load_file(FILE_TOKEN_SP)['token']
headers =
'Accept': 'application/json',
'Authorization': f'Bearer tkn_file'
return requests.get(url=URL_TRACK, headers=headers)
def current_track():
data = track_data().json()
artist = data['item']['artists'][0]['name']
track = data['item']['name']
return(f'artist - track')
def check_playback():
try:
set_status()
print(current_track())
except json.decoder.JSONDecodeError:
print('Not playing')
def token_missing(file):
return not os.path.isfile(file)
def token_expired(file, exp_in):
return time.time() - load_file(file)['time'] > exp_in
def token_not_valid(file, exp_in):
return token_missing(file) or token_expired(file, exp_in)
def run_script():
if token_not_valid(FILE_TOKEN_VK, EXP_IN_TOKEN_VK):
get_token_vk()
if token_not_valid(FILE_TOKEN_SP, EXP_IN_TOKEN_SP):
get_token_sp()
check_playback()
if __name__ == "__main__":
run_script()
【问题讨论】:
【参考方案1】:是的,您可以使用cron
作业使进程以设定的时间间隔运行。此外,如果您将其构建到 flask
应用程序中,那么您可以使用 scheduler
以设定的时间间隔运行作业。可能cron
是最快的方法。
编辑 cronjobs:
$ crontab -e
然后添加类似:
* * * * * python /tmp/spotify_update.py
每秒运行一次作业。星号代表分钟、小时、天、月和工作日。
【讨论】:
感谢您的回答!我现在不使用 Linux 或操作系统。所以 cron 不适合我,但据我所知,Windows 中有一些类似的东西可用。无论如何,这不是我想要的。因为它需要一台 PC 一直处于开启状态。 Web 应用程序对我来说是一种方式,但我更喜欢 Django,可能 Django 有一些时间表。在 Django 或 Flask 中会更快吗?我的意思是把它构建成一个网络应用程序。如果你熟悉这两个。我还没有真正接触过 Flask。以上是关于持续实时获取当前在 Spotify 上播放的歌曲的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Spotify Web API 获取当前播放/最近播放的歌曲
使用 Spotipy 获取当前正在播放的歌曲会出现错误:“'Spotify' 对象没有属性 'currently_playing'”