見出し画像

Spotifyの再生が止まらないようにする


概要

我が家ではSpotifyで24時間BGMを流しているのですが、気が付くと止まっていることがよくあります。平均すると1日に1回程度でしょうか。そのたびに手動でSpotifyアプリの再生ボタンを押しているのですが、これが面倒&小さなストレス。

なんとかしようと思い、止まらないようにするソフトを作ってみました。仕組み的にはSpotifyの状態を常時監視し、止まっていたら再生開始をするソフトです。

サーバーのように常時動作する必要があるため、PCと比べ使用電力の少ないラズパイを使用することにしました。ちょうどCO2センサーとして稼働しているラズパイ3A+があったので、そこに便乗することにします。(記事の時はラズパイ3Bでしたが、現在は3A+に乗せ換えています)

動作環境

  • Raspberry Pi 3A+ (ネットワーク付きのラズパイならなんでもOK)

  • Raspberry Pi OS

  • Python 3.9(必須)

  • Spotify-Cli 

Python は 3.10 以上では動作しません(正確にはこのソフトから利用している Spotify-Cli が動作しない)ので必ず 3.9 を使いましょう。

Spotify-Cli は Spotify をコマンドラインから操作するツールです。以前に記事にしていますので、インストールはそちらを参照してください。

インストール

以下のコードを spo_nonstop.py というファイル名で適当なディレクトリに保存します。

import os
import sys
import datetime
import subprocess
import json
import logging

# グローバル変数 設定
LOG_LEVEL = os.environ.get("LOG_LEVEL", "WARNING")
SPOTIFY = "/home/ryo/.local/bin/spotify"
LAST_LOG = os.path.join(os.path.dirname(__file__), "last_status.json")
LOG = os.path.join(os.path.dirname(__file__), "run.log")

# Logger設定
logger = logging.getLogger(__name__)
formatter = "[%(levelname)-8s] %(asctime)s %(funcName)s %(message)s"
logging.basicConfig(format=formatter, filename=LOG)
logger.setLevel(LOG_LEVEL)
logger.debug(f'{LOG_LEVEL=}')

#
# Spotifyの再生が停止していたら再生する
#
def play_spotify():

    # Spotifyの再生情報を取得
    try:
        r = subprocess.run(SPOTIFY + " status --raw", capture_output=True, shell=True)
        logger.debug(f'subprocess.run {r}')
        r_stdout = r.stdout.decode()
        j = json.loads(r_stdout)
    except:
        logger.error(f'subprocess.run {r}')

    # 取得情報をjsonファイルへ書き込み
    logger.debug(f'{LAST_LOG=}')
    json.dump(j, open(LAST_LOG, "w"))

    # 再生中でないなら再生する
    isplay = j.get("is_playing")
    logger.info(f'{isplay=}')

    if not isplay:
        r = subprocess.run(SPOTIFY + " play", capture_output=True, shell=True)
        logger.warning(r.stdout.decode())
    else:
        logger.info(j["item"]["name"])

#
# Main
#
def main():

    # 引数なし 通常処理
    if len(sys.argv) == 1:
        play_spotify()
        sys.exit()

    # 引数=check {sec} 死活監視用の処理
    if len(sys.argv) >=2 and sys.argv[1] == "check":
        error_ts = int(sys.argv[2]) # エラーとする閾値(秒)
        d = json.load(open(LAST_LOG))
        timestamp = datetime.datetime.fromtimestamp(os.path.getmtime(LAST_LOG)) # 情報ファイルの更新時間 (エポック秒をdatetime型に変換)
        tdl = datetime.datetime.now() - timestamp # 現在時刻との差(秒)
        if tdl.seconds > error_ts:
            print("ERROR")
        else:
            print("OK")
        print(f'{timestamp:%Y-%m-%d %H:%M}\n{tdl.seconds}')
        print(f'{d["item"]["name"]}/{d["item"]["artists"][0]["name"]}')

#
if __name__ == "__main__":
    main()

使用方法

動作チェック。そのまま実行し同じディレクトリに last_status.json が作成されていれば OK です。このファイルには現在再生中の曲情報が JSON 形式で保存されています。

$ python spo_nonstop.py

 実際の運用は cron で定期的に実行するようにします。crontab -e で以下の設定を書き込みます。

*/5 * * * * cd {ディレクトリ}; LOG_LEVEL=WARNING python spo_nonstop.py

5分間隔で実行するようにしていますが、これ以上間隔を詰めると、Spotify のサーバーから弾かれエラーになってしまうので注意。

run.log というログが作成されますので、これをチェックすることで実際に止まっていた日時などが分かります。

あとがき

このシステムを稼働してから一ヵ月弱経過しますが、再生が止まることはなくなりとても快適です。

ただし仕組み上、逆に再生を停止することができません・・・
停止したい場合は、cron 設定をコメントアウトしてから停止するという手間が必要です。個人的には停止することはないので、問題はないのですが。

この記事が気に入ったらサポートをしてみませんか?