flet-audio 0.1.0.dev3__py3-none-any.whl → 0.2.0.dev35__py3-none-any.whl
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.
- flet_audio/__init__.py +2 -2
- flet_audio/audio.py +249 -271
- flet_audio/types.py +69 -0
- flet_audio-0.2.0.dev35.dist-info/METADATA +66 -0
- flet_audio-0.2.0.dev35.dist-info/RECORD +18 -0
- {flet_audio-0.1.0.dev3.dist-info → flet_audio-0.2.0.dev35.dist-info}/WHEEL +1 -1
- flet_audio-0.2.0.dev35.dist-info/licenses/LICENSE +201 -0
- flutter/flet_audio/lib/flet_audio.dart +1 -1
- flutter/flet_audio/lib/src/audio.dart +125 -194
- flutter/flet_audio/lib/src/extension.dart +15 -0
- flutter/flet_audio/lib/src/utils/audio.dart +9 -0
- flutter/flet_audio/pubspec.lock +161 -136
- flutter/flet_audio/pubspec.yaml +8 -3
- flet_audio-0.1.0.dev3.dist-info/METADATA +0 -43
- flet_audio-0.1.0.dev3.dist-info/RECORD +0 -15
- flutter/flet_audio/lib/src/create_control.dart +0 -20
- {flet_audio-0.1.0.dev3.dist-info → flet_audio-0.2.0.dev35.dist-info}/top_level.txt +0 -0
flet_audio/__init__.py
CHANGED
flet_audio/audio.py
CHANGED
|
@@ -1,294 +1,272 @@
|
|
|
1
|
-
|
|
2
|
-
from typing import
|
|
1
|
+
import asyncio
|
|
2
|
+
from typing import Optional
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
from flet.core.control_event import ControlEvent
|
|
6
|
-
from flet.core.event_handler import EventHandler
|
|
7
|
-
from flet.core.ref import Ref
|
|
8
|
-
from flet.core.types import OptionalControlEventCallable, OptionalEventCallable
|
|
9
|
-
from flet.utils import deprecated
|
|
4
|
+
import flet as ft
|
|
10
5
|
|
|
6
|
+
from .types import (
|
|
7
|
+
AudioDurationChangeEvent,
|
|
8
|
+
AudioPositionChangeEvent,
|
|
9
|
+
AudioStateChangeEvent,
|
|
10
|
+
ReleaseMode,
|
|
11
|
+
)
|
|
11
12
|
|
|
12
|
-
class ReleaseMode(Enum):
|
|
13
|
-
RELEASE = "release"
|
|
14
|
-
LOOP = "loop"
|
|
15
|
-
STOP = "stop"
|
|
16
13
|
|
|
14
|
+
@ft.control("Audio")
|
|
15
|
+
class Audio(ft.Service):
|
|
16
|
+
"""
|
|
17
|
+
A control to simultaneously play multiple audio sources.
|
|
18
|
+
|
|
19
|
+
Raises:
|
|
20
|
+
AssertionError: If both [`src`][(c).] and [`src_base64`][(c).] are `None`.
|
|
21
|
+
|
|
22
|
+
Note:
|
|
23
|
+
This control is non-visual and should be added to `Page.services` list before it can be used.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
src: Optional[str] = None
|
|
27
|
+
"""
|
|
28
|
+
The audio source. Can be a URL or a local [asset file](https://flet.dev/docs/cookbook/assets).
|
|
29
|
+
|
|
30
|
+
Note:
|
|
31
|
+
- At least one of `src` or [`src_base64`][..] must be provided,
|
|
32
|
+
with `src_base64` having priority if both are provided.
|
|
33
|
+
- [Here](https://github.com/bluefireteam/audioplayers/blob/main/troubleshooting.md#supported-formats--encodings)
|
|
34
|
+
is a list of supported audio formats.
|
|
35
|
+
"""
|
|
17
36
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
37
|
+
src_base64: Optional[str] = None
|
|
38
|
+
"""
|
|
39
|
+
Sets the contents of audio file encoded in base-64 format.
|
|
40
|
+
|
|
41
|
+
Note:
|
|
42
|
+
- At least one of [`src`][..] or `src_base64` must be provided,
|
|
43
|
+
with `src_base64` having priority if both are provided.
|
|
44
|
+
- [Here](https://github.com/bluefireteam/audioplayers/blob/main/troubleshooting.md#supported-formats--encodings)
|
|
45
|
+
is a list of supported audio formats.
|
|
46
|
+
"""
|
|
24
47
|
|
|
48
|
+
autoplay: bool = False
|
|
49
|
+
"""
|
|
50
|
+
Starts playing audio as soon as audio control is added to a page.
|
|
51
|
+
|
|
52
|
+
Note:
|
|
53
|
+
Autoplay works in desktop, mobile apps and Safari browser, but doesn't work in Chrome/Edge.
|
|
54
|
+
"""
|
|
25
55
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
56
|
+
volume: ft.Number = 1.0
|
|
57
|
+
"""
|
|
58
|
+
Sets the volume (amplitude).
|
|
59
|
+
It's value ranges between `0.0` (mute) and `1.0` (maximum volume).
|
|
60
|
+
Intermediate values are linearly interpolated.
|
|
61
|
+
"""
|
|
30
62
|
|
|
63
|
+
balance: ft.Number = 0.0
|
|
64
|
+
"""
|
|
65
|
+
Sets the stereo balance.
|
|
31
66
|
|
|
32
|
-
class AudioPositionChangeEvent(ControlEvent):
|
|
33
|
-
def __init__(self, e: ControlEvent):
|
|
34
|
-
super().__init__(e.target, e.name, e.data, e.control, e.page)
|
|
35
|
-
self.position: int = int(e.data)
|
|
36
67
|
|
|
68
|
+
* `-1` - The left channel is at full volume; the right channel is silent.
|
|
69
|
+
* `1` - The right channel is at full volume; the left channel is silent.
|
|
70
|
+
* `0` - Both channels are at the same volume.
|
|
71
|
+
"""
|
|
37
72
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
73
|
+
playback_rate: ft.Number = 1.0
|
|
74
|
+
"""
|
|
75
|
+
Sets the playback rate.
|
|
76
|
+
|
|
77
|
+
Should ideally be set when creating the constructor.
|
|
78
|
+
|
|
79
|
+
Note:
|
|
80
|
+
- iOS and macOS have limits between `0.5x` and `2x`.
|
|
81
|
+
- Android SDK version should be 23 or higher.
|
|
82
|
+
"""
|
|
42
83
|
|
|
84
|
+
release_mode: ReleaseMode = ReleaseMode.RELEASE
|
|
85
|
+
"""
|
|
86
|
+
Sets the release mode.
|
|
87
|
+
"""
|
|
43
88
|
|
|
44
|
-
|
|
89
|
+
on_loaded: ft.OptionalControlEventHandler["Audio"] = None
|
|
90
|
+
"""
|
|
91
|
+
Fires when an audio is loaded/buffered.
|
|
45
92
|
"""
|
|
46
|
-
A control to simultaneously play multiple audio files. Works on macOS, Linux, Windows, iOS, Android and web. Based on audioplayers Flutter widget (https://pub.dev/packages/audioplayers).
|
|
47
93
|
|
|
48
|
-
Audio
|
|
94
|
+
on_duration_change: ft.OptionalEventHandler[AudioDurationChangeEvent["Audio"]] = None
|
|
95
|
+
"""
|
|
96
|
+
Fires as soon as audio duration is available (it might take a while to download or buffer it).
|
|
49
97
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
import flet as ft
|
|
98
|
+
Event handler argument is of type [`AudioDurationChangeEvent`][(p).].
|
|
99
|
+
"""
|
|
53
100
|
|
|
54
|
-
|
|
101
|
+
on_state_change: ft.OptionalEventHandler[AudioStateChangeEvent["Audio"]] = None
|
|
102
|
+
"""
|
|
103
|
+
Fires when audio player state changes.
|
|
55
104
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
src="https://luan.xyz/files/audio/ambient_c_motion.mp3", autoplay=True
|
|
59
|
-
)
|
|
60
|
-
page.overlay.append(audio1)
|
|
61
|
-
page.add(
|
|
62
|
-
ft.Text("This is an app with background audio."),
|
|
63
|
-
ft.ElevatedButton("Stop playing", on_click=lambda _: audio1.pause()),
|
|
64
|
-
)
|
|
105
|
+
Event handler argument is of type [`AudioStateChangeEvent`][(p).].
|
|
106
|
+
"""
|
|
65
107
|
|
|
66
|
-
ft.
|
|
67
|
-
|
|
108
|
+
on_position_change: ft.OptionalEventHandler[AudioPositionChangeEvent["Audio"]] = None
|
|
109
|
+
"""
|
|
110
|
+
Fires when audio position is changed.
|
|
111
|
+
Will continuously update the position of the playback every 1 second if the status is playing.
|
|
112
|
+
|
|
113
|
+
Can be used for a progress bar.
|
|
68
114
|
|
|
69
|
-
|
|
115
|
+
Event handler argument is of type [`AudioPositionChangeEvent`][(p).].
|
|
116
|
+
"""
|
|
70
117
|
|
|
71
|
-
|
|
118
|
+
on_seek_complete: ft.OptionalControlEventHandler["Audio"] = None
|
|
119
|
+
"""
|
|
120
|
+
Fires on seek completions.
|
|
121
|
+
An event is going to be sent as soon as the audio seek is finished.
|
|
72
122
|
"""
|
|
73
123
|
|
|
74
|
-
def
|
|
75
|
-
|
|
76
|
-
src
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
self.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
self.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
self.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
self
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
def
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
def balance(self, value: OptionalNumber):
|
|
224
|
-
if value is None or (-1 <= value <= 1):
|
|
225
|
-
self._set_attr("balance", value)
|
|
226
|
-
|
|
227
|
-
# playback_rate
|
|
228
|
-
@property
|
|
229
|
-
def playback_rate(self) -> OptionalNumber:
|
|
230
|
-
return self._get_attr("playbackRate")
|
|
231
|
-
|
|
232
|
-
@playback_rate.setter
|
|
233
|
-
def playback_rate(self, value: OptionalNumber):
|
|
234
|
-
if value is None or (0 <= value <= 2):
|
|
235
|
-
self._set_attr("playbackRate", value)
|
|
236
|
-
|
|
237
|
-
# release_mode
|
|
238
|
-
@property
|
|
239
|
-
def release_mode(self):
|
|
240
|
-
return self._get_attr("releaseMode")
|
|
241
|
-
|
|
242
|
-
@release_mode.setter
|
|
243
|
-
def release_mode(self, value: Optional[ReleaseMode]):
|
|
244
|
-
self._set_enum_attr("releaseMode", value, ReleaseMode)
|
|
245
|
-
|
|
246
|
-
# on_loaded
|
|
247
|
-
@property
|
|
248
|
-
def on_loaded(self):
|
|
249
|
-
return self._get_event_handler("loaded")
|
|
250
|
-
|
|
251
|
-
@on_loaded.setter
|
|
252
|
-
def on_loaded(self, handler: OptionalControlEventCallable):
|
|
253
|
-
self._add_event_handler("loaded", handler)
|
|
254
|
-
|
|
255
|
-
# on_duration_changed
|
|
256
|
-
@property
|
|
257
|
-
def on_duration_changed(self):
|
|
258
|
-
return self.__on_duration_changed.handler
|
|
259
|
-
|
|
260
|
-
@on_duration_changed.setter
|
|
261
|
-
def on_duration_changed(
|
|
262
|
-
self, handler: OptionalEventCallable[AudioDurationChangeEvent]
|
|
263
|
-
):
|
|
264
|
-
self.__on_duration_changed.handler = handler
|
|
265
|
-
|
|
266
|
-
# on_state_changed
|
|
267
|
-
@property
|
|
268
|
-
def on_state_changed(self):
|
|
269
|
-
return self.__on_state_changed.handler
|
|
270
|
-
|
|
271
|
-
@on_state_changed.setter
|
|
272
|
-
def on_state_changed(self, handler: OptionalEventCallable[AudioStateChangeEvent]):
|
|
273
|
-
self.__on_state_changed.handler = handler
|
|
274
|
-
|
|
275
|
-
# on_position_changed
|
|
276
|
-
@property
|
|
277
|
-
def on_position_changed(self):
|
|
278
|
-
return self.__on_position_changed.handler
|
|
279
|
-
|
|
280
|
-
@on_position_changed.setter
|
|
281
|
-
def on_position_changed(
|
|
282
|
-
self, handler: OptionalEventCallable[AudioPositionChangeEvent]
|
|
283
|
-
):
|
|
284
|
-
self.__on_position_changed.handler = handler
|
|
285
|
-
self._set_attr("onPositionChanged", True if handler is not None else None)
|
|
286
|
-
|
|
287
|
-
# on_seek_complete
|
|
288
|
-
@property
|
|
289
|
-
def on_seek_complete(self):
|
|
290
|
-
return self._get_event_handler("seek_complete")
|
|
291
|
-
|
|
292
|
-
@on_seek_complete.setter
|
|
293
|
-
def on_seek_complete(self, handler: OptionalControlEventCallable):
|
|
294
|
-
self._add_event_handler("seek_complete", handler)
|
|
124
|
+
def before_update(self):
|
|
125
|
+
super().before_update()
|
|
126
|
+
assert self.src or self.src_base64, "either src or src_base64 must be provided"
|
|
127
|
+
|
|
128
|
+
async def play_async(self, position: ft.DurationValue = ft.Duration(), timeout: Optional[float] = 10):
|
|
129
|
+
"""
|
|
130
|
+
Starts playing audio from the specified `position`.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
position: The position to start playback from.
|
|
134
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
135
|
+
Raises:
|
|
136
|
+
TimeoutError: If the request times out.
|
|
137
|
+
"""
|
|
138
|
+
await self._invoke_method_async("play", {"position": position}, timeout=timeout)
|
|
139
|
+
|
|
140
|
+
def play(self, position: ft.DurationValue = ft.Duration(), timeout: Optional[float] = 10):
|
|
141
|
+
"""
|
|
142
|
+
Starts playing audio from the specified `position`.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
position: The position to start playback from.
|
|
146
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
147
|
+
Raises:
|
|
148
|
+
TimeoutError: If the request times out.
|
|
149
|
+
"""
|
|
150
|
+
asyncio.create_task(self.play_async(position, timeout=timeout))
|
|
151
|
+
|
|
152
|
+
async def pause_async(self, timeout: Optional[float] = 10):
|
|
153
|
+
"""
|
|
154
|
+
Pauses the audio that is currently playing.
|
|
155
|
+
|
|
156
|
+
If you call [`resume()`][.resume] or [`resume_async()`][.resume_async] later,
|
|
157
|
+
the audio will resume from the point that it has been paused.
|
|
158
|
+
"""
|
|
159
|
+
await self._invoke_method_async("pause", timeout=timeout)
|
|
160
|
+
|
|
161
|
+
def pause(self, timeout: Optional[float] = 10):
|
|
162
|
+
"""
|
|
163
|
+
Pauses the audio that is currently playing.
|
|
164
|
+
|
|
165
|
+
If you call [`resume()`][.resume] or [`resume_async()`][.resume_async] later,
|
|
166
|
+
the audio will resume from the point that it has been paused.
|
|
167
|
+
|
|
168
|
+
Args:
|
|
169
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
170
|
+
Raises:
|
|
171
|
+
TimeoutError: If the request times out.
|
|
172
|
+
"""
|
|
173
|
+
asyncio.create_task(self.pause_async(timeout=timeout))
|
|
174
|
+
|
|
175
|
+
async def resume_async(self, timeout: Optional[float] = 10):
|
|
176
|
+
"""
|
|
177
|
+
Resumes the audio that has been paused or stopped.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
181
|
+
Raises:
|
|
182
|
+
TimeoutError: If the request times out.
|
|
183
|
+
"""
|
|
184
|
+
await self._invoke_method_async("resume", timeout=timeout)
|
|
185
|
+
|
|
186
|
+
def resume(self, timeout: Optional[float] = 10):
|
|
187
|
+
"""
|
|
188
|
+
Resumes the audio that has been paused or stopped.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
192
|
+
Raises:
|
|
193
|
+
TimeoutError: If the request times out.
|
|
194
|
+
"""
|
|
195
|
+
asyncio.create_task(self.resume_async(timeout=timeout))
|
|
196
|
+
|
|
197
|
+
async def release_async(self, timeout: Optional[float] = 10):
|
|
198
|
+
"""
|
|
199
|
+
Releases the resources associated with this media player.
|
|
200
|
+
These are going to be fetched or buffered again as soon as
|
|
201
|
+
you change the source or call [`resume()`][.resume] or [`resume_async()`][.resume_async].
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
205
|
+
Raises:
|
|
206
|
+
TimeoutError: If the request times out.
|
|
207
|
+
"""
|
|
208
|
+
await self._invoke_method_async("release", timeout=timeout)
|
|
209
|
+
|
|
210
|
+
def release(self, timeout: Optional[float] = 10):
|
|
211
|
+
"""
|
|
212
|
+
Releases the resources associated with this media player.
|
|
213
|
+
These are going to be fetched or buffered again as soon as
|
|
214
|
+
you change the source or call [`resume()`][.resume] or [`resume_async()`][.resume_async].
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
218
|
+
Raises:
|
|
219
|
+
TimeoutError: If the request times out.
|
|
220
|
+
"""
|
|
221
|
+
asyncio.create_task(self.release_async(timeout=timeout))
|
|
222
|
+
|
|
223
|
+
async def seek_async(self, position: ft.DurationValue, timeout: Optional[float] = 10):
|
|
224
|
+
"""
|
|
225
|
+
Moves the cursor to the desired position.
|
|
226
|
+
|
|
227
|
+
Args:
|
|
228
|
+
position: The position to seek/move to.
|
|
229
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
230
|
+
Raises:
|
|
231
|
+
TimeoutError: If the request times out.
|
|
232
|
+
"""
|
|
233
|
+
await self._invoke_method_async("seek", {"position": position}, timeout=timeout)
|
|
234
|
+
|
|
235
|
+
def seek(self, position: ft.DurationValue, timeout: Optional[float] = 10):
|
|
236
|
+
"""
|
|
237
|
+
Moves the cursor to the desired position.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
position: The position to seek/move to.
|
|
241
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
242
|
+
Raises:
|
|
243
|
+
TimeoutError: If the request times out.
|
|
244
|
+
"""
|
|
245
|
+
asyncio.create_task(self.seek_async(position, timeout=timeout))
|
|
246
|
+
|
|
247
|
+
async def get_duration_async(self, timeout: Optional[float] = 10) -> Optional[ft.Duration]:
|
|
248
|
+
"""
|
|
249
|
+
Get audio duration of the audio playback.
|
|
250
|
+
|
|
251
|
+
It will be available as soon as the audio duration is available
|
|
252
|
+
(it might take a while to download or buffer it if file is not local).
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
256
|
+
Returns:
|
|
257
|
+
The duration of audio playback.
|
|
258
|
+
Raises:
|
|
259
|
+
TimeoutError: If the request times out.
|
|
260
|
+
"""
|
|
261
|
+
return await self._invoke_method_async("get_duration", timeout=timeout)
|
|
262
|
+
|
|
263
|
+
async def get_current_position_async(self, timeout: Optional[float] = 10) -> Optional[ft.Duration]:
|
|
264
|
+
"""
|
|
265
|
+
Get the current position of the audio playback.
|
|
266
|
+
|
|
267
|
+
Args:
|
|
268
|
+
timeout: The maximum amount of time (in seconds) to wait for a response.
|
|
269
|
+
Returns:
|
|
270
|
+
The current position of the audio playback.
|
|
271
|
+
"""
|
|
272
|
+
return await self._invoke_method_async("get_current_position", timeout=timeout)
|
flet_audio/types.py
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
import flet as ft
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"AudioState",
|
|
7
|
+
"AudioStateChangeEvent",
|
|
8
|
+
"AudioPositionChangeEvent",
|
|
9
|
+
"AudioDurationChangeEvent",
|
|
10
|
+
"ReleaseMode",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ReleaseMode(Enum):
|
|
15
|
+
"""The behavior of Audio player when an audio is finished or stopped."""
|
|
16
|
+
|
|
17
|
+
RELEASE = "release"
|
|
18
|
+
"""
|
|
19
|
+
Releases all resources, just like calling release method.
|
|
20
|
+
|
|
21
|
+
Info:
|
|
22
|
+
- In Android, the media player is quite resource-intensive, and this will
|
|
23
|
+
let it go. Data will be buffered again when needed (if it's a remote file,
|
|
24
|
+
it will be downloaded again).
|
|
25
|
+
- In iOS and macOS, works just like [`Audio.stop()`][(p).Audio.stop] method.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
LOOP = "loop"
|
|
29
|
+
"""
|
|
30
|
+
Keeps buffered data and plays again after completion, creating a loop.
|
|
31
|
+
Notice that calling stop method is not enough to release the resources
|
|
32
|
+
when this mode is being used.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
STOP = "stop"
|
|
36
|
+
"""
|
|
37
|
+
Stops audio playback but keep all resources intact.
|
|
38
|
+
Use this if you intend to play again later.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class AudioState(Enum):
|
|
43
|
+
"""The state of the audio player."""
|
|
44
|
+
STOPPED = "stopped"
|
|
45
|
+
"""The audio player is stopped."""
|
|
46
|
+
|
|
47
|
+
PLAYING = "playing"
|
|
48
|
+
"""The audio player is currently playing audio."""
|
|
49
|
+
|
|
50
|
+
PAUSED = "paused"
|
|
51
|
+
"""The audio player is paused and can be resumed."""
|
|
52
|
+
|
|
53
|
+
COMPLETED = "completed"
|
|
54
|
+
"""The audio player has successfully reached the end of the audio."""
|
|
55
|
+
|
|
56
|
+
DISPOSED = "disposed"
|
|
57
|
+
"""The audio player has been disposed of and should not be used anymore."""
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class AudioStateChangeEvent(ft.Event[ft.EventControlType]):
|
|
61
|
+
state: AudioState
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class AudioPositionChangeEvent(ft.Event[ft.EventControlType]):
|
|
65
|
+
position: int
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class AudioDurationChangeEvent(ft.Event[ft.EventControlType]):
|
|
69
|
+
duration: int
|