86 lines
3.7 KiB
Python
86 lines
3.7 KiB
Python
import tkinter as tk
|
|
from tkinter import ttk
|
|
from datetime import datetime
|
|
import sounddevice as sd
|
|
import soundfile as sf
|
|
import threading
|
|
import numpy as np
|
|
from .transcription_page import TranscriptionPage
|
|
|
|
class StartPage(tk.Frame):
|
|
def __init__(self, parent, app_data):
|
|
super().__init__(parent)
|
|
self.app = parent
|
|
self.app_data = app_data
|
|
self.recording = False
|
|
self.recording_data = []
|
|
|
|
|
|
tk.Label(self, text="Lecture Summary Bot", font=self.app_data.heading_font).pack(pady=5)
|
|
self.start_page_description = tk.Label(self, text="Start by recording your lecture using selected input device.", font=self.app_data.paragraph_font, wraplength=400, justify="left")
|
|
self.start_page_description.pack(pady=5)
|
|
|
|
# Fetch all devices and filter for those with input channels
|
|
all_devices = sd.query_devices()
|
|
input_devices = {all_devices[i]['name']: i for i in range(len(all_devices)) if all_devices[i]['max_input_channels'] > 0}
|
|
|
|
# Dropdown for device selection
|
|
self.device_var = tk.StringVar()
|
|
device_names = list(input_devices.keys())
|
|
self.device_menu = ttk.Combobox(self, values=device_names, textvariable=self.device_var)
|
|
if device_names: # Automatically select the default input device if available
|
|
self.device_var.set("default")
|
|
self.device_menu.pack(pady=10)
|
|
|
|
ttk.Button(self, text="Start Recording", command=self.start_recording).pack(pady=5)
|
|
ttk.Button(self, text="Stop Recording", command=self.stop_recording).pack(pady=5)
|
|
ttk.Button(self, text="Skip Recording", command=self.skip_recording_page).pack(pady=5)
|
|
|
|
# Recording indicator
|
|
self.recording_indicator = tk.Label(self, text="Recording: OFF", fg="red")
|
|
self.recording_indicator.pack(pady=5)
|
|
|
|
def start_recording(self):
|
|
if not self.recording:
|
|
self.recording = True
|
|
self.update_recording_indicator(True)
|
|
self.recording_data = []
|
|
device_index = sd.query_devices().index(sd.query_devices(self.device_var.get()))
|
|
threading.Thread(target=self.record_audio, args=(device_index,)).start()
|
|
|
|
def stop_recording(self):
|
|
if self.recording:
|
|
self.recording = False
|
|
self.update_recording_indicator(False)
|
|
|
|
def record_audio(self, device_index):
|
|
try:
|
|
with sd.InputStream(device=device_index, samplerate=16000, channels=1, callback=self.audio_callback):
|
|
while self.recording:
|
|
sd.sleep(1000)
|
|
finally:
|
|
self.save_recording()
|
|
|
|
def audio_callback(self, indata, frames, time, status):
|
|
self.recording_data.append(indata.copy())
|
|
|
|
def save_recording(self):
|
|
date_time_str = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
self.app_data.lecture_filename = f"lecture_{date_time_str}"
|
|
audio_filepath = f"recordings/recording_{self.app_data.lecture_filename}.wav"
|
|
sf.write(audio_filepath, np.concatenate(self.recording_data, axis=0), 16000)
|
|
|
|
self.app.frames[TranscriptionPage].start_transcription_process(audio_filepath)
|
|
self.app.show_frame(TranscriptionPage)
|
|
|
|
def skip_recording_page(self):
|
|
self.app.frames[TranscriptionPage].start_transcription_process("skipped")
|
|
self.app.show_frame(TranscriptionPage)
|
|
|
|
|
|
def update_recording_indicator(self, is_recording):
|
|
#"""Update the recording indicator based on the recording state."""
|
|
if is_recording:
|
|
self.recording_indicator.config(text="Recording: ON", fg="green")
|
|
else:
|
|
self.recording_indicator.config(text="Recording: OFF", fg="red")
|