roots / app.py
haepada's picture
Update app.py
9d47e7f verified
raw
history blame
6.18 kB
import gradio as gr
import numpy as np
import librosa
from transformers import pipeline
from datetime import datetime
import os
# 전역 변수 설정
SAMPLE_RATE = 16000 # 샘플링 레이트 고정
N_MELS = 64 # mel 필터 수 조정
# AI 모델 초기화
text_analyzer = pipeline("sentiment-analysis", model="nlptown/bert-base-multilingual-uncased-sentiment")
def create_interface():
with gr.Blocks(theme=gr.themes.Soft()) as app:
# 상태 변수
state = gr.State({
"reflections": [],
"user_name": "",
"analyses": []
})
# 헤더
header = gr.Markdown("# 디지털 굿판")
user_display = gr.Markdown("")
with gr.Tabs() as tabs:
# 입장 탭
with gr.Tab("입장") as intro_tab:
gr.Markdown("""
# 디지털 굿판에 오신 것을 환영합니다
온천천의 디지털 치유 공간으로 들어가보세요.
""")
name_input = gr.Textbox(label="이름을 알려주세요")
start_btn = gr.Button("여정 시작하기")
# 청신 탭
with gr.Tab("청신") as cleansing_tab:
with gr.Row():
# 음악 플레이어
audio = gr.Audio(
value="assets/main_music.mp3",
type="filepath",
label="온천천의 소리",
interactive=True
)
with gr.Column():
reflection_input = gr.Textbox(
label="현재 순간의 감상을 적어주세요",
lines=3
)
save_btn = gr.Button("감상 저장하기")
reflections_display = gr.Dataframe(
headers=["시간", "감상", "감정"],
label="기록된 감상들"
)
# 기원 탭
with gr.Tab("기원") as prayer_tab:
with gr.Row():
voice_input = gr.Audio(
label="나누고 싶은 이야기를 들려주세요",
sources=["microphone"],
type="filepath"
)
with gr.Column():
text_output = gr.Textbox(label="인식된 텍스트")
emotion_output = gr.Textbox(label="감정 분석")
audio_features = gr.JSON(label="음성 특성 분석")
# 송신 탭
with gr.Tab("송신") as sharing_tab:
prompt_display = gr.Textbox(label="생성된 프롬프트")
gallery = gr.Gallery(label="시각화 결과")
# 함수 정의
def start_journey(name):
"""여정 시작"""
if name.strip():
welcome_text = f"# 환영합니다, {name}님"
return welcome_text, gr.update(selected="청신")
return "이름을 입력해주세요", gr.update(selected="입장")
def save_reflection(text, state_data):
"""감상 저장"""
if not text.strip():
return state_data, []
try:
current_time = datetime.now().strftime("%H:%M:%S")
sentiment = text_analyzer(text)[0]
new_reflection = [current_time, text, sentiment["label"]]
if "reflections" not in state_data:
state_data["reflections"] = []
state_data["reflections"].append(new_reflection)
return state_data, state_data["reflections"]
except Exception as e:
print(f"Error in save_reflection: {str(e)}")
return state_data, []
def analyze_voice(audio_path, state_data):
"""음성 분석"""
if audio_path is None:
return None, None, None, state_data
try:
# 오디오 로드 및 리샘플링
y, sr = librosa.load(audio_path, sr=SAMPLE_RATE)
# 기본 특성 추출
features = {
"energy": float(np.mean(librosa.feature.rms(y=y))),
"tempo": float(librosa.beat.tempo(y)[0]),
"zero_crossing_rate": float(np.mean(librosa.feature.zero_crossing_rate(y)))
}
# MFCC 계산 (파라미터 조정)
mfccs = librosa.feature.mfcc(
y=y,
sr=sr,
n_mfcc=13,
n_mels=N_MELS
)
features["mfcc_mean"] = np.mean(mfccs, axis=1).tolist()
return (
"음성이 성공적으로 분석되었습니다.", # 텍스트 출력
f"에너지: {features['energy']:.2f}\n템포: {features['tempo']:.2f}", # 감정 출력
features, # JSON 출력
state_data # 상태 업데이트
)
except Exception as e:
print(f"Error in analyze_voice: {str(e)}")
return f"오류 발생: {str(e)}", None, None, state_data
# 이벤트 연결
start_btn.click(
fn=start_journey,
inputs=[name_input],
outputs=[user_display, tabs]
)
save_btn.click(
fn=save_reflection,
inputs=[reflection_input, state],
outputs=[state, reflections_display]
)
voice_input.change(
fn=analyze_voice,
inputs=[voice_input, state],
outputs=[text_output, emotion_output, audio_features, state]
)
return app
# 앱 실행
if __name__ == "__main__":
demo = create_interface()
demo.launch()