nickmuchi/PodcastGPT
0
1import os2from pydub import AudioSegment3import openai4from openai import OpenAI5import feedparser6from pathlib import Path7import wikipedia8import json9import streamlit as st10import requests11from docx import Document12from docx.shared import Pt13from docx.enum.text import WD_PARAGRAPH_ALIGNMENT14import io15 16client = OpenAI()17 18# def load_whisper_api(audio):19 20# '''Transcribe YT audio to text using Open AI API'''21 22# import openai23# file = open(audio, "rb")24# transcript = openai.Audio.translate("whisper-1", file)25 26# return transcript27 28def export_to_word(podcast_info,podcast_title):29 # Create a new Word document30 doc = Document()31 doc.add_heading(podcast_title, 0)32 33 # Adding podcast summary34 p = doc.add_paragraph()35 run = p.add_run("Podcast Summary:\n")36 run.bold = True37 run.font.size = Pt(12)38 p.add_run(podcast_info['podcast_summary'])39 40 # Adding podcast guest details41 p = doc.add_paragraph()42 run = p.add_run("\nPodcast Guest:\n")43 run.bold = True44 run.font.size = Pt(12)45 p.add_run(podcast_info['podcast_guest'])46 47 # Adding key moments48 p = doc.add_paragraph()49 run = p.add_run("\nKey Moments:\n")50 run.bold = True51 run.font.size = Pt(12)52 p.add_run(podcast_info['podcast_highlights'])53 54 # Save the document to a byte stream55 byte_io = io.BytesIO()56 doc.save(byte_io)57 byte_io.seek(0)58 59 return byte_io60 61@st.cache_data62def load_whisper_api(audio):63 64 '''Transcribe YT audio to text using Open AI API'''65 file = open(audio, "rb")66 transcript = client.audio.transcriptions.create(model="whisper-1", file=file,response_format="text")67 68 return transcript69 70@st.cache_data71def get_transcribe_podcast(rss_url, local_path='/data/'):72 73 st.info("Starting Podcast Transcription Function...")74 print("Feed URL: ", rss_url)75 print("Local Path:", local_path) 76 77 78 # Download the podcast episode by parsing the RSS feed79 p = Path(local_path)80 # p.mkdir(exist_ok=True)81 82 st.info("Downloading the podcast episode...")83 84 episode_name = "podcast_episode.mp3"85 86 with requests.get(rss_url, stream=True) as r:87 r.raise_for_status()88 episode_path = p.joinpath(episode_name)89 print(f'episode path {episode_path}')90 91 with open(episode_path, 'wb') as f:92 for chunk in r.iter_content(chunk_size=8192):93 f.write(chunk)94 95 st.info("Podcast Episode downloaded")96 97 # Perform the transcription98 st.info("Starting podcast transcription")99 100 audio_file = episode_path101 102 103 #Get size of audio file104 audio_size = round(os.path.getsize(audio_file)/(1024*1024),1)105 106 print(f'audio size: {audio_size}')107 108 #Check if file is > 24mb, if not then use Whisper API109 if audio_size <= 25:110 111 #Use whisper API112 results = load_whisper_api(audio_file)113 114 else:115 116 st.info('File size larger than 24mb, applying chunking and transcription')117 118 song = AudioSegment.from_file(audio_file, format='mp3')119 120 # PyDub handles time in milliseconds121 twenty_minutes = 20 * 60 * 1000122 123 chunks = song[::twenty_minutes]124 125 transcriptions = []126 127 for i, chunk in enumerate(chunks):128 chunk.export(f'chunk_{i}.mp3', format='mp3')129 transcriptions.append(load_whisper_api(f'chunk_{i}.mp3'))130 131 results = ','.join(transcriptions)132 133 # Return the transcribed text134 st.info("Podcast transcription completed, returning results...")135 136 return results137 138@st.cache_data139def get_podcast_summary(podcast_transcript):140 141 instructPrompt = """142 You are a podcast analyst and your main task is to summarize the key and important points of143 the podcast for a busy professional by highlighting the main and important points144 to ensure the professional has a sufficient summary of the podcast. Include any questions you consider important or 145 any points that warrant further investigation.146 147 Please use bulletpoints.148 149 """150 151 request = instructPrompt + podcast_transcript152 153 chatOutput = client.chat.completions.create(model="gpt-4-turbo-preview",154 messages=[{"role": "system", "content": "You are a helpful podcast analyzer assistant"},155 {"role": "user", "content": request}156 ]157 )158 159 podcastSummary = chatOutput.choices[0].message.content160 161 return podcastSummary162 163@st.cache_data164def get_podcast_guest(podcast_transcript):165 '''Get guest name, professional title, organization name'''166 167 completion = client.chat.completions.create(168 model="gpt-4-turbo-preview",169 messages=[{"role": "user", "content": podcast_transcript}],170 functions=[171 172 {173 "name": "get_podcast_guest_information",174 "description": "Get information on the podcast guest using their full name and the name of the organization they are part of to search for them on Wikipedia or Google",175 "parameters": {176 "type": "object",177 "properties": {178 "guest_name": {179 "type": "string",180 "description": "The full name of the guest who is being interviewed in the podcast",181 },182 "guest_organization": {183 "type": "string",184 "description": "The name or details of the organization that the podcast guest belongs to, works for or runs",185 },186 "guest_title": {187 "type": "string",188 "description": "The title, designation or role the podcast guest holds or type of work that the podcast guest in the organization does",189 },190 },191 "required": ["guest_name"],192 },193 }194],195 function_call={"name": "get_podcast_guest_information"}196)197 198 podcast_guest = ""199 podcast_guest_org = ""200 podcast_guest_title = ""201 response_message = completion.choices[0].message.function_call202 203 print(f'func res: {response_message}')204 205 if response_message:206 207 function_name = response_message.name208 function_args = json.loads(response_message.arguments)209 podcast_guest=function_args.get("guest_name")210 podcast_guest_org=function_args.get("guest_organization")211 podcast_guest_title=function_args.get("guest_title")212 213 return (podcast_guest,podcast_guest_org,podcast_guest_title)214 215@st.cache_data216def get_podcast_highlights(podcast_transcript):217 218 instructPrompt = """219 Extract some key moments in the podcast. These are typically interesting insights from the guest or critical questions that the host might have put forward. It could also be a discussion on a hot topic or controversial opinion220"""221 request = instructPrompt + podcast_transcript222 223 chatOutput = client.chat.completions.create(model="gpt-4-turbo-preview",224 messages=[{"role": "system", "content": "You are a helpful assistant."},225 {"role": "user", "content": podcast_transcript}226 ]227 )228 229 podcastHighlights = chatOutput.choices[0].message.content230 231 return podcastHighlights232 233@st.cache_data234def process_podcast(url, path='/data/'):235 236 '''Get podcast transcription into json'''237 238 output = {}239 podcast_details = get_transcribe_podcast(url, path)240 podcast_summary = get_podcast_summary(podcast_details)241 podcast_guest_details = get_podcast_guest(podcast_details)242 podcast_highlights = get_podcast_highlights(podcast_details)243 output['podcast_details'] = podcast_details244 output['podcast_summary'] = podcast_summary245 output['podcast_guest'] = podcast_guest_details[0]246 output['podcast_guest_org'] = podcast_guest_details[1]247 output['podcast_guest_title'] = podcast_guest_details[2]248 output['podcast_highlights'] = podcast_highlights249 250 return output