| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- import os
- import datetime
- import pickle
- from googleapiclient.discovery import build
- import subprocess
- from google.auth.transport.requests import Request
- # Output directory for Emby
- OUTPUT_DIR = "/media/media/YouTube"
- # Days to look back for videos
- DAYS_BACK = 5
- # Token file
- TOKEN_FILE = "youtube_token.pickle"
- def authenticate_with_token():
- """Authenticate using the saved token."""
- if not os.path.exists(TOKEN_FILE):
- raise FileNotFoundError(f"Token file '{TOKEN_FILE}' not found. Please run the token retrieval script first.")
- with open(TOKEN_FILE, "rb") as token:
- creds = pickle.load(token)
- # Refresh the token if needed
- if creds and creds.expired and creds.refresh_token:
- creds.refresh(Request())
- youtube = build("youtube", "v3", credentials=creds)
- return youtube
- def get_subscribed_channels(youtube):
- """Fetch the list of subscribed channels."""
- channels = []
- request = youtube.subscriptions().list(
- part="snippet",
- mine=True,
- maxResults=50
- )
- while request:
- response = request.execute()
- for item in response["items"]:
- channels.append(item["snippet"]["resourceId"]["channelId"])
- request = youtube.subscriptions().list_next(request, response)
- return channels
- def get_recent_videos(youtube, channel_id):
- """Fetch videos from a channel published in the last `DAYS_BACK` days."""
- recent_videos = []
- published_after = (datetime.datetime.now() - datetime.timedelta(days=DAYS_BACK)).isoformat("T") + "Z"
-
- request = youtube.search().list(
- part="snippet",
- channelId=channel_id,
- publishedAfter=published_after,
- maxResults=50,
- type="video",
- order="date"
- )
- response = request.execute()
- for item in response["items"]:
- recent_videos.append({
- "video_id": item["id"]["videoId"],
- "title": item["snippet"]["title"],
- "description": item["snippet"]["description"],
- "published_at": item["snippet"]["publishedAt"],
- "channel_title": item["snippet"]["channelTitle"]
- })
- return recent_videos
- def download_video(video_id, output_path):
- """Download a YouTube video using yt-dlp."""
- command = [
- "yt-dlp",
- f"https://www.youtube.com/watch?v={video_id}",
- "-o", os.path.join(output_path, "%(title)s.%(ext)s")
- ]
- subprocess.run(command, check=True)
- def create_nfo_file(video_data, file_path):
- """Create an Emby-compatible NFO file."""
- nfo_content = f"""<?xml version="1.0" encoding="utf-8" standalone="yes"?>
- <movie>
- <title>{video_data['title']}</title>
- <plot>{video_data['description']}</plot>
- <year>{video_data['published_at'][:4]}</year>
- <premiered>{video_data['published_at']}</premiered>
- <studio>{video_data['channel_title']}</studio>
- </movie>
- """
- with open(file_path, "w", encoding="utf-8") as nfo_file:
- nfo_file.write(nfo_content)
- def main():
- # Authenticate YouTube API
- print("Authenticating with token...")
- youtube = authenticate_with_token()
- if not os.path.exists(OUTPUT_DIR):
- os.makedirs(OUTPUT_DIR)
-
- # Fetch subscribed channels
- print("Fetching subscribed channels...")
- channels = get_subscribed_channels(youtube)
-
- # Fetch and process recent videos
- for channel_id in channels:
- print(f"Fetching recent videos for channel: {channel_id}")
- videos = get_recent_videos(youtube, channel_id)
-
- for video in videos:
- print(f"Processing video: {video['title']}")
- # Create a folder for the video
- video_dir = os.path.join(OUTPUT_DIR, video["title"].replace("/", "_"))
- os.makedirs(video_dir, exist_ok=True)
-
- # Download the video
- download_video(video["video_id"], video_dir)
-
- # Create the NFO file
- nfo_file_path = os.path.join(video_dir, "movie.nfo")
- create_nfo_file(video, nfo_file_path)
-
- print("All videos processed successfully!")
- if __name__ == "__main__":
- main()
|