aboutsummaryrefslogtreecommitdiffstats
path: root/web-project/src/recording.py
blob: 2afd567a59d25e24c623e1ac7d64a850084c6e4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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))