Update app.py
Browse files
app.py
CHANGED
@@ -617,37 +617,40 @@ def create_interface():
|
|
617 |
# HTML5 Audio Player 템플릿
|
618 |
AUDIO_PLAYER_HTML = """
|
619 |
<div class="audio-player-container">
|
620 |
-
<audio id="mainAudio" preload="auto">
|
621 |
-
<source src="/assets/main_music.mp3" type="audio/mpeg">
|
622 |
-
Your browser does not support the audio element.
|
623 |
</audio>
|
624 |
-
<button id="playButton" onclick="
|
625 |
<span id="playButtonText">재생</span>
|
626 |
</button>
|
627 |
</div>
|
628 |
<script>
|
629 |
-
let
|
|
|
630 |
let playButtonText = document.getElementById('playButtonText');
|
631 |
-
let isPlaying = false;
|
632 |
|
633 |
-
function
|
634 |
-
if (
|
635 |
-
|
636 |
-
audioElement.play()
|
637 |
-
.then(() => {
|
638 |
-
isPlaying = true;
|
639 |
playButtonText.textContent = '일시정지';
|
640 |
-
})
|
641 |
-
|
642 |
-
|
643 |
-
alert("음악 재생에 실패했습니다. 다시 시도해주세요.");
|
644 |
});
|
645 |
} else {
|
646 |
-
|
647 |
-
isPlaying = false;
|
648 |
playButtonText.textContent = '재생';
|
649 |
}
|
650 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
651 |
</script>
|
652 |
<style>
|
653 |
.audio-player-container {
|
@@ -842,8 +845,8 @@ def create_interface():
|
|
842 |
type="numpy",
|
843 |
streaming=False
|
844 |
)
|
|
|
845 |
set_baseline_btn = gr.Button("축원 마치기", variant="primary")
|
846 |
-
baseline_status = gr.Markdown("")
|
847 |
|
848 |
# 4단계: 굿판 입장 안내
|
849 |
entry_guide_section = gr.Column(visible=False)
|
@@ -998,13 +1001,27 @@ def create_interface():
|
|
998 |
return state, "음성을 먼저 녹음해주세요.", gr.update(visible=True), gr.update(visible=False)
|
999 |
|
1000 |
try:
|
1001 |
-
#
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1008 |
except Exception as e:
|
1009 |
return state, f"오류가 발생했습니다: {str(e)}", gr.update(visible=True), gr.update(visible=False)
|
1010 |
|
@@ -1074,26 +1091,13 @@ def create_interface():
|
|
1074 |
# DB에 저장
|
1075 |
db.save_reflection(name, text, sentiment_text)
|
1076 |
|
1077 |
-
#
|
1078 |
-
|
1079 |
-
all_reflections = db.get_all_reflections()
|
1080 |
-
for ref in all_reflections:
|
1081 |
-
display_data.append([
|
1082 |
-
ref["timestamp"],
|
1083 |
-
ref["reflection"],
|
1084 |
-
ref["sentiment"]
|
1085 |
-
])
|
1086 |
-
|
1087 |
-
# 상태 업데이트
|
1088 |
-
state = safe_state_update(state, {"reflections": display_data})
|
1089 |
|
1090 |
-
return state, display_data
|
1091 |
-
|
1092 |
except Exception as e:
|
1093 |
print(f"Error saving reflection: {e}")
|
1094 |
return state, []
|
1095 |
|
1096 |
-
|
1097 |
def handle_save_wish(text, state):
|
1098 |
if not text.strip():
|
1099 |
return "소원을 입력해주세요.", []
|
@@ -1113,23 +1117,26 @@ def create_interface():
|
|
1113 |
|
1114 |
def safe_analyze_voice(audio_data, state):
|
1115 |
if audio_data is None:
|
1116 |
-
return state, "음성을 먼저 녹음해주세요.", "", "", "",
|
1117 |
-
|
1118 |
try:
|
1119 |
-
|
|
|
1120 |
|
1121 |
-
# 음성 데이터 전처리
|
1122 |
sr, y = audio_data
|
1123 |
if len(y) == 0:
|
1124 |
-
return state, "음성이 감지되지 않았습니다.", "", "", "",
|
1125 |
|
|
|
|
|
|
|
|
|
1126 |
result = analyze_voice(audio_data, state)
|
1127 |
-
if result[1] == "음성 인식 실패":
|
1128 |
-
return state, "음성 인식에 실패했습니다. 다시 시도해주세요.", "", "", "", gr.update(visible=False)
|
1129 |
-
|
1130 |
-
processing_status.update(visible=False)
|
1131 |
-
return result
|
1132 |
|
|
|
|
|
|
|
1133 |
except Exception as e:
|
1134 |
print(f"Voice analysis error: {str(e)}")
|
1135 |
return (
|
@@ -1138,9 +1145,8 @@ def create_interface():
|
|
1138 |
"",
|
1139 |
"",
|
1140 |
"",
|
1141 |
-
|
1142 |
)
|
1143 |
-
|
1144 |
|
1145 |
# 이벤트 연결
|
1146 |
name_submit_btn.click(
|
|
|
617 |
# HTML5 Audio Player 템플릿
|
618 |
AUDIO_PLAYER_HTML = """
|
619 |
<div class="audio-player-container">
|
620 |
+
<audio id="mainAudio" preload="auto" style="display:none;">
|
621 |
+
<source src="file/assets/main_music.mp3" type="audio/mpeg">
|
|
|
622 |
</audio>
|
623 |
+
<button id="playButton" onclick="toggleAudio()" class="custom-audio-button">
|
624 |
<span id="playButtonText">재생</span>
|
625 |
</button>
|
626 |
</div>
|
627 |
<script>
|
628 |
+
let audio = document.getElementById('mainAudio');
|
629 |
+
let playButton = document.getElementById('playButton');
|
630 |
let playButtonText = document.getElementById('playButtonText');
|
|
|
631 |
|
632 |
+
function toggleAudio() {
|
633 |
+
if (audio.paused) {
|
634 |
+
audio.play().then(() => {
|
|
|
|
|
|
|
635 |
playButtonText.textContent = '일시정지';
|
636 |
+
}).catch(error => {
|
637 |
+
console.error('Audio playback failed:', error);
|
638 |
+
alert('음악 재생에 실패했습니다. 다시 시도해주세요.');
|
|
|
639 |
});
|
640 |
} else {
|
641 |
+
audio.pause();
|
|
|
642 |
playButtonText.textContent = '재생';
|
643 |
}
|
644 |
}
|
645 |
+
|
646 |
+
audio.addEventListener('ended', () => {
|
647 |
+
playButtonText.textContent = '재생';
|
648 |
+
});
|
649 |
+
|
650 |
+
audio.addEventListener('error', (e) => {
|
651 |
+
console.error('Audio error:', e);
|
652 |
+
alert('음악 파일을 불러오는데 실패했습니다.');
|
653 |
+
});
|
654 |
</script>
|
655 |
<style>
|
656 |
.audio-player-container {
|
|
|
845 |
type="numpy",
|
846 |
streaming=False
|
847 |
)
|
848 |
+
blessing_status = gr.Markdown("", elem_id="blessing-status") # 상태 표시 추가
|
849 |
set_baseline_btn = gr.Button("축원 마치기", variant="primary")
|
|
|
850 |
|
851 |
# 4단계: 굿판 입장 안내
|
852 |
entry_guide_section = gr.Column(visible=False)
|
|
|
1001 |
return state, "음성을 먼저 녹음해주세요.", gr.update(visible=True), gr.update(visible=False)
|
1002 |
|
1003 |
try:
|
1004 |
+
# 상태 표시
|
1005 |
+
status_msg = "축원 분석 중..."
|
1006 |
+
|
1007 |
+
# 음성 분석 수행
|
1008 |
+
sr, y = audio
|
1009 |
+
features = calculate_baseline_features((sr, y))
|
1010 |
+
|
1011 |
+
if features:
|
1012 |
+
state = safe_state_update(state, {
|
1013 |
+
"baseline_features": features
|
1014 |
+
})
|
1015 |
+
status_msg = "축원이 완료되었습니다."
|
1016 |
+
return (
|
1017 |
+
state,
|
1018 |
+
status_msg,
|
1019 |
+
gr.update(visible=False),
|
1020 |
+
gr.update(visible=True)
|
1021 |
+
)
|
1022 |
+
|
1023 |
+
return state, "축원 분석에 실패했습니다.", gr.update(visible=True), gr.update(visible=False)
|
1024 |
+
|
1025 |
except Exception as e:
|
1026 |
return state, f"오류가 발생했습니다: {str(e)}", gr.update(visible=True), gr.update(visible=False)
|
1027 |
|
|
|
1091 |
# DB에 저장
|
1092 |
db.save_reflection(name, text, sentiment_text)
|
1093 |
|
1094 |
+
# 현재 사용자의 감상만 표시
|
1095 |
+
return state, [[current_time, text, sentiment_text]]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1096 |
|
|
|
|
|
1097 |
except Exception as e:
|
1098 |
print(f"Error saving reflection: {e}")
|
1099 |
return state, []
|
1100 |
|
|
|
1101 |
def handle_save_wish(text, state):
|
1102 |
if not text.strip():
|
1103 |
return "소원을 입력해주세요.", []
|
|
|
1117 |
|
1118 |
def safe_analyze_voice(audio_data, state):
|
1119 |
if audio_data is None:
|
1120 |
+
return state, "음성을 먼저 녹음해주세요.", "", "", "", "분석 준비 중..."
|
1121 |
+
|
1122 |
try:
|
1123 |
+
# 상태 업데이트
|
1124 |
+
status_msg = "음성 분석 중..."
|
1125 |
|
1126 |
+
# 음성 데이터 전처리
|
1127 |
sr, y = audio_data
|
1128 |
if len(y) == 0:
|
1129 |
+
return state, "음성이 감지되지 않았습니다.", "", "", "", "분석 실패"
|
1130 |
|
1131 |
+
status_msg = "음성 특성 분석 중..."
|
1132 |
+
acoustic_features = calculate_baseline_features((sr, y))
|
1133 |
+
|
1134 |
+
status_msg = "음성 인식 중..."
|
1135 |
result = analyze_voice(audio_data, state)
|
|
|
|
|
|
|
|
|
|
|
1136 |
|
1137 |
+
status_msg = "분석 완료"
|
1138 |
+
return (*result[:-1], status_msg) # 마지막 상태 메시지 추가
|
1139 |
+
|
1140 |
except Exception as e:
|
1141 |
print(f"Voice analysis error: {str(e)}")
|
1142 |
return (
|
|
|
1145 |
"",
|
1146 |
"",
|
1147 |
"",
|
1148 |
+
"분석 실패"
|
1149 |
)
|
|
|
1150 |
|
1151 |
# 이벤트 연결
|
1152 |
name_submit_btn.click(
|