lisonallen commited on
Commit
217c6bd
·
1 Parent(s): 1064203

重构处理函数以支持Hugging Face Spaces GPU,优化错误消息处理逻辑,确保用户界面友好性

Browse files
Files changed (1) hide show
  1. app.py +247 -212
app.py CHANGED
@@ -854,179 +854,164 @@ def worker(input_image, prompt, n_prompt, seed, total_second_length, latent_wind
854
  return
855
 
856
 
857
- # 创建友好的错误显示HTML
858
- def create_error_html(error_msg, is_timeout=False):
859
- """创建双语错误消息HTML"""
860
- # 提供更友好的中英文双语错误信息
861
- en_msg = ""
862
- zh_msg = ""
863
-
864
- if is_timeout:
865
- en_msg = "Processing timed out, but partial video may have been generated" if "部分视频" in error_msg else f"Processing timed out: {error_msg}"
866
- zh_msg = "处理超时,但已生成部分视频" if "部分视频" in error_msg else f"处理超时: {error_msg}"
867
- elif "模型加载失败" in error_msg:
868
- en_msg = "Failed to load models. The Space may be experiencing high traffic or GPU issues."
869
- zh_msg = "模型加载失败,可能是Space流量过高或GPU资源不足。"
870
- elif "GPU" in error_msg or "CUDA" in error_msg or "内存" in error_msg or "memory" in error_msg:
871
- en_msg = "GPU memory insufficient or GPU error. Try increasing GPU memory preservation value or reduce video length."
872
- zh_msg = "GPU内存不足或GPU错误,请尝试增加GPU推理保留内存值或降低视频长度。"
873
- elif "采样过程中出错" in error_msg:
874
- if "部分" in error_msg:
875
- en_msg = "Error during sampling process, but partial video has been generated."
876
- zh_msg = "采样过程中出错,但已生成部分视频。"
877
- else:
878
- en_msg = "Error during sampling process. Unable to generate video."
879
- zh_msg = "采样过程中出错,无法生成视频。"
880
- elif "模型下载超时" in error_msg or "网络连接不稳定" in error_msg or "ReadTimeoutError" in error_msg or "ConnectionError" in error_msg:
881
- en_msg = "Network connection is unstable, model download timed out. Please try again later."
882
- zh_msg = "网络连接不稳定,模型下载超时。请稍后再试。"
883
- elif "VAE" in error_msg or "解码" in error_msg or "decode" in error_msg:
884
- en_msg = "Error during video decoding or saving process. Try again with a different seed."
885
- zh_msg = "视频解码或保存过程中出错,请尝试使用不同的随机种子。"
886
- else:
887
- en_msg = f"Processing error: {error_msg}"
888
- zh_msg = f"处理过程出错: {error_msg}"
889
-
890
- # 创建双语错误消息HTML - 添加有用的图标并确保CSS样式适用
891
- return f"""
892
- <div class="error-message" id="custom-error-container">
893
- <div class="error-msg-en" data-lang="en">
894
- <span class="error-icon">⚠️</span> {en_msg}
895
- </div>
896
- <div class="error-msg-zh" data-lang="zh">
897
- <span class="error-icon">⚠️</span> {zh_msg}
898
- </div>
899
- </div>
900
- <script>
901
- // 根据当前语言显示相应的错误消息
902
- (function() {{
903
- const errorContainer = document.getElementById('custom-error-container');
904
- if (errorContainer) {{
905
- const currentLang = window.currentLang || 'en'; // 默认英语
906
- const errMsgs = errorContainer.querySelectorAll('[data-lang]');
907
- errMsgs.forEach(msg => {{
908
- msg.style.display = msg.getAttribute('data-lang') === currentLang ? 'block' : 'none';
909
- }});
910
-
911
- // 确保Gradio默认错误UI不显示
912
- const defaultErrorElements = document.querySelectorAll('.error');
913
- defaultErrorElements.forEach(el => {{
914
- el.style.display = 'none';
915
- }});
916
- }}
917
- }})();
918
- </script>
919
- """
920
 
921
- # 修改process函数,添加任务状态检查
922
- def process(input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache):
923
- global stream
924
- assert input_image is not None, 'No input image!'
925
 
926
- # 检查是否有正在运行的任务并清理
927
- if hasattr(stream, 'is_running') and stream.is_running:
928
  try:
929
- # 终止现有任务
930
- stream.input_queue.push('end')
931
- time.sleep(0.5) # 给一点时间让旧任务结束
932
- except:
933
- pass
934
-
935
- # 创建新的流实例
936
- stream = AsyncStream()
937
- stream.is_running = True
938
-
939
- # 初始化UI状态
940
- yield None, None, '', '', gr.update(interactive=False), gr.update(interactive=True)
941
 
942
- try:
943
- # 异步启动worker
944
- async_run(worker, input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache)
945
 
946
- output_filename = None
947
- prev_output_filename = None
948
- error_message = None
949
 
950
- # 持续检查worker的输出
951
- while True:
952
- try:
953
- flag, data = stream.output_queue.next()
954
-
955
- if flag == 'file':
956
- output_filename = data
957
- prev_output_filename = output_filename
958
- # 清除错误显示,确保文件成功时不显示错误
959
- yield output_filename, gr.update(), gr.update(), '', gr.update(interactive=False), gr.update(interactive=True)
960
-
961
- if flag == 'progress':
962
- preview, desc, html = data
963
- # 更新进度时不改变错误信息
964
- yield gr.update(), gr.update(visible=True, value=preview), desc, html, gr.update(interactive=False), gr.update(interactive=True)
965
-
966
- if flag == 'error':
967
- error_message = data
968
- print(f"收到错误消息: {error_message}")
969
- # 不立即显示,等待end信号
970
-
971
- if flag == 'end':
972
- # 如果有最后的视频文件,确保返回
973
- if output_filename is None and prev_output_filename is not None:
974
- output_filename = prev_output_filename
975
 
976
- # 如果有错误消息,创建友好的错误显示
977
- if error_message:
978
- error_html = create_error_html(error_message)
979
- yield output_filename, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
980
- else:
981
- # 确保成功完成时不显示任何错误
982
- yield output_filename, gr.update(visible=False), gr.update(), '', gr.update(interactive=True), gr.update(interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
983
 
984
- # 标记任务已结束
985
- stream.is_running = False
986
- break
987
- except Exception as e:
988
- print(f"处理输出时出错: {e}")
989
- # 检查是否长时间没有更新
990
- current_time = time.time()
991
- if current_time - last_update_time > 60: # 60秒没有更新,可能卡住了
992
- print(f"处理似乎卡住了,已经 {current_time - last_update_time:.1f} 秒没有更新")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
993
 
994
- # 如果有部分生成的视频,返回
995
- if prev_output_filename:
996
- error_html = create_error_html("处理超时,但已生成部分视频", is_timeout=True)
997
- yield prev_output_filename, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
998
- else:
999
- error_html = create_error_html(f"处理超时: {e}", is_timeout=True)
1000
- yield None, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1001
 
1002
- # 标记任务已结束
1003
- stream.is_running = False
1004
- break
1005
-
1006
- except Exception as e:
1007
- print(f"启动处理时出错: {e}")
1008
- traceback.print_exc()
1009
- error_msg = str(e)
1010
-
1011
- error_html = create_error_html(error_msg)
1012
- yield None, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
1013
-
1014
- # 标记任务已结束
1015
- stream.is_running = False
1016
-
1017
- def end_process():
1018
- if hasattr(stream, 'input_queue'):
1019
- stream.input_queue.push('end')
1020
- if hasattr(stream, 'is_running'):
1021
- stream.is_running = False
1022
 
1023
 
1024
- # 使用Hugging Face Spaces GPU装饰器处理进程函数
1025
- if IN_HF_SPACE and 'spaces' in globals():
1026
- @spaces.GPU
1027
- def process_with_gpu(input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache):
1028
- # 调用普通的process函数实现,以避免重复代码
1029
- return process(input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache)
1030
 
1031
 
1032
  quick_prompts = [
@@ -1148,65 +1133,56 @@ def make_custom_css():
1148
  /* 进度条样式增强 */
1149
  .progress-container {
1150
  margin-top: 10px;
 
1151
  }
1152
 
1153
  /* 错误消息样式 */
 
 
 
 
 
 
 
 
 
1154
  .error-message {
1155
- background-color: rgba(255, 220, 220, 0.95);
1156
- border: 1px solid #ff0000;
1157
- border-radius: 5px;
1158
- padding: 12px 15px;
1159
- margin: 15px 0;
1160
- font-size: 15px;
1161
- display: flex;
1162
- flex-direction: column;
1163
- gap: 4px;
1164
  }
1165
 
1166
- .error-message:empty {
1167
- display: none;
1168
- background: none;
1169
- border: none;
1170
- padding: 0;
1171
- margin: 0;
1172
  }
1173
 
 
1174
  .error-icon {
 
 
1175
  margin-right: 8px;
1176
- font-size: 16px;
1177
  }
1178
 
1179
- .error-msg-en, .error-msg-zh {
1180
- padding: 4px 0;
1181
- line-height: 1.4;
1182
- }
1183
-
1184
- /* 确保Gradio默认错误消息不与我们的冲突 */
1185
- #custom-error-container + .error {
1186
- display: none !important;
1187
  }
1188
 
1189
- /* 空错误消息不显示 */
1190
- #error-message:empty,
1191
- #custom-error-container:empty {
1192
  display: none !important;
1193
- background: none !important;
1194
- border: none !important;
1195
- padding: 0 !important;
1196
- margin: 0 !important;
1197
- }
1198
-
1199
- /* 黑暗模式下的错误消息 */
1200
- @media (prefers-color-scheme: dark) {
1201
- .error-message {
1202
- background-color: rgba(80, 0, 0, 0.95);
1203
- border-color: #ff5555;
1204
- color: #ffdddd;
1205
- }
1206
  }
1207
  """
1208
 
1209
- return progress_bar_css + responsive_css
 
 
1210
 
1211
 
1212
  css = make_custom_css()
@@ -1519,18 +1495,77 @@ with block:
1519
 
1520
  # 错误信息区域 - 确保使用HTML组件以支持我们的自定义错误消息格式
1521
  error_message = gr.HTML('', elem_id='error-message', visible=True)
1522
-
1523
- # 在此处定义处理函数需要的输入参数列表,确保UI元素已定义
1524
  ips = [input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache]
1525
 
1526
  # 开始和结束按钮事件
1527
- if IN_HF_SPACE and 'spaces' in globals() and GPU_AVAILABLE and not cpu_fallback_mode:
1528
- # 使用带GPU装饰器的处理函数
1529
- start_button.click(fn=process_with_gpu, inputs=ips, outputs=[result_video, preview_image, progress_desc, progress_bar, start_button, end_button])
1530
- else:
1531
- # 使用普通处理函数
1532
- start_button.click(fn=process, inputs=ips, outputs=[result_video, preview_image, progress_desc, progress_bar, start_button, end_button])
1533
-
1534
  end_button.click(fn=end_process)
1535
 
1536
- block.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
854
  return
855
 
856
 
857
+ # 使用Hugging Face Spaces GPU装饰器处理进程函数
858
+ if IN_HF_SPACE and 'spaces' in globals():
859
+ @spaces.GPU
860
+ def process_with_gpu(input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache):
861
+ global stream
862
+ assert input_image is not None, 'No input image!'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
863
 
864
+ # 初始化UI状态
865
+ yield None, None, '', '', gr.update(interactive=False), gr.update(interactive=True)
 
 
866
 
 
 
867
  try:
868
+ stream = AsyncStream()
 
 
 
 
 
 
 
 
 
 
 
869
 
870
+ # 异步启动worker
871
+ async_run(worker, input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache)
 
872
 
873
+ output_filename = None
874
+ prev_output_filename = None
875
+ error_message = None
876
 
877
+ # 持续检查worker的输出
878
+ while True:
879
+ try:
880
+ flag, data = stream.output_queue.next()
881
+
882
+ if flag == 'file':
883
+ output_filename = data
884
+ prev_output_filename = output_filename
885
+ # 清除错误显示,确保文件成功时不显示错误
886
+ yield output_filename, gr.update(), gr.update(), '', gr.update(interactive=False), gr.update(interactive=True)
887
+
888
+ if flag == 'progress':
889
+ preview, desc, html = data
890
+ # 更新进度时不改变错误信息
891
+ yield gr.update(), gr.update(visible=True, value=preview), desc, html, gr.update(interactive=False), gr.update(interactive=True)
 
 
 
 
 
 
 
 
 
 
892
 
893
+ if flag == 'error':
894
+ error_message = data
895
+ print(f"收到错误消息: {error_message}")
896
+ # 不立即显示,等待end信号
897
+
898
+ if flag == 'end':
899
+ # 如果有最后的视频文件,确保返回
900
+ if output_filename is None and prev_output_filename is not None:
901
+ output_filename = prev_output_filename
902
+
903
+ # 如果有错误消息,创建友好的错误显示
904
+ if error_message:
905
+ error_html = create_error_html(error_message)
906
+ yield output_filename, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
907
+ else:
908
+ # 确保成功完成时不显示任何错误
909
+ yield output_filename, gr.update(visible=False), gr.update(), '', gr.update(interactive=True), gr.update(interactive=False)
910
+ break
911
+ except Exception as e:
912
+ print(f"处理输出时出错: {e}")
913
+ # 检查是否长时间没有更新
914
+ current_time = time.time()
915
+ if current_time - last_update_time > 60: # 60秒没有更新,可能卡住了
916
+ print(f"处理似乎卡住了,已经 {current_time - last_update_time:.1f} 秒没有更新")
917
+
918
+ # 如果有部分生成的视频,返回
919
+ if prev_output_filename:
920
+ error_html = create_error_html("处理超时,但已生成部分视频", is_timeout=True)
921
+ yield prev_output_filename, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
922
+ else:
923
+ error_html = create_error_html(f"处理超时: {e}", is_timeout=True)
924
+ yield None, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
925
+ break
926
 
927
+ except Exception as e:
928
+ print(f"启动处理时出错: {e}")
929
+ traceback.print_exc()
930
+ error_msg = str(e)
931
+
932
+ error_html = create_error_html(error_msg)
933
+ yield None, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
934
+
935
+ process = process_with_gpu
936
+ else:
937
+ def process(input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache):
938
+ global stream
939
+ assert input_image is not None, 'No input image!'
940
+
941
+ # 初始化UI状态
942
+ yield None, None, '', '', gr.update(interactive=False), gr.update(interactive=True)
943
+
944
+ try:
945
+ stream = AsyncStream()
946
+
947
+ # 异步启动worker
948
+ async_run(worker, input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache)
949
+
950
+ output_filename = None
951
+ prev_output_filename = None
952
+ error_message = None
953
+
954
+ # 持续检查worker的输出
955
+ while True:
956
+ try:
957
+ flag, data = stream.output_queue.next()
958
+
959
+ if flag == 'file':
960
+ output_filename = data
961
+ prev_output_filename = output_filename
962
+ # 清除错误显示,确保文件成功时不显示错误
963
+ yield output_filename, gr.update(), gr.update(), '', gr.update(interactive=False), gr.update(interactive=True)
964
+
965
+ if flag == 'progress':
966
+ preview, desc, html = data
967
+ # 更新进度时不改变错误信息
968
+ yield gr.update(), gr.update(visible=True, value=preview), desc, html, gr.update(interactive=False), gr.update(interactive=True)
969
 
970
+ if flag == 'error':
971
+ error_message = data
972
+ print(f"收到错误消息: {error_message}")
973
+ # 不立即显示,等待end信号
974
+
975
+ if flag == 'end':
976
+ # 如果有最后的视频文件,确保返回
977
+ if output_filename is None and prev_output_filename is not None:
978
+ output_filename = prev_output_filename
979
+
980
+ # 如果有错误消息,创建友好的错误显示
981
+ if error_message:
982
+ error_html = create_error_html(error_message)
983
+ yield output_filename, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
984
+ else:
985
+ # 确保成功完成时不显示任何错误
986
+ yield output_filename, gr.update(visible=False), gr.update(), '', gr.update(interactive=True), gr.update(interactive=False)
987
+ break
988
+ except Exception as e:
989
+ print(f"处理输出时出错: {e}")
990
+ # 检查是否长时间没有更新
991
+ current_time = time.time()
992
+ if current_time - last_update_time > 60: # 60秒没有更新,可能卡住了
993
+ print(f"处理似乎卡住了,已经 {current_time - last_update_time:.1f} 秒没有更新")
994
+
995
+ # 如果有部分生成的视频,返回
996
+ if prev_output_filename:
997
+ error_html = create_error_html("处理超时,但已生成部分视频", is_timeout=True)
998
+ yield prev_output_filename, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
999
+ else:
1000
+ error_html = create_error_html(f"处理超时: {e}", is_timeout=True)
1001
+ yield None, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
1002
+ break
1003
 
1004
+ except Exception as e:
1005
+ print(f"启动处理时出错: {e}")
1006
+ traceback.print_exc()
1007
+ error_msg = str(e)
1008
+
1009
+ error_html = create_error_html(error_msg)
1010
+ yield None, gr.update(visible=False), gr.update(), error_html, gr.update(interactive=True), gr.update(interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
1011
 
1012
 
1013
+ def end_process():
1014
+ stream.input_queue.push('end')
 
 
 
 
1015
 
1016
 
1017
  quick_prompts = [
 
1133
  /* 进度条样式增强 */
1134
  .progress-container {
1135
  margin-top: 10px;
1136
+ margin-bottom: 10px;
1137
  }
1138
 
1139
  /* 错误消息样式 */
1140
+ #error-message {
1141
+ color: #ff4444;
1142
+ font-weight: bold;
1143
+ padding: 10px;
1144
+ border-radius: 4px;
1145
+ margin-top: 10px;
1146
+ }
1147
+
1148
+ /* 确保错误容器正确显示 */
1149
  .error-message {
1150
+ background-color: rgba(255, 0, 0, 0.1);
1151
+ padding: 10px;
1152
+ border-radius: 4px;
1153
+ margin-top: 10px;
1154
+ border: 1px solid #ffcccc;
 
 
 
 
1155
  }
1156
 
1157
+ /* 处理多语言错误消息 */
1158
+ .error-msg-en, .error-msg-zh {
1159
+ font-weight: bold;
 
 
 
1160
  }
1161
 
1162
+ /* 错误图标 */
1163
  .error-icon {
1164
+ color: #ff4444;
1165
+ font-size: 18px;
1166
  margin-right: 8px;
 
1167
  }
1168
 
1169
+ /* 确保空错误消息不显示背景和边框 */
1170
+ #error-message:empty {
1171
+ background-color: transparent;
1172
+ border: none;
1173
+ padding: 0;
1174
+ margin: 0;
 
 
1175
  }
1176
 
1177
+ /* 修复Gradio默认错误显示 */
1178
+ .error {
 
1179
  display: none !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
1180
  }
1181
  """
1182
 
1183
+ # 合并CSS
1184
+ combined_css = progress_bar_css + responsive_css
1185
+ return combined_css
1186
 
1187
 
1188
  css = make_custom_css()
 
1495
 
1496
  # 错误信息区域 - 确保使用HTML组件以支持我们的自定义错误消息格式
1497
  error_message = gr.HTML('', elem_id='error-message', visible=True)
1498
+
1499
+ # 处理函数
1500
  ips = [input_image, prompt, n_prompt, seed, total_second_length, latent_window_size, steps, cfg, gs, rs, gpu_memory_preservation, use_teacache]
1501
 
1502
  # 开始和结束按钮事件
1503
+ start_button.click(fn=process, inputs=ips, outputs=[result_video, preview_image, progress_desc, progress_bar, start_button, end_button])
 
 
 
 
 
 
1504
  end_button.click(fn=end_process)
1505
 
1506
+
1507
+ block.launch()
1508
+
1509
+ # 创建友好的错误显示HTML
1510
+ def create_error_html(error_msg, is_timeout=False):
1511
+ """创建双语错误消息HTML"""
1512
+ # 提供更友好的中英文双语错误信息
1513
+ en_msg = ""
1514
+ zh_msg = ""
1515
+
1516
+ if is_timeout:
1517
+ en_msg = "Processing timed out, but partial video may have been generated" if "部分视频" in error_msg else f"Processing timed out: {error_msg}"
1518
+ zh_msg = "处理超时,但已生成部分视频" if "部分视频" in error_msg else f"处理超时: {error_msg}"
1519
+ elif "模型加载失败" in error_msg:
1520
+ en_msg = "Failed to load models. The Space may be experiencing high traffic or GPU issues."
1521
+ zh_msg = "模型加载失败,可能是Space流量过高或GPU资源不足。"
1522
+ elif "GPU" in error_msg or "CUDA" in error_msg or "内存" in error_msg or "memory" in error_msg:
1523
+ en_msg = "GPU memory insufficient or GPU error. Try increasing GPU memory preservation value or reduce video length."
1524
+ zh_msg = "GPU内存不足或GPU错误,请尝试增加GPU推理保留内存值或降低视频长度。"
1525
+ elif "采样过程中出错" in error_msg:
1526
+ if "部分" in error_msg:
1527
+ en_msg = "Error during sampling process, but partial video has been generated."
1528
+ zh_msg = "采样过程中出错,但已生成部分视频。"
1529
+ else:
1530
+ en_msg = "Error during sampling process. Unable to generate video."
1531
+ zh_msg = "采样过程中出错,无法生成视频。"
1532
+ elif "模型下载超时" in error_msg or "网络连接不稳定" in error_msg or "ReadTimeoutError" in error_msg or "ConnectionError" in error_msg:
1533
+ en_msg = "Network connection is unstable, model download timed out. Please try again later."
1534
+ zh_msg = "网络连接不稳定,模型下载超时。请稍后再试。"
1535
+ elif "VAE" in error_msg or "解码" in error_msg or "decode" in error_msg:
1536
+ en_msg = "Error during video decoding or saving process. Try again with a different seed."
1537
+ zh_msg = "视频解码或保存过程中出错,请尝试使用不同的随机种子。"
1538
+ else:
1539
+ en_msg = f"Processing error: {error_msg}"
1540
+ zh_msg = f"处理过程出错: {error_msg}"
1541
+
1542
+ # 创建双语错误消息HTML - 添加有用的图标并确保CSS样式适用
1543
+ return f"""
1544
+ <div class="error-message" id="custom-error-container">
1545
+ <div class="error-msg-en" data-lang="en">
1546
+ <span class="error-icon">⚠️</span> {en_msg}
1547
+ </div>
1548
+ <div class="error-msg-zh" data-lang="zh">
1549
+ <span class="error-icon">⚠️</span> {zh_msg}
1550
+ </div>
1551
+ </div>
1552
+ <script>
1553
+ // 根据当前语言显示相应的错误消息
1554
+ (function() {{
1555
+ const errorContainer = document.getElementById('custom-error-container');
1556
+ if (errorContainer) {{
1557
+ const currentLang = window.currentLang || 'en'; // 默认英语
1558
+ const errMsgs = errorContainer.querySelectorAll('[data-lang]');
1559
+ errMsgs.forEach(msg => {{
1560
+ msg.style.display = msg.getAttribute('data-lang') === currentLang ? 'block' : 'none';
1561
+ }});
1562
+
1563
+ // 确保Gradio默认错误UI不显示
1564
+ const defaultErrorElements = document.querySelectorAll('.error');
1565
+ defaultErrorElements.forEach(el => {{
1566
+ el.style.display = 'none';
1567
+ }});
1568
+ }}
1569
+ }})();
1570
+ </script>
1571
+ """