|
|
@ -11,17 +11,17 @@ import argparse |
|
|
|
|
|
|
|
|
|
|
|
def get_video_id(url): |
|
|
|
def get_video_id(url): |
|
|
|
# Extract video ID from URL |
|
|
|
# Extract video ID from URL |
|
|
|
pattern = r'(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})' |
|
|
|
pattern = r"(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:[^\/\n\s]+\/\S+\/|(?:v|e(?:mbed)?)\/|\S*?[?&]v=)|youtu\.be\/)([a-zA-Z0-9_-]{11})" |
|
|
|
match = re.search(pattern, url) |
|
|
|
match = re.search(pattern, url) |
|
|
|
return match.group(1) if match else None |
|
|
|
return match.group(1) if match else None |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main_function(url, options): |
|
|
|
def main_function(url, options): |
|
|
|
# Load environment variables from .env file |
|
|
|
# Load environment variables from .env file |
|
|
|
load_dotenv(os.path.expanduser('~/.config/fabric/.env')) |
|
|
|
load_dotenv(os.path.expanduser("~/.config/fabric/.env")) |
|
|
|
|
|
|
|
|
|
|
|
# Get YouTube API key from environment variable |
|
|
|
# Get YouTube API key from environment variable |
|
|
|
api_key = os.getenv('YOUTUBE_API_KEY') |
|
|
|
api_key = os.getenv("YOUTUBE_API_KEY") |
|
|
|
if not api_key: |
|
|
|
if not api_key: |
|
|
|
print("Error: YOUTUBE_API_KEY not found in ~/.config/fabric/.env") |
|
|
|
print("Error: YOUTUBE_API_KEY not found in ~/.config/fabric/.env") |
|
|
|
return |
|
|
|
return |
|
|
@ -34,25 +34,23 @@ def main_function(url, options): |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
try: |
|
|
|
# Initialize the YouTube API client |
|
|
|
# Initialize the YouTube API client |
|
|
|
youtube = build('youtube', 'v3', developerKey=api_key) |
|
|
|
youtube = build("youtube", "v3", developerKey=api_key) |
|
|
|
|
|
|
|
|
|
|
|
# Get video details |
|
|
|
# Get video details |
|
|
|
video_response = youtube.videos().list( |
|
|
|
video_response = ( |
|
|
|
id=video_id, |
|
|
|
youtube.videos().list(id=video_id, part="contentDetails").execute() |
|
|
|
part='contentDetails' |
|
|
|
) |
|
|
|
).execute() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Extract video duration and convert to minutes |
|
|
|
# Extract video duration and convert to minutes |
|
|
|
duration_iso = video_response['items'][0]['contentDetails']['duration'] |
|
|
|
duration_iso = video_response["items"][0]["contentDetails"]["duration"] |
|
|
|
duration_seconds = isodate.parse_duration(duration_iso).total_seconds() |
|
|
|
duration_seconds = isodate.parse_duration(duration_iso).total_seconds() |
|
|
|
duration_minutes = round(duration_seconds / 60) |
|
|
|
duration_minutes = round(duration_seconds / 60) |
|
|
|
|
|
|
|
|
|
|
|
# Get video transcript |
|
|
|
# Get video transcript |
|
|
|
try: |
|
|
|
try: |
|
|
|
transcript_list = YouTubeTranscriptApi.get_transcript(video_id) |
|
|
|
transcript_list = YouTubeTranscriptApi.get_transcript(video_id) |
|
|
|
transcript_text = ' '.join([item['text'] |
|
|
|
transcript_text = " ".join([item["text"] for item in transcript_list]) |
|
|
|
for item in transcript_list]) |
|
|
|
transcript_text = transcript_text.replace("\n", " ") |
|
|
|
transcript_text = transcript_text.replace('\n', ' ') |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
except Exception as e: |
|
|
|
transcript_text = "Transcript not available." |
|
|
|
transcript_text = "Transcript not available." |
|
|
|
|
|
|
|
|
|
|
@ -63,24 +61,26 @@ def main_function(url, options): |
|
|
|
print(transcript_text) |
|
|
|
print(transcript_text) |
|
|
|
else: |
|
|
|
else: |
|
|
|
# Create JSON object |
|
|
|
# Create JSON object |
|
|
|
output = { |
|
|
|
output = {"transcript": transcript_text, "duration": duration_minutes} |
|
|
|
"transcript": transcript_text, |
|
|
|
|
|
|
|
"duration": duration_minutes |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
# Print JSON object |
|
|
|
# Print JSON object |
|
|
|
print(json.dumps(output)) |
|
|
|
print(json.dumps(output)) |
|
|
|
except HttpError as e: |
|
|
|
except HttpError as e: |
|
|
|
print("Error: Failed to access YouTube API. Please check your YOUTUBE_API_KEY and ensure it is valid.") |
|
|
|
print( |
|
|
|
|
|
|
|
"Error: Failed to access YouTube API. Please check your YOUTUBE_API_KEY and ensure it is valid." |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main(): |
|
|
|
def main(): |
|
|
|
parser = argparse.ArgumentParser( |
|
|
|
parser = argparse.ArgumentParser( |
|
|
|
description='vm (video meta) extracts metadata about a video, such as the transcript and the video\'s duration. By Daniel Miessler.') |
|
|
|
description="vm (video meta) extracts metadata about a video, such as the transcript and the video's duration. By Daniel Miessler." |
|
|
|
parser.add_argument('url', nargs='?', help='YouTube video URL') |
|
|
|
) |
|
|
|
parser.add_argument('--duration', action='store_true', |
|
|
|
parser.add_argument("url", nargs="?", help="YouTube video URL") |
|
|
|
help='Output only the duration') |
|
|
|
parser.add_argument( |
|
|
|
parser.add_argument('--transcript', action='store_true', |
|
|
|
"--duration", action="store_true", help="Output only the duration" |
|
|
|
help='Output only the transcript') |
|
|
|
) |
|
|
|
|
|
|
|
parser.add_argument( |
|
|
|
|
|
|
|
"--transcript", action="store_true", help="Output only the transcript" |
|
|
|
|
|
|
|
) |
|
|
|
args = parser.parse_args() |
|
|
|
args = parser.parse_args() |
|
|
|
|
|
|
|
|
|
|
|
if args.url: |
|
|
|
if args.url: |
|
|
|