You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
3.0 KiB
85 lines
3.0 KiB
1 year ago
|
import re
|
||
|
from googleapiclient.discovery import build
|
||
|
from googleapiclient.errors import HttpError
|
||
|
from youtube_transcript_api import YouTubeTranscriptApi
|
||
|
from dotenv import load_dotenv
|
||
|
import os
|
||
|
import json
|
||
|
import isodate
|
||
|
import argparse
|
||
|
|
||
12 months ago
|
|
||
1 year ago
|
def get_video_id(url):
|
||
|
# Extract video ID from URL
|
||
12 months ago
|
pattern = r"(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})"
|
||
1 year ago
|
match = re.search(pattern, url)
|
||
|
return match.group(1) if match else None
|
||
|
|
||
12 months ago
|
|
||
12 months ago
|
def main_function(url, options):
|
||
1 year ago
|
# Load environment variables from .env file
|
||
12 months ago
|
load_dotenv(os.path.expanduser("~/.config/fabric/.env"))
|
||
1 year ago
|
|
||
|
# Get YouTube API key from environment variable
|
||
12 months ago
|
api_key = os.getenv("YOUTUBE_API_KEY")
|
||
1 year ago
|
if not api_key:
|
||
|
print("Error: YOUTUBE_API_KEY not found in ~/.config/fabric/.env")
|
||
|
return
|
||
|
|
||
|
# Extract video ID from URL
|
||
|
video_id = get_video_id(url)
|
||
|
if not video_id:
|
||
|
print("Invalid YouTube URL")
|
||
|
return
|
||
|
|
||
|
try:
|
||
|
# Initialize the YouTube API client
|
||
12 months ago
|
youtube = build("youtube", "v3", developerKey=api_key)
|
||
1 year ago
|
|
||
|
# Get video details
|
||
12 months ago
|
video_response = (
|
||
|
youtube.videos().list(id=video_id, part="contentDetails").execute()
|
||
|
)
|
||
1 year ago
|
|
||
|
# Extract video duration and convert to minutes
|
||
12 months ago
|
duration_iso = video_response["items"][0]["contentDetails"]["duration"]
|
||
1 year ago
|
duration_seconds = isodate.parse_duration(duration_iso).total_seconds()
|
||
|
duration_minutes = round(duration_seconds / 60)
|
||
|
|
||
|
# Get video transcript
|
||
|
try:
|
||
|
transcript_list = YouTubeTranscriptApi.get_transcript(video_id)
|
||
12 months ago
|
transcript_text = " ".join([item["text"]
|
||
|
for item in transcript_list])
|
||
12 months ago
|
transcript_text = transcript_text.replace("\n", " ")
|
||
1 year ago
|
except Exception as e:
|
||
12 months ago
|
transcript_text = f"Transcript not available. ({e})"
|
||
1 year ago
|
|
||
|
# Output based on options
|
||
|
if options.duration:
|
||
|
print(duration_minutes)
|
||
|
elif options.transcript:
|
||
|
print(transcript_text)
|
||
|
else:
|
||
|
# Create JSON object
|
||
12 months ago
|
output = {"transcript": transcript_text,
|
||
|
"duration": duration_minutes}
|
||
1 year ago
|
# Print JSON object
|
||
|
print(json.dumps(output))
|
||
|
except HttpError as e:
|
||
12 months ago
|
|
||
12 months ago
|
print(
|
||
|
f"Error: Failed to access YouTube API. Please check your YOUTUBE_API_KEY and ensure it is valid: {e}")
|
||
12 months ago
|
|
||
|
|
||
|
def main():
|
||
|
parser = argparse.ArgumentParser(
|
||
12 months ago
|
|
||
12 months ago
|
description='yt (video meta) extracts metadata about a video, such as the transcript and the video\'s duration. By Daniel Miessler.')
|
||
1 year ago
|
parser.add_argument('url', nargs='?', help='YouTube video URL')
|
||
12 months ago
|
parser.add_argument('--duration', action='store_true',
|
||
|
help='Output only the duration')
|
||
|
parser.add_argument('--transcript', action='store_true',
|
||
|
help='Output only the transcript')
|
||
12 months ago
|
parser.add_argument("url", nargs="?", help="YouTube video URL")
|