Watch History

  1. Save your watch-history.json file to some directory
  2. Update PATH to that directory
  3. (Optional) On the very last line, you can change how many years of data you want to parse
  4. Run script Python
  5. View your output files in that directory
import json
import codecs
import datetime
import collections
import os


JAN_1_25 = datetime.datetime(2025, 1, 1)
JAN_1_24 = datetime.datetime(2024, 1, 1)
JAN_1_23 = datetime.datetime(2023, 1, 1)
JAN_1_22 = datetime.datetime(2022, 1, 1)
JAN_1_21 = datetime.datetime(2021, 1, 1)
JAN_1_20 = datetime.datetime(2020, 1, 1)


PATH = 'path/to/folder/with/watch-history.json'


TIME_BUCKETS = [
    '12AM-4AM',
    '4AM-8AM',
    '8AM-12PM',
    '12PM-4PM',
    '4PM-8PM',
    '8PM-12AM'
]


def process(start, end):
    # For file name compatibility
    with codecs.open(os.path.join(PATH, 'watch-history.json'), 'r', encoding='utf-8') as f:
        raw_file = f.read()
        jsonified = json.loads(raw_file)

    channel_to_video_count = collections.defaultdict(int)
    channel_to_music_count = collections.defaultdict(int)

    day_of_week_buckets = {
        'Monday': 0,
        'Tuesday': 0,
        'Wednesday': 0,
        'Thursday': 0,
        'Friday': 0,
        'Saturday': 0,
        'Sunday': 0,
    }
    hour_of_day_buckets = {bucket: 0 for bucket in TIME_BUCKETS}

    for video in jsonified:
        watch_time = datetime.datetime.fromisoformat(video['time'][:-1])
        if watch_time > end:
            continue
        if watch_time < start:
            # File is ordered DESC
            break
        if 'subtitles' not in video:
            # Privated video
            continue
        channel_name = video['subtitles'][0]['name']
        try:
            if video['header'] == 'YouTube Music':
                channel_to_music_count[channel_name] += 1
            else:
                channel_to_video_count[channel_name] += 1
            day_of_week_buckets[watch_time.strftime('%A')] += 1
            hour_of_day_buckets[TIME_BUCKETS[watch_time.hour // 4]] += 1

        except KeyError as e:
            print('Missing header: ', e)

    metadata_output = {
        'Videos Watched By Day of Week (UTC)': day_of_week_buckets,
        'Videos Watched By Hour of Day (UTC)': hour_of_day_buckets,
    }

    sorted_video_list = dict(sorted(channel_to_video_count.items(), key=lambda item: item[1], reverse=True))
    sorted_music_list = dict(sorted(channel_to_music_count.items(), key=lambda item: item[1], reverse=True))

    stringified_videos = json.dumps(sorted_video_list, indent=2, ensure_ascii=False)
    stringified_music = json.dumps(sorted_music_list, indent=2, ensure_ascii=False)
    stringified_metadata = json.dumps(metadata_output, indent=2)

    with codecs.open(os.path.join(PATH, 'watch-history-videos.out.txt'), 'w+', encoding='utf-8') as f:
        f.write(stringified_videos)
    with codecs.open(os.path.join(PATH, 'watch-history-music.out.txt'), 'w+', encoding='utf-8') as f:
        f.write(stringified_music)
    with open(os.path.join(PATH, 'watch-history-metadata.out.txt'), 'w+') as f:
        f.write(stringified_metadata)


if __name__ == '__main__':
    process(JAN_1_24, JAN_1_25)
Edit

Pub: 10 Nov 2024 04:26 UTC

Edit: 10 Nov 2024 04:49 UTC

Views: 51