flet-audio-recorder 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of flet-audio-recorder might be problematic. Click here for more details.
- flet_audio_recorder-0.1.0/PKG-INFO +93 -0
- flet_audio_recorder-0.1.0/README.md +79 -0
- flet_audio_recorder-0.1.0/pyproject.toml +36 -0
- flet_audio_recorder-0.1.0/setup.cfg +4 -0
- flet_audio_recorder-0.1.0/src/flet_audio_recorder/__init__.py +6 -0
- flet_audio_recorder-0.1.0/src/flet_audio_recorder/audio_recorder.py +294 -0
- flet_audio_recorder-0.1.0/src/flet_audio_recorder.egg-info/PKG-INFO +93 -0
- flet_audio_recorder-0.1.0/src/flet_audio_recorder.egg-info/SOURCES.txt +19 -0
- flet_audio_recorder-0.1.0/src/flet_audio_recorder.egg-info/dependency_links.txt +1 -0
- flet_audio_recorder-0.1.0/src/flet_audio_recorder.egg-info/requires.txt +1 -0
- flet_audio_recorder-0.1.0/src/flet_audio_recorder.egg-info/top_level.txt +2 -0
- flet_audio_recorder-0.1.0/src/flutter/flet_audio_recorder/CHANGELOG.md +3 -0
- flet_audio_recorder-0.1.0/src/flutter/flet_audio_recorder/LICENSE +201 -0
- flet_audio_recorder-0.1.0/src/flutter/flet_audio_recorder/README.md +3 -0
- flet_audio_recorder-0.1.0/src/flutter/flet_audio_recorder/analysis_options.yaml +4 -0
- flet_audio_recorder-0.1.0/src/flutter/flet_audio_recorder/lib/flet_audio_recorder.dart +3 -0
- flet_audio_recorder-0.1.0/src/flutter/flet_audio_recorder/lib/src/audio_recorder.dart +165 -0
- flet_audio_recorder-0.1.0/src/flutter/flet_audio_recorder/lib/src/create_control.dart +17 -0
- flet_audio_recorder-0.1.0/src/flutter/flet_audio_recorder/lib/src/utils/audio_recorder.dart +26 -0
- flet_audio_recorder-0.1.0/src/flutter/flet_audio_recorder/pubspec.lock +799 -0
- flet_audio_recorder-0.1.0/src/flutter/flet_audio_recorder/pubspec.yaml +18 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: flet-audio-recorder
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AudioRecorder control for Flet
|
|
5
|
+
Author-email: Flet contributors <hello@flet.dev>
|
|
6
|
+
Project-URL: Homepage, https://flet.dev
|
|
7
|
+
Project-URL: Documentation, https://flet.dev/docs/controls/audiorecorder
|
|
8
|
+
Project-URL: Repository, https://github.com/flet-dev/flet-audio-recorder
|
|
9
|
+
Project-URL: Issues, https://github.com/flet-dev/flet-audio-recorder/issues
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: flet>=0.25.2
|
|
14
|
+
|
|
15
|
+
# AudioRecorder control for Flet
|
|
16
|
+
|
|
17
|
+
`AudioRecorder` control for Flet.
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
Add `flet-audio-recorder` as dependency (`pyproject.toml` or `requirements.txt`) to your Flet project.
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
|
|
25
|
+
```py
|
|
26
|
+
|
|
27
|
+
import flet as ft
|
|
28
|
+
|
|
29
|
+
import flet_audio_recorder as far
|
|
30
|
+
|
|
31
|
+
async def main(page: ft.Page):
|
|
32
|
+
page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
|
|
33
|
+
page.appbar = ft.AppBar(title=ft.Text("Audio Recorder"), center_title=True)
|
|
34
|
+
|
|
35
|
+
path = "test-audio-file.wav"
|
|
36
|
+
|
|
37
|
+
async def handle_start_recording(e):
|
|
38
|
+
print(f"StartRecording: {path}")
|
|
39
|
+
await audio_rec.start_recording_async(path)
|
|
40
|
+
|
|
41
|
+
async def handle_stop_recording(e):
|
|
42
|
+
output_path = await audio_rec.stop_recording_async()
|
|
43
|
+
print(f"StopRecording: {output_path}")
|
|
44
|
+
if page.web and output_path is not None:
|
|
45
|
+
await page.launch_url_async(output_path)
|
|
46
|
+
|
|
47
|
+
async def handle_list_devices(e):
|
|
48
|
+
devices = await audio_rec.get_input_devices_async()
|
|
49
|
+
print(devices)
|
|
50
|
+
|
|
51
|
+
async def handle_has_permission(e):
|
|
52
|
+
try:
|
|
53
|
+
print(f"HasPermission: {await audio_rec.has_permission_async()}")
|
|
54
|
+
except Exception as e:
|
|
55
|
+
print(e)
|
|
56
|
+
|
|
57
|
+
async def handle_pause(e):
|
|
58
|
+
print(f"isRecording: {await audio_rec.is_recording_async()}")
|
|
59
|
+
if await audio_rec.is_recording_async():
|
|
60
|
+
await audio_rec.pause_recording_async()
|
|
61
|
+
|
|
62
|
+
async def handle_resume(e):
|
|
63
|
+
print(f"isPaused: {await audio_rec.is_paused_async()}")
|
|
64
|
+
if await audio_rec.is_paused_async():
|
|
65
|
+
await audio_rec.resume_recording_async()
|
|
66
|
+
|
|
67
|
+
async def handle_audio_encoding_test(e):
|
|
68
|
+
for i in list(far.AudioEncoder):
|
|
69
|
+
print(f"{i}: {await audio_rec.is_supported_encoder_async(i)}")
|
|
70
|
+
|
|
71
|
+
async def handle_state_change(e):
|
|
72
|
+
print(f"State Changed: {e.data}")
|
|
73
|
+
|
|
74
|
+
audio_rec = far.AudioRecorder(
|
|
75
|
+
audio_encoder=far.AudioEncoder.WAV,
|
|
76
|
+
on_state_changed=handle_state_change,
|
|
77
|
+
)
|
|
78
|
+
page.overlay.append(audio_rec)
|
|
79
|
+
await page.update_async()
|
|
80
|
+
|
|
81
|
+
await page.add_async(
|
|
82
|
+
ft.ElevatedButton("Start Audio Recorder", on_click=handle_start_recording),
|
|
83
|
+
ft.ElevatedButton("Stop Audio Recorder", on_click=handle_stop_recording),
|
|
84
|
+
ft.ElevatedButton("List Devices", on_click=handle_list_devices),
|
|
85
|
+
ft.ElevatedButton("Pause Recording", on_click=handle_pause),
|
|
86
|
+
ft.ElevatedButton("Resume Recording", on_click=handle_resume),
|
|
87
|
+
ft.ElevatedButton("Test AudioEncodings", on_click=handle_audio_encoding_test),
|
|
88
|
+
ft.ElevatedButton("Has Permission", on_click=handle_has_permission),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
ft.app(main)
|
|
93
|
+
```
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# AudioRecorder control for Flet
|
|
2
|
+
|
|
3
|
+
`AudioRecorder` control for Flet.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Add `flet-audio-recorder` as dependency (`pyproject.toml` or `requirements.txt`) to your Flet project.
|
|
8
|
+
|
|
9
|
+
## Example
|
|
10
|
+
|
|
11
|
+
```py
|
|
12
|
+
|
|
13
|
+
import flet as ft
|
|
14
|
+
|
|
15
|
+
import flet_audio_recorder as far
|
|
16
|
+
|
|
17
|
+
async def main(page: ft.Page):
|
|
18
|
+
page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
|
|
19
|
+
page.appbar = ft.AppBar(title=ft.Text("Audio Recorder"), center_title=True)
|
|
20
|
+
|
|
21
|
+
path = "test-audio-file.wav"
|
|
22
|
+
|
|
23
|
+
async def handle_start_recording(e):
|
|
24
|
+
print(f"StartRecording: {path}")
|
|
25
|
+
await audio_rec.start_recording_async(path)
|
|
26
|
+
|
|
27
|
+
async def handle_stop_recording(e):
|
|
28
|
+
output_path = await audio_rec.stop_recording_async()
|
|
29
|
+
print(f"StopRecording: {output_path}")
|
|
30
|
+
if page.web and output_path is not None:
|
|
31
|
+
await page.launch_url_async(output_path)
|
|
32
|
+
|
|
33
|
+
async def handle_list_devices(e):
|
|
34
|
+
devices = await audio_rec.get_input_devices_async()
|
|
35
|
+
print(devices)
|
|
36
|
+
|
|
37
|
+
async def handle_has_permission(e):
|
|
38
|
+
try:
|
|
39
|
+
print(f"HasPermission: {await audio_rec.has_permission_async()}")
|
|
40
|
+
except Exception as e:
|
|
41
|
+
print(e)
|
|
42
|
+
|
|
43
|
+
async def handle_pause(e):
|
|
44
|
+
print(f"isRecording: {await audio_rec.is_recording_async()}")
|
|
45
|
+
if await audio_rec.is_recording_async():
|
|
46
|
+
await audio_rec.pause_recording_async()
|
|
47
|
+
|
|
48
|
+
async def handle_resume(e):
|
|
49
|
+
print(f"isPaused: {await audio_rec.is_paused_async()}")
|
|
50
|
+
if await audio_rec.is_paused_async():
|
|
51
|
+
await audio_rec.resume_recording_async()
|
|
52
|
+
|
|
53
|
+
async def handle_audio_encoding_test(e):
|
|
54
|
+
for i in list(far.AudioEncoder):
|
|
55
|
+
print(f"{i}: {await audio_rec.is_supported_encoder_async(i)}")
|
|
56
|
+
|
|
57
|
+
async def handle_state_change(e):
|
|
58
|
+
print(f"State Changed: {e.data}")
|
|
59
|
+
|
|
60
|
+
audio_rec = far.AudioRecorder(
|
|
61
|
+
audio_encoder=far.AudioEncoder.WAV,
|
|
62
|
+
on_state_changed=handle_state_change,
|
|
63
|
+
)
|
|
64
|
+
page.overlay.append(audio_rec)
|
|
65
|
+
await page.update_async()
|
|
66
|
+
|
|
67
|
+
await page.add_async(
|
|
68
|
+
ft.ElevatedButton("Start Audio Recorder", on_click=handle_start_recording),
|
|
69
|
+
ft.ElevatedButton("Stop Audio Recorder", on_click=handle_stop_recording),
|
|
70
|
+
ft.ElevatedButton("List Devices", on_click=handle_list_devices),
|
|
71
|
+
ft.ElevatedButton("Pause Recording", on_click=handle_pause),
|
|
72
|
+
ft.ElevatedButton("Resume Recording", on_click=handle_resume),
|
|
73
|
+
ft.ElevatedButton("Test AudioEncodings", on_click=handle_audio_encoding_test),
|
|
74
|
+
ft.ElevatedButton("Has Permission", on_click=handle_has_permission),
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
ft.app(main)
|
|
79
|
+
```
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "flet-audio-recorder"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "AudioRecorder control for Flet"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Flet contributors", email = "hello@flet.dev" }
|
|
8
|
+
]
|
|
9
|
+
classifiers = [
|
|
10
|
+
"License :: OSI Approved :: Apache Software License",
|
|
11
|
+
]
|
|
12
|
+
requires-python = ">=3.8"
|
|
13
|
+
dependencies = [
|
|
14
|
+
"flet>=0.25.2",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
[project.urls]
|
|
18
|
+
Homepage = "https://flet.dev"
|
|
19
|
+
Documentation = "https://flet.dev/docs/controls/audiorecorder"
|
|
20
|
+
Repository = "https://github.com/flet-dev/flet-audio-recorder"
|
|
21
|
+
Issues = "https://github.com/flet-dev/flet-audio-recorder/issues"
|
|
22
|
+
|
|
23
|
+
[tool.setuptools.package-data]
|
|
24
|
+
"flutter.flet_audio_recorder" = ["**/*"]
|
|
25
|
+
|
|
26
|
+
[tool.uv]
|
|
27
|
+
dev-dependencies = [
|
|
28
|
+
"flet[all]>=0.25.2",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[tool.setuptools]
|
|
32
|
+
license-files = []
|
|
33
|
+
|
|
34
|
+
[build-system]
|
|
35
|
+
requires = ["setuptools"]
|
|
36
|
+
build-backend = "setuptools.build_meta"
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
|
|
5
|
+
from flet.core.control import Control, OptionalNumber
|
|
6
|
+
from flet.core.control_event import ControlEvent
|
|
7
|
+
from flet.core.event_handler import EventHandler
|
|
8
|
+
from flet.core.ref import Ref
|
|
9
|
+
from flet.core.types import OptionalEventCallable
|
|
10
|
+
from flet.utils import deprecated
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AudioRecorderState(Enum):
|
|
14
|
+
STOPPED = "stopped"
|
|
15
|
+
RECORDING = "recording"
|
|
16
|
+
PAUSED = "paused"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AudioRecorderStateChangeEvent(ControlEvent):
|
|
20
|
+
def __init__(self, e: ControlEvent):
|
|
21
|
+
super().__init__(e.target, e.name, e.data, e.control, e.page)
|
|
22
|
+
self.state: AudioRecorderState = AudioRecorderState(e.data)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AudioEncoder(Enum):
|
|
26
|
+
AACLC = "aacLc"
|
|
27
|
+
AACELD = "aacEld"
|
|
28
|
+
AACHE = "aacHe"
|
|
29
|
+
AMRNB = "amrNb"
|
|
30
|
+
AMRWB = "amrWb"
|
|
31
|
+
OPUS = "opus"
|
|
32
|
+
FLAC = "flac"
|
|
33
|
+
WAV = "wav"
|
|
34
|
+
PCM16BITS = "pcm16bits"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class AudioRecorder(Control):
|
|
38
|
+
"""
|
|
39
|
+
A control that allows you to record audio from your device.
|
|
40
|
+
|
|
41
|
+
-----
|
|
42
|
+
|
|
43
|
+
Online docs: https://flet.dev/docs/controls/audiorecorder
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(
|
|
47
|
+
self,
|
|
48
|
+
audio_encoder: Optional[AudioEncoder] = None,
|
|
49
|
+
suppress_noise: Optional[bool] = None,
|
|
50
|
+
cancel_echo: Optional[bool] = None,
|
|
51
|
+
auto_gain: Optional[bool] = None,
|
|
52
|
+
channels_num: OptionalNumber = None,
|
|
53
|
+
sample_rate: OptionalNumber = None,
|
|
54
|
+
bit_rate: OptionalNumber = None,
|
|
55
|
+
on_state_changed: OptionalEventCallable[AudioRecorderStateChangeEvent] = None,
|
|
56
|
+
#
|
|
57
|
+
# Control
|
|
58
|
+
#
|
|
59
|
+
ref: Optional[Ref] = None,
|
|
60
|
+
data: Any = None,
|
|
61
|
+
):
|
|
62
|
+
Control.__init__(
|
|
63
|
+
self,
|
|
64
|
+
ref=ref,
|
|
65
|
+
data=data,
|
|
66
|
+
)
|
|
67
|
+
self.__on_state_changed = EventHandler(
|
|
68
|
+
lambda e: AudioRecorderStateChangeEvent(e)
|
|
69
|
+
)
|
|
70
|
+
self._add_event_handler("state_changed", self.__on_state_changed.get_handler())
|
|
71
|
+
|
|
72
|
+
self.audio_encoder = audio_encoder
|
|
73
|
+
self.suppress_noise = suppress_noise
|
|
74
|
+
self.cancel_echo = cancel_echo
|
|
75
|
+
self.auto_gain = auto_gain
|
|
76
|
+
self.channels_num = channels_num
|
|
77
|
+
self.sample_rate = sample_rate
|
|
78
|
+
self.bit_rate = bit_rate
|
|
79
|
+
self.on_state_changed = on_state_changed
|
|
80
|
+
|
|
81
|
+
def _get_control_name(self):
|
|
82
|
+
return "audiorecorder"
|
|
83
|
+
|
|
84
|
+
def start_recording(
|
|
85
|
+
self, output_path: str = None, wait_timeout: Optional[float] = 10
|
|
86
|
+
) -> bool:
|
|
87
|
+
assert (
|
|
88
|
+
self.page.web or output_path
|
|
89
|
+
), "output_path must be provided when not on web"
|
|
90
|
+
started = self.invoke_method(
|
|
91
|
+
"start_recording",
|
|
92
|
+
{"outputPath": output_path},
|
|
93
|
+
wait_for_result=True,
|
|
94
|
+
wait_timeout=wait_timeout,
|
|
95
|
+
)
|
|
96
|
+
return started == "true"
|
|
97
|
+
|
|
98
|
+
def is_recording(self, wait_timeout: Optional[float] = 5) -> bool:
|
|
99
|
+
recording = self.invoke_method(
|
|
100
|
+
"is_recording",
|
|
101
|
+
wait_for_result=True,
|
|
102
|
+
wait_timeout=wait_timeout,
|
|
103
|
+
)
|
|
104
|
+
return recording == "true"
|
|
105
|
+
|
|
106
|
+
async def is_recording_async(self, wait_timeout: Optional[float] = 5) -> bool:
|
|
107
|
+
recording = await self.invoke_method_async(
|
|
108
|
+
"is_recording",
|
|
109
|
+
wait_for_result=True,
|
|
110
|
+
wait_timeout=wait_timeout,
|
|
111
|
+
)
|
|
112
|
+
return recording == "true"
|
|
113
|
+
|
|
114
|
+
def stop_recording(self, wait_timeout: Optional[float] = 5) -> Optional[str]:
|
|
115
|
+
return self.invoke_method(
|
|
116
|
+
"stop_recording",
|
|
117
|
+
wait_for_result=True,
|
|
118
|
+
wait_timeout=wait_timeout,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
async def stop_recording_async(
|
|
122
|
+
self, wait_timeout: Optional[float] = 10
|
|
123
|
+
) -> Optional[str]:
|
|
124
|
+
return await self.invoke_method_async(
|
|
125
|
+
"stop_recording",
|
|
126
|
+
wait_for_result=True,
|
|
127
|
+
wait_timeout=wait_timeout,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
def cancel_recording(self, wait_timeout: Optional[float] = 5) -> None:
|
|
131
|
+
self.invoke_method(
|
|
132
|
+
"cancel_recording",
|
|
133
|
+
wait_for_result=True,
|
|
134
|
+
wait_timeout=wait_timeout,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
def resume_recording(self):
|
|
138
|
+
self.invoke_method("resume_recording")
|
|
139
|
+
|
|
140
|
+
def pause_recording(self):
|
|
141
|
+
self.invoke_method("pause_recording")
|
|
142
|
+
|
|
143
|
+
def is_paused(self, wait_timeout: Optional[float] = 5) -> bool:
|
|
144
|
+
paused = self.invoke_method(
|
|
145
|
+
"is_paused",
|
|
146
|
+
wait_for_result=True,
|
|
147
|
+
wait_timeout=wait_timeout,
|
|
148
|
+
)
|
|
149
|
+
return paused == "true"
|
|
150
|
+
|
|
151
|
+
async def is_paused_async(self, wait_timeout: Optional[float] = 5) -> bool:
|
|
152
|
+
supported = await self.invoke_method_async(
|
|
153
|
+
"is_paused",
|
|
154
|
+
wait_for_result=True,
|
|
155
|
+
wait_timeout=wait_timeout,
|
|
156
|
+
)
|
|
157
|
+
return supported == "true"
|
|
158
|
+
|
|
159
|
+
def is_supported_encoder(
|
|
160
|
+
self, encoder: AudioEncoder, wait_timeout: Optional[float] = 5
|
|
161
|
+
) -> bool:
|
|
162
|
+
supported = self.invoke_method(
|
|
163
|
+
"is_supported_encoder",
|
|
164
|
+
{
|
|
165
|
+
"encoder": (
|
|
166
|
+
encoder.value if isinstance(encoder, AudioEncoder) else encoder
|
|
167
|
+
)
|
|
168
|
+
},
|
|
169
|
+
wait_for_result=True,
|
|
170
|
+
wait_timeout=wait_timeout,
|
|
171
|
+
)
|
|
172
|
+
return supported == "true"
|
|
173
|
+
|
|
174
|
+
async def is_supported_encoder_async(
|
|
175
|
+
self, encoder: AudioEncoder, wait_timeout: Optional[float] = 5
|
|
176
|
+
) -> bool:
|
|
177
|
+
supported = await self.invoke_method_async(
|
|
178
|
+
"is_supported_encoder",
|
|
179
|
+
{
|
|
180
|
+
"encoder": (
|
|
181
|
+
encoder.value if isinstance(encoder, AudioEncoder) else encoder
|
|
182
|
+
)
|
|
183
|
+
},
|
|
184
|
+
wait_for_result=True,
|
|
185
|
+
wait_timeout=wait_timeout,
|
|
186
|
+
)
|
|
187
|
+
return supported == "true"
|
|
188
|
+
|
|
189
|
+
def get_input_devices(self, wait_timeout: Optional[float] = 5) -> dict:
|
|
190
|
+
devices = self.invoke_method(
|
|
191
|
+
"get_input_devices",
|
|
192
|
+
wait_for_result=True,
|
|
193
|
+
wait_timeout=wait_timeout,
|
|
194
|
+
)
|
|
195
|
+
return json.loads(devices)
|
|
196
|
+
|
|
197
|
+
async def get_input_devices_async(self, wait_timeout: Optional[float] = 5) -> dict:
|
|
198
|
+
devices = await self.invoke_method_async(
|
|
199
|
+
"get_input_devices",
|
|
200
|
+
wait_for_result=True,
|
|
201
|
+
wait_timeout=wait_timeout,
|
|
202
|
+
)
|
|
203
|
+
return json.loads(devices)
|
|
204
|
+
|
|
205
|
+
def has_permission(self, wait_timeout: Optional[float] = 10) -> bool:
|
|
206
|
+
p = self.invoke_method(
|
|
207
|
+
"has_permission",
|
|
208
|
+
wait_for_result=True,
|
|
209
|
+
wait_timeout=wait_timeout,
|
|
210
|
+
)
|
|
211
|
+
return p == "true"
|
|
212
|
+
|
|
213
|
+
async def has_permission_async(self, wait_timeout: Optional[float] = 10) -> bool:
|
|
214
|
+
p = await self.invoke_method_async(
|
|
215
|
+
"has_permission",
|
|
216
|
+
wait_for_result=True,
|
|
217
|
+
wait_timeout=wait_timeout,
|
|
218
|
+
)
|
|
219
|
+
return p == "true"
|
|
220
|
+
|
|
221
|
+
# audio_encoder
|
|
222
|
+
@property
|
|
223
|
+
def audio_encoder(self):
|
|
224
|
+
return self._get_attr("audioEncoder")
|
|
225
|
+
|
|
226
|
+
@audio_encoder.setter
|
|
227
|
+
def audio_encoder(self, value: Optional[AudioEncoder]):
|
|
228
|
+
self._set_enum_attr("audioEncoder", value, AudioEncoder)
|
|
229
|
+
|
|
230
|
+
# suppress_noise
|
|
231
|
+
@property
|
|
232
|
+
def suppress_noise(self) -> bool:
|
|
233
|
+
return self._get_attr("suppressNoise", data_type="bool", def_value=False)
|
|
234
|
+
|
|
235
|
+
@suppress_noise.setter
|
|
236
|
+
def suppress_noise(self, value: Optional[bool]):
|
|
237
|
+
self._set_attr("suppressNoise", value)
|
|
238
|
+
|
|
239
|
+
# cancel_echo
|
|
240
|
+
@property
|
|
241
|
+
def cancel_echo(self) -> bool:
|
|
242
|
+
return self._get_attr("cancelEcho", data_type="bool", def_value=False)
|
|
243
|
+
|
|
244
|
+
@cancel_echo.setter
|
|
245
|
+
def cancel_echo(self, value: Optional[bool]):
|
|
246
|
+
self._set_attr("cancelEcho", value)
|
|
247
|
+
|
|
248
|
+
# auto_gain
|
|
249
|
+
@property
|
|
250
|
+
def auto_gain(self) -> bool:
|
|
251
|
+
return self._get_attr("autoGain", data_type="bool", def_value=False)
|
|
252
|
+
|
|
253
|
+
@auto_gain.setter
|
|
254
|
+
def auto_gain(self, value: Optional[bool]):
|
|
255
|
+
self._set_attr("autoGain", value)
|
|
256
|
+
|
|
257
|
+
# bit_rate
|
|
258
|
+
@property
|
|
259
|
+
def bit_rate(self) -> OptionalNumber:
|
|
260
|
+
return self._get_attr("bitRate")
|
|
261
|
+
|
|
262
|
+
@bit_rate.setter
|
|
263
|
+
def bit_rate(self, value: OptionalNumber):
|
|
264
|
+
self._set_attr("bitRate", value)
|
|
265
|
+
|
|
266
|
+
# sample_rate
|
|
267
|
+
@property
|
|
268
|
+
def sample_rate(self) -> OptionalNumber:
|
|
269
|
+
return self._get_attr("sampleRate")
|
|
270
|
+
|
|
271
|
+
@sample_rate.setter
|
|
272
|
+
def sample_rate(self, value: OptionalNumber):
|
|
273
|
+
self._set_attr("sampleRate", value)
|
|
274
|
+
|
|
275
|
+
# channels_num
|
|
276
|
+
@property
|
|
277
|
+
def channels_num(self) -> OptionalNumber:
|
|
278
|
+
return self._get_attr("channels")
|
|
279
|
+
|
|
280
|
+
@channels_num.setter
|
|
281
|
+
def channels_num(self, value: OptionalNumber):
|
|
282
|
+
if value is None or value in (1, 2):
|
|
283
|
+
self._set_attr("channels", value)
|
|
284
|
+
|
|
285
|
+
# on_state_changed
|
|
286
|
+
@property
|
|
287
|
+
def on_state_changed(self):
|
|
288
|
+
return self.__on_state_changed.handler
|
|
289
|
+
|
|
290
|
+
@on_state_changed.setter
|
|
291
|
+
def on_state_changed(
|
|
292
|
+
self, handler: OptionalEventCallable[AudioRecorderStateChangeEvent]
|
|
293
|
+
):
|
|
294
|
+
self.__on_state_changed.handler = handler
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: flet-audio-recorder
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: AudioRecorder control for Flet
|
|
5
|
+
Author-email: Flet contributors <hello@flet.dev>
|
|
6
|
+
Project-URL: Homepage, https://flet.dev
|
|
7
|
+
Project-URL: Documentation, https://flet.dev/docs/controls/audiorecorder
|
|
8
|
+
Project-URL: Repository, https://github.com/flet-dev/flet-audio-recorder
|
|
9
|
+
Project-URL: Issues, https://github.com/flet-dev/flet-audio-recorder/issues
|
|
10
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: flet>=0.25.2
|
|
14
|
+
|
|
15
|
+
# AudioRecorder control for Flet
|
|
16
|
+
|
|
17
|
+
`AudioRecorder` control for Flet.
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
Add `flet-audio-recorder` as dependency (`pyproject.toml` or `requirements.txt`) to your Flet project.
|
|
22
|
+
|
|
23
|
+
## Example
|
|
24
|
+
|
|
25
|
+
```py
|
|
26
|
+
|
|
27
|
+
import flet as ft
|
|
28
|
+
|
|
29
|
+
import flet_audio_recorder as far
|
|
30
|
+
|
|
31
|
+
async def main(page: ft.Page):
|
|
32
|
+
page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
|
|
33
|
+
page.appbar = ft.AppBar(title=ft.Text("Audio Recorder"), center_title=True)
|
|
34
|
+
|
|
35
|
+
path = "test-audio-file.wav"
|
|
36
|
+
|
|
37
|
+
async def handle_start_recording(e):
|
|
38
|
+
print(f"StartRecording: {path}")
|
|
39
|
+
await audio_rec.start_recording_async(path)
|
|
40
|
+
|
|
41
|
+
async def handle_stop_recording(e):
|
|
42
|
+
output_path = await audio_rec.stop_recording_async()
|
|
43
|
+
print(f"StopRecording: {output_path}")
|
|
44
|
+
if page.web and output_path is not None:
|
|
45
|
+
await page.launch_url_async(output_path)
|
|
46
|
+
|
|
47
|
+
async def handle_list_devices(e):
|
|
48
|
+
devices = await audio_rec.get_input_devices_async()
|
|
49
|
+
print(devices)
|
|
50
|
+
|
|
51
|
+
async def handle_has_permission(e):
|
|
52
|
+
try:
|
|
53
|
+
print(f"HasPermission: {await audio_rec.has_permission_async()}")
|
|
54
|
+
except Exception as e:
|
|
55
|
+
print(e)
|
|
56
|
+
|
|
57
|
+
async def handle_pause(e):
|
|
58
|
+
print(f"isRecording: {await audio_rec.is_recording_async()}")
|
|
59
|
+
if await audio_rec.is_recording_async():
|
|
60
|
+
await audio_rec.pause_recording_async()
|
|
61
|
+
|
|
62
|
+
async def handle_resume(e):
|
|
63
|
+
print(f"isPaused: {await audio_rec.is_paused_async()}")
|
|
64
|
+
if await audio_rec.is_paused_async():
|
|
65
|
+
await audio_rec.resume_recording_async()
|
|
66
|
+
|
|
67
|
+
async def handle_audio_encoding_test(e):
|
|
68
|
+
for i in list(far.AudioEncoder):
|
|
69
|
+
print(f"{i}: {await audio_rec.is_supported_encoder_async(i)}")
|
|
70
|
+
|
|
71
|
+
async def handle_state_change(e):
|
|
72
|
+
print(f"State Changed: {e.data}")
|
|
73
|
+
|
|
74
|
+
audio_rec = far.AudioRecorder(
|
|
75
|
+
audio_encoder=far.AudioEncoder.WAV,
|
|
76
|
+
on_state_changed=handle_state_change,
|
|
77
|
+
)
|
|
78
|
+
page.overlay.append(audio_rec)
|
|
79
|
+
await page.update_async()
|
|
80
|
+
|
|
81
|
+
await page.add_async(
|
|
82
|
+
ft.ElevatedButton("Start Audio Recorder", on_click=handle_start_recording),
|
|
83
|
+
ft.ElevatedButton("Stop Audio Recorder", on_click=handle_stop_recording),
|
|
84
|
+
ft.ElevatedButton("List Devices", on_click=handle_list_devices),
|
|
85
|
+
ft.ElevatedButton("Pause Recording", on_click=handle_pause),
|
|
86
|
+
ft.ElevatedButton("Resume Recording", on_click=handle_resume),
|
|
87
|
+
ft.ElevatedButton("Test AudioEncodings", on_click=handle_audio_encoding_test),
|
|
88
|
+
ft.ElevatedButton("Has Permission", on_click=handle_has_permission),
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
ft.app(main)
|
|
93
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/flet_audio_recorder/__init__.py
|
|
4
|
+
src/flet_audio_recorder/audio_recorder.py
|
|
5
|
+
src/flet_audio_recorder.egg-info/PKG-INFO
|
|
6
|
+
src/flet_audio_recorder.egg-info/SOURCES.txt
|
|
7
|
+
src/flet_audio_recorder.egg-info/dependency_links.txt
|
|
8
|
+
src/flet_audio_recorder.egg-info/requires.txt
|
|
9
|
+
src/flet_audio_recorder.egg-info/top_level.txt
|
|
10
|
+
src/flutter/flet_audio_recorder/CHANGELOG.md
|
|
11
|
+
src/flutter/flet_audio_recorder/LICENSE
|
|
12
|
+
src/flutter/flet_audio_recorder/README.md
|
|
13
|
+
src/flutter/flet_audio_recorder/analysis_options.yaml
|
|
14
|
+
src/flutter/flet_audio_recorder/pubspec.lock
|
|
15
|
+
src/flutter/flet_audio_recorder/pubspec.yaml
|
|
16
|
+
src/flutter/flet_audio_recorder/lib/flet_audio_recorder.dart
|
|
17
|
+
src/flutter/flet_audio_recorder/lib/src/audio_recorder.dart
|
|
18
|
+
src/flutter/flet_audio_recorder/lib/src/create_control.dart
|
|
19
|
+
src/flutter/flet_audio_recorder/lib/src/utils/audio_recorder.dart
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
flet>=0.25.2
|