#!/usr/bin/env python3 import json import time from PIL import Image, ImageDraw, ImageFont import requests from rgbmatrix import RGBMatrix, RGBMatrixOptions import os class YouTubeDisplay: def __init__(self, config_path='config/config.json', secrets_path='config/config_secrets.json'): self.config = self._load_config(config_path) self.secrets = self._load_config(secrets_path) self.matrix = self._setup_matrix() self.canvas = self.matrix.CreateFrameCanvas() self.font = ImageFont.truetype("assets/fonts/PressStart2P-Regular.ttf", 8) self.youtube_logo = Image.open("assets/youtube_logo.png") def _load_config(self, config_path): with open(config_path, 'r') as f: return json.load(f) def _setup_matrix(self): options = RGBMatrixOptions() display_config = self.config['display']['hardware'] options.rows = display_config['rows'] options.cols = display_config['cols'] options.chain_length = display_config['chain_length'] options.parallel = display_config['parallel'] options.hardware_mapping = display_config['hardware_mapping'] options.brightness = display_config['brightness'] options.pwm_bits = display_config['pwm_bits'] options.pwm_lsb_nanoseconds = display_config['pwm_lsb_nanoseconds'] options.disable_hardware_pulsing = display_config['disable_hardware_pulsing'] options.show_refresh_rate = display_config['show_refresh_rate'] options.limit_refresh_rate_hz = display_config['limit_refresh_rate_hz'] options.gpio_slowdown = self.config['display']['runtime']['gpio_slowdown'] return RGBMatrix(options=options) def _get_channel_stats(self, channel_id): api_key = self.secrets['youtube']['api_key'] url = f"https://www.googleapis.com/youtube/v3/channels?part=statistics,snippet&id={channel_id}&key={api_key}" try: response = requests.get(url) data = response.json() if data['items']: channel = data['items'][0] return { 'title': channel['snippet']['title'], 'subscribers': int(channel['statistics']['subscriberCount']), 'views': int(channel['statistics']['viewCount']) } except Exception as e: print(f"Error fetching YouTube stats: {e}") return None def _create_display(self, channel_stats): # Create a new image with the matrix dimensions image = Image.new('RGB', (self.matrix.width, self.matrix.height)) draw = ImageDraw.Draw(image) # Resize YouTube logo to fit logo_height = self.matrix.height // 3 logo_width = int(self.youtube_logo.width * (logo_height / self.youtube_logo.height)) resized_logo = self.youtube_logo.resize((logo_width, logo_height)) # Calculate positions logo_x = (self.matrix.width - logo_width) // 2 logo_y = 0 # Paste the logo image.paste(resized_logo, (logo_x, logo_y)) # Draw channel name channel_name = channel_stats['title'] name_bbox = draw.textbbox((0, 0), channel_name, font=self.font) name_width = name_bbox[2] - name_bbox[0] name_x = (self.matrix.width - name_width) // 2 name_y = logo_height + 5 draw.text((name_x, name_y), channel_name, font=self.font, fill=(255, 255, 255)) # Draw subscriber count subs_text = f"{channel_stats['subscribers']:,} subscribers" subs_bbox = draw.textbbox((0, 0), subs_text, font=self.font) subs_width = subs_bbox[2] - subs_bbox[0] subs_x = (self.matrix.width - subs_width) // 2 subs_y = name_y + 15 draw.text((subs_x, subs_y), subs_text, font=self.font, fill=(255, 255, 255)) return image def run(self): if not self.config.get('youtube', {}).get('enabled', False): return channel_id = self.secrets['youtube']['channel_id'] duration = self.config['display']['display_durations']['youtube'] channel_stats = self._get_channel_stats(channel_id) if channel_stats: display_image = self._create_display(channel_stats) self.canvas.SetImage(display_image) self.matrix.SwapOnVSync(self.canvas) time.sleep(duration) def cleanup(self): self.matrix.Clear() if __name__ == "__main__": # Example usage youtube_display = YouTubeDisplay() youtube_display.run() youtube_display.cleanup()