Skip to content

Instantly share code, notes, and snippets.

@fuddl
Last active July 1, 2024 21:52
Show Gist options
  • Save fuddl/e17aa687df6ac1c7cbee5650ccfbc889 to your computer and use it in GitHub Desktop.
Save fuddl/e17aa687df6ac1c7cbee5650ccfbc889 to your computer and use it in GitHub Desktop.
YTMusic2listenbrainz.py

Submit Your YouTube Music Watch History to Listenbrainz

This script allows you to submit your YouTube Music watch history to Listenbrainz.

Prerequisites

  1. Python 3.x installed on your computer.
  2. An active Listenbrainz account.
  3. Your YouTube Music watch history file from Google Takeout.

Instructions

Step 1: Download Your YouTube Watch History

  • Visit Google Takeout.
  • From the list of data to include, deselect all except for YouTube and YouTube Music.
  • Within the YouTube and YouTube Music section, select only history and then watch history.
  • Click Next step and follow the prompts to download your watch history, which will be provided as a watch-history.json file.

Step 2: Prepare Your Environment

  1. Download YTMusic2listenbrainz.py script from this repository.
  2. Place your watch-history.json file in the same directory as the YTMusic2listenbrainz.py script.
  3. Enter your listenbrainz_token in YTMusic2listenbrainz.py.

Step 3: Run the Script

Open a terminal or command prompt and navigate to the directory containing the script and your watch history file. Run the script with the following command:

python3 YTMusic2listenbrainz.py

Step 4: Verify Your Submission

After running the script, log in to your Listenbrainz account to verify that your watch history has been submitted successfully.

import requests
import json
import re
from datetime import datetime
import time
# your token here
listenbrainz_token = '<enter yout token here>'
# the earliest timestamp you want to submit from.
min_timestamp = 963792000
def batch(iterable, n=1):
l = len(iterable)
for ndx in range(0, l, n):
yield iterable[ndx:min(ndx + n, l)]
with open ('watch-history.json', 'r') as file:
json_data = json.loads(file.read())
def submit_to_listenbrainz(data, token):
headers = {
'Authorization': f'Token {token}',
'Content-Type': 'application/json'
}
listenbrainz_url = 'https://api.listenbrainz.org/1/submit-listens'
listens = []
for entry in data:
listened_at = int(datetime.fromisoformat(entry['time']).timestamp())
if (listened_at < min_timestamp):
continue
if (entry["header"] == "YouTube"):
continue
if 'subtitles' not in entry:
continue
if entry['subtitles'][0]['name'] == ' - Topic':
continue
track_metadata = {
'artist_name': re.sub(r'\s-\sTopic$', '', entry['subtitles'][0]['name']),
'track_name': re.sub(r'^Watched\s', '', entry['title']),
'additional_info': {
'music_service': 'music.youtube.com',
'origin_url': entry['titleUrl'],
'submission_client': 'https://gist.github.com/fuddl/e17aa687df6ac1c7cbee5650ccfbc889',
}
}
listens.append({
'listened_at': listened_at,
'track_metadata': track_metadata
})
responses = []
for listen_batch in batch(listens, 1000):
payload = {
'listen_type': 'import',
'payload': listen_batch
}
response = requests.post(listenbrainz_url, headers=headers, data=json.dumps(payload))
time.sleep(int(response.headers['X-RateLimit-Reset-In']))
print(response)
responses.append(response)
return responses
response = submit_to_listenbrainz(json_data, listenbrainz_token)
print(response)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment