fdbw commited on
Commit
d5ff5e8
·
verified ·
1 Parent(s): 98296a9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -27
app.py CHANGED
@@ -8,8 +8,8 @@
8
  import uvicorn
9
  import logging
10
  import asyncio
11
- from dashscope.audio.omni import OmniRealtimeConversation, OmniRealtimeConfig, OmniRealtimeParam, OmniRealtimeCallback
12
- from dashscope.audio.omni import OmniRealtimeAudioFormat, OmniRealtimeModality, OmniRealtimeTranslationParam
13
 
14
  logging.basicConfig(level=logging.INFO)
15
  logger = logging.getLogger(__name__)
@@ -48,8 +48,8 @@ def on_event(self, message):
48
  except Exception as e:
49
  logger.error(f"Error processing message: {e}")
50
 
51
- def on_close(self, code, reason):
52
- logger.info(f"Connection closed: {code} - {reason}")
53
 
54
  @app.get("/", response_class=HTMLResponse)
55
  async def get_index(request: Request):
@@ -64,47 +64,59 @@ async def websocket_endpoint(websocket: WebSocket):
64
  try:
65
  msg = json.loads(data)
66
  api_key = msg.get("api_key")
67
- workspace_id = msg.get("workspace_id", "your_workspace_id")
68
  region = msg.get("region", "cn-beijing")
69
  except:
70
- await websocket.send_text(json.dumps({"type": "error", "message": "Invalid API key format"}))
71
  return
72
 
 
73
  if not api_key:
74
  api_key = os.getenv("DASHSCOPE_API_KEY")
75
  if not api_key:
76
  await websocket.send_text(json.dumps({"type": "error", "message": "API key is required"}))
77
  return
78
 
79
- param = OmniRealtimeParam.builder() \
80
- .model("qwen3.5-livetranslate-flash-realtime") \
81
- .url(f"wss://{workspace_id}.{region}.maas.aliyuncs.com/api-ws/v1/realtime") \
82
- .build()
83
-
84
- config = OmniRealtimeConfig.builder() \
85
- .modalities([OmniRealtimeModality.AUDIO, OmniRealtimeModality.TEXT]) \
86
- .translationConfig(
87
- OmniRealtimeTranslationParam.builder()
88
- .language("auto")
89
- .build()
90
- ) \
91
- .inputAudioFormat(OmniRealtimeAudioFormat.PCM_16000HZ_MONO_16BIT) \
92
- .outputAudioFormat(OmniRealtimeAudioFormat.PCM_24000HZ_MONO_16BIT) \
93
- .enableTurnDetection(True) \
94
- .build()
95
 
 
96
  callback = TranslateCallback(websocket)
97
- conversation = OmniRealtimeConversation(param, callback)
 
 
 
 
 
 
 
98
  conversation.connect()
99
- conversation.updateSession(config)
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
  await websocket.send_text(json.dumps({"type": "ready", "message": "Connected to translation service"}))
102
 
 
103
  while True:
104
  audio_data = await websocket.receive_bytes()
105
  if audio_data:
106
  audio_base64 = base64.b64encode(audio_data).decode('utf-8')
107
- conversation.appendAudio(audio_base64)
108
 
109
  except WebSocketDisconnect:
110
  logger.info("WebSocket disconnected")
@@ -117,8 +129,7 @@ async def websocket_endpoint(websocket: WebSocket):
117
  finally:
118
  if conversation:
119
  try:
120
- conversation.endSession()
121
- conversation.close(1000, "Session ended")
122
  except:
123
  pass
124
 
 
8
  import uvicorn
9
  import logging
10
  import asyncio
11
+ from dashscope.audio.qwen_omni import OmniRealtimeConversation, OmniRealtimeCallback
12
+ from dashscope.audio.qwen_omni.omni_realtime import TranslationParams, MultiModality, AudioFormat
13
 
14
  logging.basicConfig(level=logging.INFO)
15
  logger = logging.getLogger(__name__)
 
48
  except Exception as e:
49
  logger.error(f"Error processing message: {e}")
50
 
51
+ def on_close(self):
52
+ logger.info("Connection closed.")
53
 
54
  @app.get("/", response_class=HTMLResponse)
55
  async def get_index(request: Request):
 
64
  try:
65
  msg = json.loads(data)
66
  api_key = msg.get("api_key")
67
+ workspace_id = msg.get("workspace_id")
68
  region = msg.get("region", "cn-beijing")
69
  except:
70
+ await websocket.send_text(json.dumps({"type": "error", "message": "Invalid config format"}))
71
  return
72
 
73
+ # 优先使用前端传入的 API Key,如果没有则从环境变量读取
74
  if not api_key:
75
  api_key = os.getenv("DASHSCOPE_API_KEY")
76
  if not api_key:
77
  await websocket.send_text(json.dumps({"type": "error", "message": "API key is required"}))
78
  return
79
 
80
+ if not workspace_id:
81
+ await websocket.send_text(json.dumps({"type": "error", "message": "Workspace ID is required"}))
82
+ return
83
+
84
+ # 构建 WebSocket URL
85
+ ws_url = f"wss://{workspace_id}.{region}.maas.aliyuncs.com/api-ws/v1/realtime"
 
 
 
 
 
 
 
 
 
 
86
 
87
+ # 创建回调实例
88
  callback = TranslateCallback(websocket)
89
+
90
+ # 建立连接
91
+ conversation = OmniRealtimeConversation(
92
+ model='qwen3.5-livetranslate-flash-realtime',
93
+ url=ws_url,
94
+ api_key=api_key,
95
+ callback=callback
96
+ )
97
  conversation.connect()
98
+
99
+ # 配置会话参数
100
+ translation_params = TranslationParams(
101
+ language='auto' # auto 表示自动检测源语言
102
+ )
103
+ conversation.update_session(
104
+ output_modalities=[MultiModality.TEXT, MultiModality.AUDIO],
105
+ voice='Tina',
106
+ translation_params=translation_params,
107
+ input_audio_format=AudioFormat.PCM_16000HZ_MONO_16BIT,
108
+ output_audio_format=AudioFormat.PCM_24000HZ_MONO_16BIT,
109
+ enable_turn_detection=True
110
+ )
111
 
112
  await websocket.send_text(json.dumps({"type": "ready", "message": "Connected to translation service"}))
113
 
114
+ # 循环接收音频数据
115
  while True:
116
  audio_data = await websocket.receive_bytes()
117
  if audio_data:
118
  audio_base64 = base64.b64encode(audio_data).decode('utf-8')
119
+ conversation.append_audio(audio_base64)
120
 
121
  except WebSocketDisconnect:
122
  logger.info("WebSocket disconnected")
 
129
  finally:
130
  if conversation:
131
  try:
132
+ conversation.close()
 
133
  except:
134
  pass
135