0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Spotifyでいいねした曲をYoutube Musicでいいねするヤツ

Posted at

概要

内容はタイトルママ
SpotifyAPIとYouTubeMusicAPI使う
YouTubeMusicAPIは非公式なので一応注意

spotifyAPIに関しては資料が多いので省略

この記事がわかりやすいのでおすすめ
YouTubeMusicAPIは資料少ないので下の方で解説する

環境

  • Python 3.9.7
  • ytmusicapi==1.1.1
  • spotipy==2.23.0

処理の流れ

spotifyAPIでいいねした曲を取得したあと、YouTubeMusicAPIで検索して曲名とidを抽出
jsonにspotifyの曲名、ytmusicの検索曲名、ytmusicの検索曲idを保存
json内容を確認してもらい(検索結果が間違ってる可能性があるので)、問題なかったらjsonを元にいいねする関数を起動して終わり

処理順

  1. spotifyAPI(spotipy)でいいねした曲の、曲名&アーティスト名を取得する
  2. 取得した曲名&アーティスト名をYouTubeMusicAPI(ytmusicapi)で検索
  3. 検索結果から曲名とidを抽出し、spotifyでいいねした曲名と一緒にjsonで保存
  4. json内容に問題なかったら、ytmusicで"いいね"する関数を起動して終わり

コード

main.py
import os
import json
import spotipy
from spotipy.oauth2 import SpotifyOAuth
import ytmusicapi


class Spotify2YTMusic():
    def __init__(self):
        # Spotify APIの設定
        SPOTIFY_CLIENT_ID = 'your client id'
        SPOTIFY_CLIENT_SECRET = 'your client secret'
        SPOTIFY_REDIRECT_URI = 'your redirect uri'
        self.sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=SPOTIFY_CLIENT_ID,
                                                            client_secret=SPOTIFY_CLIENT_SECRET,
                                                            redirect_uri=SPOTIFY_REDIRECT_URI,
                                                            scope='user-library-read'))
        # YTMusicの設定
        # browser.jsonファイルが存在しなかったら作成
        if not os.path.exists('browser.json'):
            ytmusicapi.setup_oauth(filepath="browser.json")
        
        # 作成したbrowser.jsonファイルで設定
        self.ytmusic = ytmusicapi.YTMusic("browser.json")

        # combined_data.jsonファイルが存在するかチェック
        if os.path.exists('combined_data.json'):
            # combined_data.jsonファイルが存在する場合はデータをロードする
            with open('combined_data.json', 'r', encoding='utf-8') as f:
                self.combined_data = json.load(f)
        else:
            # combined_data.jsonファイルが存在しない場合は空のリストを作成する
            self.combined_data = []

    # Spotifyでいいねした曲を取得する関数
    def _get_liked_tracks(self):
        liked_tracks = []
        offset = 0
        limit = 50  # 取得する曲の数(50曲ごとにAPIリクエストを送信)
        while True:
            results = self.sp.current_user_saved_tracks(limit=limit, offset=offset)
            for item in results['items']:
                track = item['track']
                liked_tracks.append({
                    'name': track['name'],
                    'artist': track['artists'][0]['name']
                })
                
            # 次のページがある場合はオフセットを更新してループを続ける
            if results['next']:
                offset += limit
            else:
                break
        return liked_tracks

    # ytmusicの検索結果を取得する関数
    def _search_youtube_music(self,query):
        search_results = self.ytmusic.search(query)

        for result in search_results:
            if result['resultType'] != 'song':
                continue
            print(result['title'])
            print(result['resultType'])
            music = {
                        'title': result['title'],
                        'id': result['videoId']
                    }
            print(music)
            return music

    # ytmusicの検索結果をjsonにして出力
    def printJSON(self):
        liked_tracks = self._get_liked_tracks()
        combined_data = []
        for track in liked_tracks:
            yt_top_result = self._search_youtube_music(track['name'] + ' ' + track['artist'])
            combined_data.append({
                'spotify_track': track,
                'youtube_music_track': yt_top_result['title'],
                'youtube_music_id': yt_top_result['id']
            })
        
        # 結果をJSON形式で出力
        with open('combined_data.json', 'w', encoding='utf-8') as f:
            json.dump(combined_data, f, ensure_ascii=False, indent=2)

    # combined_dataのデータを元にytmusicで"いいね"する
    def likeYTMusicSongs(self):
        # combined_dataからidだけ取得
        # いいねした順が逆になってしまうのでreversed()で戻す
        youtube_music_ids = [item["youtube_music_id"] for item in reversed(self.combined_data)]
        for id in youtube_music_ids:
            self.ytmusic.rate_song(videoId=id, rating = 'LIKE')
            print(f"liked {id}")

__init__()

やってること

  1. spotifyapiの認証
  2. ytmusicapiの認証
  3. combined_data変数にcombined_data.jsonをロード
def __init__(self):
        # Spotify APIの設定
        SPOTIFY_CLIENT_ID = 'your client id'
        SPOTIFY_CLIENT_SECRET = 'your client secret'
        SPOTIFY_REDIRECT_URI = 'your redirect uri'
        self.sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=SPOTIFY_CLIENT_ID,
                                                            client_secret=SPOTIFY_CLIENT_SECRET,
                                                            redirect_uri=SPOTIFY_REDIRECT_URI,
                                                            scope='user-library-read'))
        # YTMusicの設定
        # browser.jsonファイルが存在しなかったら作成
        if not os.path.exists('browser.json'):
            ytmusicapi.setup_oauth(filepath="browser.json")
        
        # 作成したbrowser.jsonファイルで設定
        self.ytmusic = ytmusicapi.YTMusic("browser.json")

        # combined_data.jsonファイルが存在するかチェック
        if os.path.exists('combined_data.json'):
            # combined_data.jsonファイルが存在する場合はデータをロードする
            with open('combined_data.json', 'r', encoding='utf-8') as f:
                self.combined_data = json.load(f)
        else:
            # combined_data.jsonファイルが存在しない場合は空のリストを作成する
            self.combined_data = []

spotifyAPIについては省略
SPOTIFY_CLIENT_ID,SPOTIFY_CLIENT_SECRET,SPOTIFY_REDIRECT_URIは自分で発行したやつに変えてください

ytmusicapiの認証はbrower.jsonを使うので、brower.jsonが無い初回は

# YTMusicの設定
# browser.jsonファイルが存在しなかったら作成
if not os.path.exists('browser.json'):
    ytmusicapi.setup_oauth(filepath="browser.json")

でbrower.jsonを作る

# 作成したbrowser.jsonファイルで設定
self.ytmusic = ytmusicapi.YTMusic("browser.json")

作ったbrowser.jsonを読み込んでytmusicapiの設定終了

 # combined_data.jsonファイルが存在するかチェック
if os.path.exists('combined_data.json'):
    # combined_data.jsonファイルが存在する場合はデータをロードする
    with open('combined_data.json', 'r', encoding='utf-8') as f:
        self.combined_data = json.load(f)
else:
    # combined_data.jsonファイルが存在しない場合は空のリストを作成する
    self.combined_data = []

ytmusicapiで検索した結果と元の曲名を保存するcombined_data.jsonのロード

printJSON()

やってること

  1. _get_liked_tracks()でspotifyでいいねした曲を取得
  2. _search_youtube_music()でytmusicの検索結果を取得
  3. combined_data.jsonにspotifyの曲名、ytmusicの曲名、ytmusicのidを書き込む
# ytmusicの検索結果をjsonにして出力
def printJSON(self):
    liked_tracks = self._get_liked_tracks()
    combined_data = []
    for track in liked_tracks:
        yt_top_result = self._search_youtube_music(track['name'] + ' ' + track['artist'])
        combined_data.append({
            'spotify_track': track,
            'youtube_music_track': yt_top_result['title'],
            'youtube_music_id': yt_top_result['id']
        })
    
    # 結果をJSON形式で出力
    with open('combined_data.json', 'w', encoding='utf-8') as f:
        json.dump(combined_data, f, ensure_ascii=False, indent=2)

likeYTMusicSongs()

やってること

  1. initでロードしたcombined_dataからytmusicのidを抽出(いいね順もコピーするためにreversed()で反転しておく)
  2. ytmusic.rate_song(videoId=id, rating = 'LIKE')でytmusicで"いいね"する
# combined_dataのデータを元にytmusicで"いいね"する
def likeYTMusicSongs(self):
    # combined_dataからidだけ取得
    # いいねした順が逆になってしまうのでreversed()で戻す
    youtube_music_ids = [item["youtube_music_id"] for item in reversed(self.combined_data)]
    for id in youtube_music_ids:
        self.ytmusic.rate_song(videoId=id, rating = 'LIKE')
        print(f"liked {id}")

使い方

spotify2YTMusic = Spotify2YTMusic()
spotify2YTMusic.printJSON()

printJSON()を実行するとcombined_data.jsonが出力されるので、検索結果に間違いがなかったら、

spotify2YTMusic.likeYTMusicSongs()

でいいね実行して終わり

感想

spotifyからytmusicに移行するとき、700曲あるspotifyのいいねも移行するのがめんどくさいと思ったのが作るきっかけ
そういうサービスはすでにあるっぽいけど、自分の場合だとエラー起きたし簡単に作れそうだから作った

今回はytmusicapiがあったから簡単に作れたけど、全部自力でやったらかなりめんどくさそうだなと感じた
ytmusicapi様々

音楽系サブスクはアーティストのフォローもレコメンドに関わってくるので(多分)、アーティストのフォローを移行する機能もついでに作ったら良かったかも

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?