Breeze1124 commited on
Commit
a247643
·
1 Parent(s): 04c1763
Files changed (1) hide show
  1. app.py +42 -50
app.py CHANGED
@@ -28,6 +28,8 @@ SCENES = [
28
 
29
  gallery_items = [(item["thumb"], item["name"]) for item in SCENES]
30
 
 
 
31
  def load_scene(evt: gr.SelectData, request: gr.Request):
32
  index = evt.index
33
  scene = SCENES[index]
@@ -35,6 +37,7 @@ def load_scene(evt: gr.SelectData, request: gr.Request):
35
  # 組合絕對路徑
36
  full_model_path = os.path.join(BASE_DIR, scene["model"])
37
 
 
38
  if not os.path.exists(full_model_path):
39
  return (
40
  "<div style='text-align:center; padding:50px; color:red'>⚠️ File not found</div>",
@@ -42,67 +45,50 @@ def load_scene(evt: gr.SelectData, request: gr.Request):
42
  f"**⚠️ Error:** File not found: {full_model_path}"
43
  )
44
 
45
- # --- 關鍵修正開始 ---
46
-
47
- # 1. 處理 Windows 路徑 (將 \ 轉為 /)
48
- # Gradio 的 file路由需要正斜線,且不能有磁碟機代號之後的雙反斜線混亂
49
- clean_path = full_model_path.replace("\\", "/")
50
 
51
- # 2. 判斷網址 (這是最容易報錯的地方)
52
- base_url = "http://127.0.0.1:7860" # 預設值
53
- is_https = False
54
 
55
  if request:
56
- host = request.headers.get("host")
57
- if "gradio.live" in host:
 
 
 
58
  base_url = f"https://{host}"
59
- is_https = True
60
  else:
61
  base_url = f"http://{host}"
62
-
63
- # 3. 組合檔案連結並進行 URL 編碼
64
- # 我們只對路徑部分進行編碼,避免空白變成無效字元
65
- # 瀏覽器看到的連結會類似: https://xxx.gradio.live/file=D:/Path/To/File.ply
66
  file_url = f"{base_url}/file={clean_path}"
67
 
68
- # file_url 再進行一次完整編碼,因為它將作為 ?url= 的參數傳遞給外部網站
69
- # 外部網站讀取時會解碼一次
 
70
  encoded_file_url = urllib.parse.quote(file_url, safe=':/')
71
 
72
- # 4. 組合外部 Viewer 連結
73
  viewer_url = f"https://antimatter15.com/splat/?url={encoded_file_url}"
74
 
75
- print(f"🔗 Base URL: {base_url}")
76
- print(f"📂 File URL: {file_url}")
77
- print(f"🚀 Final Viewer URL: {viewer_url}")
78
 
79
- # --- 關鍵修正結束 ---
80
-
81
- # 提示訊息
82
- if not is_https:
83
- status_msg = f"""
84
- ### ⚠️ 警告:無法載入 (CORS Error)
85
- 偵測到您正在使用 **Localhost (http)**。
86
- 由於安全性限制,外部 Viewer (https) 無法讀取您的本機檔案。
87
-
88
- **請解決:**
89
- 1. 查看終端機 (Terminal)。
90
- 2. 複製 **Running on public URL: https://xxxx.gradio.live** 的連結。
91
- 3. 用該連結開啟網頁,即可正常顯示。
92
- """
93
- html = f"<div style='background:#333; color:white; padding:20px; border-radius:10px;'>{status_msg}</div>"
94
- else:
95
- status_msg = f"**{scene['name']}** Loaded successfully from {base_url}"
96
- html = f"""
97
- <iframe
98
- src="{viewer_url}"
99
- width="100%"
100
- height="600px"
101
- frameborder="0"
102
- allow="camera; display-capture"
103
- style="border-radius: 8px; background: #000;"
104
- ></iframe>
105
- """
106
 
107
  return (
108
  html,
@@ -140,5 +126,11 @@ with gr.Blocks(title="RGS-SLAM Demo") as demo:
140
  )
141
 
142
  if __name__ == "__main__":
143
- # 這裡必須保留 share=True
144
- demo.launch(share=True, allowed_paths=[BASE_DIR])
 
 
 
 
 
 
 
28
 
29
  gallery_items = [(item["thumb"], item["name"]) for item in SCENES]
30
 
31
+ import urllib.parse # 確保有這一行
32
+
33
  def load_scene(evt: gr.SelectData, request: gr.Request):
34
  index = evt.index
35
  scene = SCENES[index]
 
37
  # 組合絕對路徑
38
  full_model_path = os.path.join(BASE_DIR, scene["model"])
39
 
40
+ # 1. 檢查檔案是否存在
41
  if not os.path.exists(full_model_path):
42
  return (
43
  "<div style='text-align:center; padding:50px; color:red'>⚠️ File not found</div>",
 
45
  f"**⚠️ Error:** File not found: {full_model_path}"
46
  )
47
 
48
+ # 2. 處理路徑 (Linux/HF Spaces 相容性)
49
+ # HF Spaces 是 Linux 環境,路徑通常是 /home/user/app/...
50
+ clean_path = full_model_path
 
 
51
 
52
+ # 3. 判斷網址 (這是修正的關鍵!)
53
+ # 預設值
54
+ base_url = "http://127.0.0.1:7860"
55
 
56
  if request:
57
+ host = request.headers.get("host") # 獲取網域,例如 yfyangd-rgs-slam-demo.hf.space
58
+
59
+ # --- 強制轉 HTTPS 的邏輯 ---
60
+ # 如果網址包含 'hf.space' (Hugging Face) 或 'gradio.live',強制用 https
61
+ if "hf.space" in host or "gradio.live" in host:
62
  base_url = f"https://{host}"
 
63
  else:
64
  base_url = f"http://{host}"
65
+
66
+ # 4. 組合檔案連結
 
 
67
  file_url = f"{base_url}/file={clean_path}"
68
 
69
+ # 5. 編碼網址
70
+ # 這裡很關鍵:我們要把 file_url 變成外部 viewer 看得懂的參數
71
+ # 使用 quote 將特殊符號 (如空格、=、?) 轉碼,但保留 : 和 / 以維持網址結構
72
  encoded_file_url = urllib.parse.quote(file_url, safe=':/')
73
 
74
+ # 6. 組合外部 Viewer 連結
75
  viewer_url = f"https://antimatter15.com/splat/?url={encoded_file_url}"
76
 
77
+ print(f"🚀 Final URL (Should be HTTPS): {viewer_url}")
 
 
78
 
79
+ # 7. 生成 HTML
80
+ html = f"""
81
+ <iframe
82
+ src="{viewer_url}"
83
+ width="100%"
84
+ height="600px"
85
+ frameborder="0"
86
+ allow="camera; display-capture"
87
+ style="border-radius: 8px; background: #000;"
88
+ ></iframe>
89
+ """
90
+
91
+ status_msg = f"**{scene['name']}** - Loaded from {base_url}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
 
93
  return (
94
  html,
 
126
  )
127
 
128
  if __name__ == "__main__":
129
+ # 判斷是否在 Hugging Face Spaces 上執行
130
+ # HF Spaces 會有名為 "SPACE_ID" 的環境變數
131
+ is_on_hf_spaces = "SPACE_ID" in os.environ
132
+
133
+ demo.launch(
134
+ share=not is_on_hf_spaces, # 如果在 HF Spaces 就 False,本地就 True
135
+ allowed_paths=[BASE_DIR]
136
+ )