File size: 6,096 Bytes
553b26d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
import gradio as gr
import assemblyai as aai
from anthropic import Anthropic
import os
from pydub import AudioSegment
import tempfile
# Initialize API clients
aai.settings.api_key = os.getenv("AAI_KEY")
anthropic = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
model_name = "claude-3-5-sonnet-20240620"
# Default prompts from the initial Python file
DEFAULT_TITLE_PROMPT = """
Suggest a title for the podcast episode
Dwarkesh is the host, not the guest.
The format should be:
Guest Name - Title
Make it sexy! Enticing! No boilerplate!!
Don't output anything but the suggested podcast title. Don't use hashtags or Emojis. Titles should be around 80 characters long. The best titles take a number of ideas from the episode
Here are some examples of previous podcast episode titles:
Patrick Collison (Stripe CEO) - Craft, Beauty, & The Future of Payments
Tyler Cowen - Hayek, Keynes, & Smith on AI, Animal Spirits, Anarchy, & Growth
Jung Chang - Living through Cultural Revolution and the Crimes of Mao
Andrew Roberts - SV's Napoleon Cult, Why Hitler Lost WW2, Churchill as Applied Historian
Dominic Cummings - COVID, Brexit, & Fixing Western Governance
Paul Christiano - Preventing an AI Takeover
Shane Legg (DeepMind Founder) - 2028 AGI, New Architectures, Aligning Superhuman Models
Grant Sanderson (3Blue1Brown) - Past, Present, & Future of Mathematics
Sarah C. M. Paine - WW2, Taiwan, Ukraine, & Maritime vs Continental Powers
Dario Amodei (Anthropic CEO) - Scaling, Alignment, & AI Progress
Francois Chollet - LLMs won’t lead to AGI - $1,000,000 Prize to find true solution
Leopold Aschenbrenner - 2027 AGI, China/US Super-Intelligence Race, & The Return of History
John Schulman (OpenAI Cofounder) - Reasoning, RLHF, & Plan for 2027 AGI
Come up with a title for the following transcript using guidance above.
Come up 10 titles, each on a new line, so I can select the best one.
Titles:
"""
DEFAULT_CLIP_PROMPT = """
Suggest some best portions of these episodes to make clips of.
Format this as "Aprox Timestamp: ____ - ____ || Title: "
Clips should be the most intriguing and critical parts of the episode. They should start right at the action and end once the topic has been resolved. They should be
2-10 minutes in length. Good clips often feature debate, appealing rhetoric, core ideas, intresting stories, or counterintuitve facts.
Titles should be your 2-10 word description of what is in the clip. e.g: AGI Timelines debate, Lee Kuan Yu's best choices, Why LLMs are enough for AGI, etc.
Example Output: Aprox Timestamp: 1:10 - 5:12 || Title: The Million Dollar Prize for AGI
"""
def transcribe_audio(audio_file):
# Handle both file objects and file paths
if isinstance(audio_file, str):
audio_path = audio_file
else:
audio_path = audio_file.name
# Convert audio to MP3 if it's not already
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as temp_file:
audio = AudioSegment.from_file(audio_path)
audio.export(temp_file.name, format="mp3")
# Transcribe the audio file
transcriber = aai.Transcriber()
transcript = transcriber.transcribe(
temp_file.name, config=aai.TranscriptionConfig(speaker_labels=True)
)
# Format the transcript
formatted_transcript = ""
for utterance in transcript.utterances:
formatted_transcript += f"{utterance.speaker} {format_timestamp(utterance.start)}\n{utterance.text}\n\n"
return formatted_transcript
def format_timestamp(milliseconds):
seconds = int(milliseconds / 1000)
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
return f"{hours:02d}:{minutes:02d}:{seconds:02d}"
def generate_titles(transcript, prompt):
message = anthropic.messages.create(
model=model_name,
max_tokens=1024,
messages=[
{"role": "user", "content": f"{prompt}\n\nTranscript:\n{transcript}"},
],
)
return message.content[0].text
def generate_clips(transcript, prompt):
message = anthropic.messages.create(
model=model_name,
max_tokens=1024,
messages=[
{"role": "user", "content": f"{prompt}\n\nTranscript:\n{transcript}"},
],
)
return message.content[0].text
def process_transcript(audio_file):
transcript = transcribe_audio(audio_file)
# Save transcript to a temporary file
with tempfile.NamedTemporaryFile(
mode="w", delete=False, suffix=".txt"
) as temp_file:
temp_file.write(transcript)
temp_file_path = temp_file.name
return transcript, temp_file_path
def process_title_and_clips(transcript, title_prompt, clip_prompt):
titles = generate_titles(transcript, title_prompt)
clips = generate_clips(transcript, clip_prompt)
return titles, clips
# Define the Gradio interface
with gr.Blocks() as app:
gr.Markdown("# Podcast Helper")
# with gr.Row():
audio_input = gr.Audio(type="filepath", label="Upload MP3")
transcribe_button = gr.Button("Generate Transcript")
with gr.Row():
transcript_output = gr.Textbox(label="Transcript", lines=10)
transcript_file = gr.File(label="Download Transcript")
with gr.Row():
title_prompt = gr.Textbox(
label="Title Generation Prompt", lines=3, value=DEFAULT_TITLE_PROMPT
)
clip_prompt = gr.Textbox(
label="Clip Search Prompt", lines=3, value=DEFAULT_CLIP_PROMPT
)
generate_button = gr.Button("Generate Title and Clips")
with gr.Row():
titles_output = gr.Textbox(label="Generated Titles", lines=10)
clips_output = gr.Textbox(label="Generated Clips", lines=10)
transcribe_button.click(
process_transcript,
inputs=[audio_input],
outputs=[transcript_output, transcript_file],
)
generate_button.click(
process_title_and_clips,
inputs=[transcript_output, title_prompt, clip_prompt],
outputs=[titles_output, clips_output],
)
# Launch the app
if __name__ == "__main__":
app.launch() |