1616"""
1717
1818import asyncio
19+ import logging
1920import time
2021import uuid
21- import webbrowser
2222from dotenv import load_dotenv
23- from urllib .parse import urlencode
2423
2524from getstream .stream import Stream
2625from getstream .video import rtc
2726from getstream .video .rtc .track_util import PcmData
2827from getstream .plugins .stt .deepgram import Deepgram
29-
30-
31- def open_browser (api_key : str , token : str , call_id : str ) -> str :
32- """
33- Helper function to open browser with Stream call link.
34-
35- Args:
36- api_key: Stream API key
37- token: JWT token for the user
38- call_id: ID of the call
39-
40- Returns:
41- The URL that was opened
42- """
43- base_url = "https://pronto.getstream.io/bare/join/"
44- params = {"api_key" : api_key , "token" : token , "skip_lobby" : "true" }
45-
46- url = f"{ base_url } { call_id } ?{ urlencode (params )} "
47- print (f"Opening browser to: { url } " )
48-
49- try :
50- webbrowser .open (url )
51- print ("Browser opened successfully!" )
52- except Exception as e :
53- print (f"Failed to open browser: { e } " )
54- print (f"Please manually open this URL: { url } " )
55-
56- return url
28+ from examples .utils import create_user , open_browser
5729
5830
5931async def main ():
@@ -71,14 +43,16 @@ async def main():
7143 call_id = str (uuid .uuid4 ())
7244 print (f"📞 Call ID: { call_id } " )
7345
74- # Create a token for a user to join the call from browser
75- user_id = "browser-user"
76- user_token = client .create_token (user_id = user_id )
77- print (f"🔑 Created token for browser user: { user_id } " )
46+ user_id = f"user-{ uuid .uuid4 ()} "
47+ create_user (client , user_id , "My User" )
48+ logging .info ("👤 Created user: %s" , user_id )
7849
79- # Create a token for the transcription bot
80- bot_user_id = "transcription-bot"
81- print (f"🤖 Created token for bot user: { bot_user_id } " )
50+ user_token = client .create_token (user_id , expiration = 3600 )
51+ logging .info ("🔑 Created token for user: %s" , user_id )
52+
53+ bot_user_id = f"transcription-bot-{ uuid .uuid4 ()} "
54+ create_user (client , bot_user_id , "Transcription Bot" )
55+ logging .info ("🤖 Created bot user: %s" , bot_user_id )
8256
8357 # Create the call
8458 call = client .video .call ("default" , call_id )
@@ -96,49 +70,49 @@ async def main():
9670 # Initialize Deepgram STT (api_key comes from .env)
9771 stt = Deepgram ()
9872
99- async with await rtc .join (call , bot_user_id ) as connection :
100- print (f"✅ Bot joined call: { call_id } " )
101-
102- # Set up transcription handlers
103- @connection .on ("audio" )
104- async def on_audio (pcm : PcmData , user ):
105- # Process audio through Deepgram STT
106- await stt .process_audio (pcm , user )
107-
108- @stt .on ("transcript" )
109- async def on_transcript (text : str , user : any , metadata : dict ):
110- timestamp = time .strftime ("%H:%M:%S" )
111- user_info = user if user else "unknown"
112- print (f"[{ timestamp } ] { user_info } : { text } " )
113- if metadata .get ("confidence" ):
114- print (f" └─ confidence: { metadata ['confidence' ]:.2%} " )
115-
116- @stt .on ("partial_transcript" )
117- async def on_partial_transcript (text : str , user : any , metadata : dict ):
118- if text .strip (): # Only show non-empty partial transcripts
73+ try :
74+ async with await rtc .join (call , bot_user_id ) as connection :
75+ print (f"✅ Bot joined call: { call_id } " )
76+
77+ # Set up transcription handlers
78+ @connection .on ("audio" )
79+ async def on_audio (pcm : PcmData , user ):
80+ # Process audio through Deepgram STT
81+ await stt .process_audio (pcm , user )
82+
83+ @stt .on ("transcript" )
84+ async def on_transcript (text : str , user : any , metadata : dict ):
85+ timestamp = time .strftime ("%H:%M:%S" )
11986 user_info = user if user else "unknown"
120- print (f" { user_info } (partial): { text } " , end = "\r " ) # Overwrite line
121-
122- @stt .on ("error" )
123- async def on_stt_error (error ):
124- print (f"\n ❌ STT Error: { error } " )
87+ print (f"[{ timestamp } ] { user_info } : { text } " )
88+ if metadata .get ("confidence" ):
89+ print (f" └─ confidence: { metadata ['confidence' ]:.2%} " )
12590
126- # Keep the connection alive and wait for audio
127- print ("🎧 Listening for audio... (Press Ctrl+C to stop)" )
128- await connection .wait ()
91+ @stt .on ("partial_transcript" )
92+ async def on_partial_transcript (text : str , user : any , metadata : dict ):
93+ if text .strip (): # Only show non-empty partial transcripts
94+ user_info = user if user else "unknown"
95+ print (f" { user_info } (partial): { text } " , end = "\r " ) # Overwrite line
12996
130- # Clean up STT service
131- await stt . close ()
132- print ("🧹 Cleanup completed " )
97+ @ stt . on ( "error" )
98+ async def on_stt_error ( error ):
99+ print (f" \n ❌ STT Error: { error } " )
133100
101+ # Keep the connection alive and wait for audio
102+ print ("🎧 Listening for audio... (Press Ctrl+C to stop)" )
103+ await connection .wait ()
134104
135- if __name__ == "__main__" :
136- try :
137- asyncio .run (main ())
138- except KeyboardInterrupt :
105+ except asyncio .CancelledError :
139106 print ("\n ⏹️ Stopping transcription bot..." )
140107 except Exception as e :
141108 print (f"❌ Error: { e } " )
142109 import traceback
143-
144110 traceback .print_exc ()
111+ finally :
112+ await stt .close ()
113+ client .delete_users ([user_id , bot_user_id ])
114+ print ("🧹 Cleanup completed" )
115+
116+ if __name__ == "__main__" :
117+ asyncio .run (main ())
118+
0 commit comments