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
112
113
114
115
116
117
|
from pathlib import Path
from contextlib import contextmanager
from asyncio import sleep
from tempfile import TemporaryDirectory
from datetime import date
from re import sub
from nicegui import ui, run
from slugify import slugify
_recording = None
def _removeParens(string):
return sub(r'\(.*?\)', '', string).strip()
@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, getCurrentSong):
async def f():
with ui.dialog() as dialog, ui.card():
defaultName = f"{slugify(_removeParens(getCurrentSong()))}.mp3"
fileName = ui.input(label='File name', value=defaultName)
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, getCurrentSong):
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, getCurrentSong))
|