picard47at commited on
Commit
2c52bed
·
1 Parent(s): 7a73eb6

Initial commit: Voice recorder app

Browse files
Files changed (5) hide show
  1. DEPLOY.md +113 -0
  2. README.md +32 -5
  3. app.py +202 -0
  4. requirements.txt +3 -0
  5. run_local.sh +38 -0
DEPLOY.md ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 部署到 Hugging Face Spaces
2
+
3
+ ## 方法一:使用 Git 推送
4
+
5
+ ### 1. 創建新的 Space
6
+
7
+ 1. 前往 https://huggingface.co/spaces
8
+ 2. 點擊 "Create new Space"
9
+ 3. 填寫以下資訊:
10
+ - **Space name**: `voice-recorder`(或你喜歡的名字)
11
+ - **License**: MIT
12
+ - **SDK**: Gradio
13
+ - **Visibility**: Public 或 Private
14
+
15
+ ### 2. 克隆 Space 倉庫
16
+
17
+ ```bash
18
+ # 替換為你的 username 和 space name
19
+ git clone https://huggingface.co/spaces/YOUR_USERNAME/YOUR_SPACE_NAME
20
+ cd YOUR_SPACE_NAME
21
+ ```
22
+
23
+ ### 3. 複製文件
24
+
25
+ ```bash
26
+ # 將本地文件複製到 space 目錄
27
+ cp /home/picard/voicerecord/app.py .
28
+ cp /home/picard/voicerecord/requirements.txt .
29
+ cp /home/picard/voicerecord/README.md .
30
+ ```
31
+
32
+ ### 4. 推送代碼
33
+
34
+ ```bash
35
+ git add .
36
+ git commit -m "Initial commit: Voice recorder app"
37
+ git push
38
+ ```
39
+
40
+ ### 5. 等待部署
41
+
42
+ Hugging Face 會自動部署你的應用,通常需要 1-2 分鐘。
43
+ 部署完成後,你可以在 Space 頁面看到應用程式。
44
+
45
+ ---
46
+
47
+ ## 方法二:直接上傳文件
48
+
49
+ 1. 前往你的 Space 頁面
50
+ 2. 點擊 "Files" 標籤
51
+ 3. 點擊 "Add file" → "Upload files"
52
+ 4. 上傳以下文件:
53
+ - `app.py`
54
+ - `requirements.txt`
55
+ - `README.md`
56
+ 5. 點擊 "Commit changes to main"
57
+
58
+ ---
59
+
60
+ ## 本地測試
61
+
62
+ 在部署之前,建議先在本地測試:
63
+
64
+ ```bash
65
+ cd /home/picard/voicerecord
66
+ bash run_local.sh
67
+ ```
68
+
69
+ 然後在瀏覽器中開啟:http://localhost:7860
70
+
71
+ ---
72
+
73
+ ## 使用說明
74
+
75
+ ### 在 Hugging Face Spaces 上
76
+
77
+ 1. 開啟你的 Space 頁面
78
+ 2. 點擊 "🔴 開始錄音" 按鈕
79
+ 3. 允許瀏覽器使用麥克風
80
+ 4. 對著麥克風說話
81
+ 5. 點擊 "⏹️ 停止錄音" 按鈕
82
+ 6. 點擊 "💾 保存錄音" 按鈕
83
+ 7. 錄音將保存為 16kHz WAV 文件
84
+ 8. 點擊音頻播放器右側的下載按鈕可下載文件
85
+
86
+ ### 注意事項
87
+
88
+ - **麥克風權限**:首次使用時需要授權麥克風權限
89
+ - **瀏覽器相容性**:建议使用 Chrome、Firefox 或 Edge
90
+ - **錄音長度**:建議每段錄音不超過 60 秒
91
+ - **文件格式**:所有錄音都保存為 16kHz 單聲道 WAV 格式
92
+
93
+ ---
94
+
95
+ ## 疑難排解
96
+
97
+ ### 麥克風無法使用
98
+
99
+ 1. 檢查瀏覽器是否已授權麥克風權限
100
+ 2. 檢查系統麥克風設定
101
+ 3. 嘗試使用 HTTPS(Hugging Face Spaces 預設使用 HTTPS)
102
+
103
+ ### 應用無法載入
104
+
105
+ 1. 檢查 `requirements.txt` 是否包含所有依賴
106
+ 2. 查看 Space 的 "Logs" 標籤查看錯誤訊息
107
+ 3. 確保 `app.py` 沒有語法錯誤
108
+
109
+ ### 音頻質量問題
110
+
111
+ - 確保錄音環境安靜
112
+ - 麥克風距離嘴巴約 10-20 公分
113
+ - 避免對著麥克風吹氣
README.md CHANGED
@@ -1,13 +1,40 @@
1
  ---
2
- title: Voicerecord
3
- emoji:
4
  colorFrom: blue
5
- colorTo: indigo
6
  sdk: gradio
7
- sdk_version: 6.9.0
8
  app_file: app.py
9
  pinned: false
10
  license: mit
11
  ---
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: 語音錄音器
3
+ emoji: 🎤
4
  colorFrom: blue
5
+ colorTo: purple
6
  sdk: gradio
7
+ sdk_version: 4.44.0
8
  app_file: app.py
9
  pinned: false
10
  license: mit
11
  ---
12
 
13
+ # 語音錄音器
14
+
15
+ 從麥克風錄音並保存為 16kHz WAV 文件的 Gradio 應用程式。
16
+
17
+ ## 使用方式
18
+
19
+ 1. 點擊 **🔴 開始錄音** 按鈕
20
+ 2. 對著麥克風說話
21
+ 3. 點擊 **⏹️ 停止錄音** 按鈕
22
+ 4. 點擊 **💾 保存錄音** 按鈕保存文件
23
+
24
+ ## 設定
25
+
26
+ - 採樣率:16000 Hz
27
+ - 格式:WAV
28
+ - 聲道:單聲道
29
+ - 位元深度:16-bit
30
+
31
+ ## 本地運行
32
+
33
+ ```bash
34
+ pip install -r requirements.txt
35
+ python app.py
36
+ ```
37
+
38
+ ## 授權
39
+
40
+ MIT License
app.py ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ 語音錄音應用程式
5
+ 部署在 Hugging Face Spaces 上,從麥克風錄音並保存為 16kHz WAV 文件
6
+
7
+ Usage:
8
+ python app.py
9
+ """
10
+
11
+ import gradio as gr
12
+ import numpy as np
13
+ import wave
14
+ import os
15
+ from datetime import datetime
16
+ from pathlib import Path
17
+
18
+ # 設定
19
+ SAMPLE_RATE = 16000 # 16kHz
20
+ OUTPUT_DIR = "recordings" # 錄音保存目錄
21
+
22
+ # 確保輸出目錄存在
23
+ os.makedirs(OUTPUT_DIR, exist_ok=True)
24
+
25
+
26
+ def save_audio(audio_data: np.ndarray, sr: int) -> str:
27
+ """
28
+ 將音頻數據保存為 WAV 文件
29
+
30
+ Args:
31
+ audio_data: 音頻數據 (numpy array)
32
+ sr: 採樣率
33
+
34
+ Returns:
35
+ 保存的文件路徑
36
+ """
37
+ # 生成文件名
38
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
39
+ filename = f"recording_{timestamp}.wav"
40
+ filepath = os.path.join(OUTPUT_DIR, filename)
41
+
42
+ # 確保是單聲道
43
+ if len(audio_data.shape) > 1:
44
+ audio_data = audio_data.mean(axis=1)
45
+
46
+ # 歸一化到 16-bit 範圍
47
+ audio_int16 = (audio_data * 32767).astype(np.int16)
48
+
49
+ # 保存為 WAV
50
+ with wave.open(filepath, 'w') as wav_file:
51
+ wav_file.setnchannels(1) # 單聲道
52
+ wav_file.setsampwidth(2) # 2 bytes (16-bit)
53
+ wav_file.setframerate(sr)
54
+ wav_file.writeframes(audio_int16.tobytes())
55
+
56
+ return filepath
57
+
58
+
59
+ def process_recording(audio_tuple):
60
+ """
61
+ 處理錄音並保存
62
+
63
+ Args:
64
+ audio_tuple: (sampling_rate, audio_data) 元組
65
+
66
+ Returns:
67
+ 保存的文件路徑和狀態訊息
68
+ """
69
+ if audio_tuple is None:
70
+ return None, "❌ 沒有錄音數據"
71
+
72
+ sr, audio_data = audio_tuple
73
+
74
+ # 如果採樣率不是 16kHz,需要重採樣
75
+ if sr != SAMPLE_RATE:
76
+ # 使用 librosa 重採樣
77
+ try:
78
+ import librosa
79
+ audio_data = librosa.resample(audio_data, orig_sr=sr, target_sr=SAMPLE_RATE)
80
+ sr = SAMPLE_RATE
81
+ except ImportError:
82
+ # 如果沒有 librosa,使用簡單的降採樣
83
+ ratio = SAMPLE_RATE / sr
84
+ new_length = int(len(audio_data) * ratio)
85
+ audio_data = np.interp(
86
+ np.linspace(0, len(audio_data), new_length),
87
+ np.arange(len(audio_data)),
88
+ audio_data
89
+ )
90
+ sr = SAMPLE_RATE
91
+
92
+ # 保存文件
93
+ filepath = save_audio(audio_data, sr)
94
+
95
+ # 計算錄音長度
96
+ duration = len(audio_data) / sr
97
+
98
+ return filepath, f"✅ 已保存:{filepath}\n📊 長度:{duration:.2f}秒 | 採樣率:{sr}Hz"
99
+
100
+
101
+ def create_demo():
102
+ """創建 Gradio 介面"""
103
+
104
+ with gr.Blocks(title="語音錄音器") as demo:
105
+ gr.Markdown("""
106
+ # 🎤 語音錄音器
107
+
108
+ 按下「開始錄音」按鈕開始錄音,再次按下「停止錄音」按鈕停止並保存。
109
+ 錄音將保存為 16kHz 採樣率的 WAV 文件。
110
+ """)
111
+
112
+ with gr.Row():
113
+ with gr.Column(scale=1):
114
+ gr.Markdown("### 📝 錄音說明")
115
+ gr.Markdown("""
116
+ 1. 點擊 **🔴 開始錄音** 按鈕
117
+ 2. 對著麥克風說話
118
+ 3. 點擊 **⏹️ 停止錄音** 按鈕
119
+ 4. 錄音將自動保存為 WAV 文件
120
+ """)
121
+
122
+ gr.Markdown("### ⚙️ 設定")
123
+ gr.Markdown(f"""
124
+ - 採樣率:**{SAMPLE_RATE} Hz**
125
+ - 格式:**WAV**
126
+ - 聲道:**單聲道**
127
+ - 位元深度:**16-bit**
128
+ """)
129
+
130
+ with gr.Column(scale=2):
131
+ # 錄音組件
132
+ audio_input = gr.Audio(
133
+ label="🎤 錄音",
134
+ sources=["microphone"],
135
+ type="numpy",
136
+ waveform_options=gr.WaveformOptions(
137
+ sample_rate=SAMPLE_RATE,
138
+ ),
139
+ )
140
+
141
+ # 狀態顯示
142
+ status_text = gr.Textbox(
143
+ label="📋 狀態",
144
+ placeholder="等待錄音...",
145
+ interactive=False,
146
+ )
147
+
148
+ # 保存的文件顯示
149
+ audio_output = gr.Audio(
150
+ label="📁 已保存的錄音",
151
+ type="filepath",
152
+ interactive=False,
153
+ )
154
+
155
+ # 按鈕
156
+ with gr.Row():
157
+ save_btn = gr.Button(
158
+ "💾 保存錄音",
159
+ variant="primary",
160
+ size="lg",
161
+ )
162
+ clear_btn = gr.Button(
163
+ "🗑️ 清除",
164
+ variant="secondary",
165
+ size="lg",
166
+ )
167
+
168
+ # 錄音說明
169
+ gr.Markdown("""
170
+ ---
171
+ ### 💡 使用提示
172
+
173
+ - **錄音時**:請確保瀏覽器已授權麥克風權限
174
+ - **停止錄音**:錄音完成後點擊「保存錄音」按鈕
175
+ - **文件位置**:錄音保存在 `recordings/` 目錄下
176
+ - **下載**:點擊音頻播放器右側的下載按鈕可下載文件
177
+ """)
178
+
179
+ # 事件處理
180
+ save_btn.click(
181
+ fn=process_recording,
182
+ inputs=[audio_input],
183
+ outputs=[audio_output, status_text],
184
+ )
185
+
186
+ clear_btn.click(
187
+ fn=lambda: (None, "🗑️ 已清除"),
188
+ inputs=[],
189
+ outputs=[audio_input, status_text],
190
+ )
191
+
192
+ return demo
193
+
194
+
195
+ if __name__ == "__main__":
196
+ # 創建並啟動應用
197
+ demo = create_demo()
198
+ demo.launch(
199
+ server_name="0.0.0.0",
200
+ server_port=7860,
201
+ share=False, # 設為 True 可創建公開分享連結
202
+ )
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio>=4.0.0
2
+ numpy>=1.24.0
3
+ librosa>=0.10.0
run_local.sh ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # =============================================================
3
+ # 語音錄音器 - 本地測試腳本
4
+ # =============================================================
5
+ set -e
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ cd "$SCRIPT_DIR"
9
+
10
+ echo "=========================================="
11
+ echo "語音錄音器 - 本地測試"
12
+ echo "=========================================="
13
+ echo ""
14
+
15
+ # 檢查虛擬環境
16
+ PYTHON="/home/picard/venv/bin/python"
17
+
18
+ if [ ! -f "$PYTHON" ]; then
19
+ echo "錯誤:虛擬環境未找到:$PYTHON"
20
+ exit 1
21
+ fi
22
+
23
+ # 安裝依賴
24
+ echo "安裝依賴..."
25
+ $PYTHON -m pip install -q -r requirements.txt
26
+
27
+ echo ""
28
+ echo "=========================================="
29
+ echo "啟動應用..."
30
+ echo "=========================================="
31
+ echo ""
32
+ echo "瀏覽器開啟:http://localhost:7860"
33
+ echo ""
34
+ echo "按 Ctrl+C 停止服務"
35
+ echo ""
36
+
37
+ # 啟動應用
38
+ exec $PYTHON app.py