aboutsummaryrefslogtreecommitdiffstats
path: root/web-project/src/recording.py
diff options
context:
space:
mode:
authorEddy Pedroni <epedroni@pm.me>2026-01-01 17:57:27 +0100
committerEddy Pedroni <epedroni@pm.me>2026-01-01 17:57:27 +0100
commit8ea2b64ff798af913dcba64baace8d2536bf0b18 (patch)
treef85ea2f371055e67c629909df4897aec2f4bbad2 /web-project/src/recording.py
parent88ce99d87889cdf953af611ef09d7a12b6d23747 (diff)
Add Android app wrapper around web interface
Diffstat (limited to 'web-project/src/recording.py')
-rw-r--r--web-project/src/recording.py111
1 files changed, 111 insertions, 0 deletions
diff --git a/web-project/src/recording.py b/web-project/src/recording.py
new file mode 100644
index 0000000..2afd567
--- /dev/null
+++ b/web-project/src/recording.py
@@ -0,0 +1,111 @@
+from pathlib import Path
+from contextlib import contextmanager
+from asyncio import sleep
+from tempfile import TemporaryDirectory
+from datetime import date
+
+from nicegui import ui, run
+
+_recording = None
+
+@contextmanager
+def _disable(button: ui.button):
+ button.disable()
+ try:
+ yield
+ finally:
+ button.enable()
+
+async def _stopRecording(recordButton, uploadButton, recorder, wavFile):
+ with _disable(recordButton):
+ global _recording
+ _recording = recorder.stopRecording()
+ await run.cpu_bound(_recording.writeWav, wavFile)
+ uploadButton.enable()
+
+def _makeRecordCallback(playButton, recordButton, uploadButton, soloTool, recorder, wavFile):
+ async def f():
+ if recorder.recording:
+ await _stopRecording(recordButton, uploadButton, recorder, wavFile)
+ else:
+ if soloTool.playingAdHoc:
+ soloTool.backToNormal()
+ uploadButton.disable()
+ recorder.startRecording()
+ playButton.enable()
+ return f
+
+def _makePlayCallback(playButton, recordButton, uploadButton, soloTool, recorder, wavFile):
+ async def f():
+ with _disable(playButton):
+ if recorder.recording:
+ await _stopRecording(recordButton, uploadButton, recorder, wavFile)
+
+ if soloTool.playingAdHoc:
+ soloTool.backToNormal()
+ else:
+ soloTool.playAdHoc(wavFile)
+ soloTool.play()
+ return f
+
+def _makeUploadCallback(playButton, recordButton, uploadButton, tempDir, sessionManager):
+ async def f():
+ with ui.dialog() as dialog, ui.card():
+ fileName = ui.input(label='File name', value="jam.mp3")
+ with ui.row():
+ ui.button('Upload', color='positive', on_click=lambda: dialog.submit(fileName.value))
+ ui.button('Cancel', color='negative' ,on_click=lambda: dialog.submit(None))
+
+ fileName = await dialog
+ if fileName is None:
+ return
+
+ playButton.disable()
+ recordButton.disable()
+ uploadButton.disable()
+
+ def on_dismiss():
+ playButton.enable()
+ recordButton.enable()
+ uploadButton.enable()
+ n = ui.notification(timeout=None, position='bottom-right', type='ongoing', spinner=True, on_dismiss=on_dismiss, icon='check')
+
+ n.message = f'Converting to .mp3...'
+ mp3File = Path(tempDir.name) / fileName
+ await run.cpu_bound(_recording.writeMp3, mp3File)
+
+ n.message = 'Uploading...'
+ folderName = date.today().isoformat()
+ try:
+ await run.io_bound(sessionManager.saveRecording, mp3File, f"{folderName}/{fileName}")
+ except:
+ n.spinner = False
+ n.icon = 'error'
+ n.message = 'Upload failed!'
+ n.close_button = 'Close'
+ return
+
+ n.spinner = False
+ n.message = 'Done!'
+ await sleep(2)
+ n.dismiss()
+ return f
+
+def recordingControls(soloTool, recorder, sessionManager):
+ tempDir = TemporaryDirectory(prefix="solotool-")
+ wavFile = Path(tempDir.name) / "st_recording.wav"
+
+ with ui.button_group().classes('').style('height: 40px'):
+ recordButton = ui.button(icon='fiber_manual_record', color='negative') \
+ .bind_icon_from(recorder, 'recording', lambda recording: 'radio_button_unchecked' if recording else 'fiber_manual_record')
+
+ playButton = ui.button(icon='hearing') \
+ .bind_icon_from(soloTool, 'playingAdHoc', lambda adHoc: 'close' if adHoc else 'hearing')
+ playButton.disable()
+
+ uploadButton = ui.button(icon='cloud_upload')
+ uploadButton.disable()
+
+ recordButton.on_click(_makeRecordCallback(playButton, recordButton, uploadButton, soloTool, recorder, wavFile))
+ playButton.on_click(_makePlayCallback(playButton, recordButton, uploadButton, soloTool, recorder, wavFile))
+ uploadButton.on_click(_makeUploadCallback(playButton, recordButton, uploadButton, tempDir, sessionManager))