Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -714,7 +714,7 @@ def generate_docx(data: dict, output_path: str) -> str:
|
|
| 714 |
def process_audio(audio_file):
|
| 715 |
"""Main function to process audio and generate Word document."""
|
| 716 |
if audio_file is None:
|
| 717 |
-
return None, "Please upload an audio file.", None
|
| 718 |
|
| 719 |
api_key = os.environ.get("GEMINI_API_KEY")
|
| 720 |
if not api_key:
|
|
@@ -750,6 +750,48 @@ def process_audio(audio_file):
|
|
| 750 |
except Exception as e:
|
| 751 |
return None, f"Error: {str(e)}", None
|
| 752 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 753 |
# ============================================================================
|
| 754 |
# GRADIO INTERFACE
|
| 755 |
# ============================================================================
|
|
@@ -767,35 +809,66 @@ custom_theme = gr.themes.Base(
|
|
| 767 |
block_title_text_color="#111827",
|
| 768 |
)
|
| 769 |
|
| 770 |
-
with gr.Blocks(title="Advance Care Planning"
|
| 771 |
gr.Markdown("""
|
| 772 |
# Advance Care Planning
|
| 773 |
|
| 774 |
-
|
| 775 |
""")
|
| 776 |
|
| 777 |
-
with gr.
|
| 778 |
-
with gr.
|
| 779 |
-
|
| 780 |
-
|
| 781 |
-
|
| 782 |
-
|
| 783 |
-
)
|
| 784 |
|
| 785 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 786 |
|
| 787 |
-
with gr.
|
| 788 |
-
|
| 789 |
-
|
| 790 |
-
|
| 791 |
-
|
| 792 |
-
|
| 793 |
-
|
| 794 |
-
|
| 795 |
-
|
| 796 |
-
|
| 797 |
-
|
| 798 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 799 |
|
| 800 |
gr.Markdown("""
|
| 801 |
---
|
|
@@ -805,4 +878,4 @@ with gr.Blocks(title="Advance Care Planning", theme=custom_theme) as demo:
|
|
| 805 |
""")
|
| 806 |
|
| 807 |
if __name__ == "__main__":
|
| 808 |
-
demo.launch()
|
|
|
|
| 714 |
def process_audio(audio_file):
|
| 715 |
"""Main function to process audio and generate Word document."""
|
| 716 |
if audio_file is None:
|
| 717 |
+
return None, "Please record or upload an audio file.", None
|
| 718 |
|
| 719 |
api_key = os.environ.get("GEMINI_API_KEY")
|
| 720 |
if not api_key:
|
|
|
|
| 750 |
except Exception as e:
|
| 751 |
return None, f"Error: {str(e)}", None
|
| 752 |
|
| 753 |
+
|
| 754 |
+
def on_recording_stop(audio_data):
|
| 755 |
+
"""
|
| 756 |
+
Called when recording stops. Automatically triggers processing.
|
| 757 |
+
audio_data is a tuple of (sample_rate, audio_array) from microphone recording.
|
| 758 |
+
"""
|
| 759 |
+
if audio_data is None:
|
| 760 |
+
return None, "No audio recorded.", None
|
| 761 |
+
|
| 762 |
+
# Save the recorded audio to a temporary file
|
| 763 |
+
import numpy as np
|
| 764 |
+
from scipy.io import wavfile
|
| 765 |
+
|
| 766 |
+
sample_rate, audio_array = audio_data
|
| 767 |
+
|
| 768 |
+
# Create temporary wav file
|
| 769 |
+
temp_dir = tempfile.gettempdir()
|
| 770 |
+
temp_path = os.path.join(temp_dir, f"recording_{int(time.time())}.wav")
|
| 771 |
+
|
| 772 |
+
# Ensure audio is in the right format
|
| 773 |
+
if audio_array.dtype != np.int16:
|
| 774 |
+
# Normalize and convert to int16
|
| 775 |
+
if audio_array.dtype == np.float32 or audio_array.dtype == np.float64:
|
| 776 |
+
audio_array = (audio_array * 32767).astype(np.int16)
|
| 777 |
+
else:
|
| 778 |
+
audio_array = audio_array.astype(np.int16)
|
| 779 |
+
|
| 780 |
+
wavfile.write(temp_path, sample_rate, audio_array)
|
| 781 |
+
|
| 782 |
+
# Process the audio
|
| 783 |
+
docx_file, status, json_data = process_audio(temp_path)
|
| 784 |
+
|
| 785 |
+
return docx_file, status, json_data
|
| 786 |
+
|
| 787 |
+
|
| 788 |
+
def process_uploaded_file(audio_file):
|
| 789 |
+
"""Process an uploaded audio file."""
|
| 790 |
+
if audio_file is None:
|
| 791 |
+
return None, "Please upload an audio file.", None
|
| 792 |
+
|
| 793 |
+
return process_audio(audio_file)
|
| 794 |
+
|
| 795 |
# ============================================================================
|
| 796 |
# GRADIO INTERFACE
|
| 797 |
# ============================================================================
|
|
|
|
| 809 |
block_title_text_color="#111827",
|
| 810 |
)
|
| 811 |
|
| 812 |
+
with gr.Blocks(title="Advance Care Planning") as demo:
|
| 813 |
gr.Markdown("""
|
| 814 |
# Advance Care Planning
|
| 815 |
|
| 816 |
+
Record or upload an audio conversation to generate a structured Word document summary report.
|
| 817 |
""")
|
| 818 |
|
| 819 |
+
with gr.Tabs():
|
| 820 |
+
with gr.TabItem("Record Audio"):
|
| 821 |
+
gr.Markdown("""
|
| 822 |
+
**Instructions:** Click the microphone button to start recording. Click again to stop.
|
| 823 |
+
The recording will be automatically analyzed when you stop.
|
| 824 |
+
""")
|
|
|
|
| 825 |
|
| 826 |
+
with gr.Row():
|
| 827 |
+
with gr.Column(scale=1):
|
| 828 |
+
audio_recorder = gr.Audio(
|
| 829 |
+
label="Recording",
|
| 830 |
+
sources=["microphone"],
|
| 831 |
+
type="numpy",
|
| 832 |
+
interactive=True
|
| 833 |
+
)
|
| 834 |
+
|
| 835 |
+
with gr.Column(scale=1):
|
| 836 |
+
record_status = gr.Textbox(label="Status", interactive=False)
|
| 837 |
+
record_docx_output = gr.File(label="Download Word Document")
|
| 838 |
+
|
| 839 |
+
with gr.Accordion("View Extracted Data (JSON)", open=False):
|
| 840 |
+
record_json_output = gr.Code(label="Extracted Data", language="json")
|
| 841 |
+
|
| 842 |
+
# Auto-process when recording stops
|
| 843 |
+
audio_recorder.stop_recording(
|
| 844 |
+
fn=on_recording_stop,
|
| 845 |
+
inputs=[audio_recorder],
|
| 846 |
+
outputs=[record_docx_output, record_status, record_json_output]
|
| 847 |
+
)
|
| 848 |
|
| 849 |
+
with gr.TabItem("Upload Audio"):
|
| 850 |
+
with gr.Row():
|
| 851 |
+
with gr.Column(scale=1):
|
| 852 |
+
audio_upload = gr.Audio(
|
| 853 |
+
label="Upload Audio Recording",
|
| 854 |
+
type="filepath",
|
| 855 |
+
sources=["upload"]
|
| 856 |
+
)
|
| 857 |
+
|
| 858 |
+
upload_btn = gr.Button("Analyze & Generate Word Doc", variant="primary")
|
| 859 |
+
|
| 860 |
+
with gr.Column(scale=1):
|
| 861 |
+
upload_status = gr.Textbox(label="Status", interactive=False)
|
| 862 |
+
upload_docx_output = gr.File(label="Download Word Document")
|
| 863 |
+
|
| 864 |
+
with gr.Accordion("View Extracted Data (JSON)", open=False):
|
| 865 |
+
upload_json_output = gr.Code(label="Extracted Data", language="json")
|
| 866 |
+
|
| 867 |
+
upload_btn.click(
|
| 868 |
+
fn=process_uploaded_file,
|
| 869 |
+
inputs=[audio_upload],
|
| 870 |
+
outputs=[upload_docx_output, upload_status, upload_json_output]
|
| 871 |
+
)
|
| 872 |
|
| 873 |
gr.Markdown("""
|
| 874 |
---
|
|
|
|
| 878 |
""")
|
| 879 |
|
| 880 |
if __name__ == "__main__":
|
| 881 |
+
demo.launch(theme=custom_theme)
|