flet-audio 1.1.0.dev2__tar.gz → 1.1.0.dev4__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.
Files changed (20) hide show
  1. {flet_audio-1.1.0.dev2/src/flet_audio.egg-info → flet_audio-1.1.0.dev4}/PKG-INFO +12 -7
  2. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/README.md +10 -5
  3. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/pyproject.toml +2 -2
  4. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/src/flet_audio/__init__.py +6 -0
  5. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/src/flet_audio/audio.py +16 -0
  6. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/src/flet_audio/types.py +114 -1
  7. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4/src/flet_audio.egg-info}/PKG-INFO +12 -7
  8. flet_audio-1.1.0.dev4/src/flet_audio.egg-info/requires.txt +1 -0
  9. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/src/flutter/flet_audio/lib/src/audio.dart +11 -0
  10. flet_audio-1.1.0.dev4/src/flutter/flet_audio/lib/src/utils/audio.dart +25 -0
  11. flet_audio-1.1.0.dev2/src/flet_audio.egg-info/requires.txt +0 -1
  12. flet_audio-1.1.0.dev2/src/flutter/flet_audio/lib/src/utils/audio.dart +0 -9
  13. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/LICENSE +0 -0
  14. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/setup.cfg +0 -0
  15. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/src/flet_audio.egg-info/SOURCES.txt +0 -0
  16. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/src/flet_audio.egg-info/dependency_links.txt +0 -0
  17. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/src/flet_audio.egg-info/top_level.txt +0 -0
  18. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/src/flutter/flet_audio/lib/flet_audio.dart +0 -0
  19. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/src/flutter/flet_audio/lib/src/extension.dart +0 -0
  20. {flet_audio-1.1.0.dev2 → flet_audio-1.1.0.dev4}/src/flutter/flet_audio/pubspec.yaml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet-audio
3
- Version: 1.1.0.dev2
3
+ Version: 1.1.0.dev4
4
4
  Summary: Provides audio integration and playback in Flet apps.
5
5
  Author-email: Flet contributors <hello@flet.dev>
6
6
  License-Expression: Apache-2.0
@@ -11,7 +11,7 @@ Project-URL: Issues, https://github.com/flet-dev/flet/issues
11
11
  Requires-Python: >=3.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: flet==1.1.0.dev2
14
+ Requires-Dist: flet==1.1.0.dev4
15
15
  Dynamic: license-file
16
16
 
17
17
  # flet-audio
@@ -58,15 +58,20 @@ To install the `flet-audio` package and add it to your project dependencies:
58
58
  After this, you will have to manually add this package to your `requirements.txt` or `pyproject.toml`.
59
59
 
60
60
  > [!NOTE]
61
- > On Linux/WSL, you need to install [`GStreamer`](https://github.com/GStreamer/gstreamer) library.
61
+ > On Linux, `Audio` is only available in the **full** desktop client. With the default **light** client,
62
+ > calls such as [`play()`](https://flet.dev/docs/services/audio#flet_audio.Audio.play) fail with `Timeout waiting for invoke method listener` - set
63
+ > [`FLET_DESKTOP_FLAVOR=full`](https://flet.dev/docs/reference/environment-variables#flet_desktop_flavor) or `desktop_flavor = "full"` under `[tool.flet]` in `pyproject.toml`.
62
64
  >
63
- > If you receive `error while loading shared libraries: libgstapp-1.0.so.0`, it means `GStreamer` is not installed in your WSL environment.
64
- >
65
- > To install it, run the following command:
65
+ > The full client needs GStreamer and, because it also contains the `Video` control, `libmpv`.
66
+ > On Debian 12+ and Ubuntu 24.04+:
66
67
  >
67
68
  > ```bash
68
- > apt install -y libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools
69
+ > sudo apt install libmpv2 gstreamer1.0-plugins-base gstreamer1.0-plugins-good
69
70
  > ```
71
+ >
72
+ > On Debian 11 and Ubuntu 20.04/22.04, install `libmpv1` instead of `libmpv2`. For more formats, also install
73
+ > `gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav`.
74
+ > If you receive `error while loading shared libraries: libgstapp-1.0.so.0`, GStreamer is not installed.
70
75
 
71
76
  ### Examples
72
77
 
@@ -42,15 +42,20 @@ To install the `flet-audio` package and add it to your project dependencies:
42
42
  After this, you will have to manually add this package to your `requirements.txt` or `pyproject.toml`.
43
43
 
44
44
  > [!NOTE]
45
- > On Linux/WSL, you need to install [`GStreamer`](https://github.com/GStreamer/gstreamer) library.
45
+ > On Linux, `Audio` is only available in the **full** desktop client. With the default **light** client,
46
+ > calls such as [`play()`](https://flet.dev/docs/services/audio#flet_audio.Audio.play) fail with `Timeout waiting for invoke method listener` - set
47
+ > [`FLET_DESKTOP_FLAVOR=full`](https://flet.dev/docs/reference/environment-variables#flet_desktop_flavor) or `desktop_flavor = "full"` under `[tool.flet]` in `pyproject.toml`.
46
48
  >
47
- > If you receive `error while loading shared libraries: libgstapp-1.0.so.0`, it means `GStreamer` is not installed in your WSL environment.
48
- >
49
- > To install it, run the following command:
49
+ > The full client needs GStreamer and, because it also contains the `Video` control, `libmpv`.
50
+ > On Debian 12+ and Ubuntu 24.04+:
50
51
  >
51
52
  > ```bash
52
- > apt install -y libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools
53
+ > sudo apt install libmpv2 gstreamer1.0-plugins-base gstreamer1.0-plugins-good
53
54
  > ```
55
+ >
56
+ > On Debian 11 and Ubuntu 20.04/22.04, install `libmpv1` instead of `libmpv2`. For more formats, also install
57
+ > `gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav`.
58
+ > If you receive `error while loading shared libraries: libgstapp-1.0.so.0`, GStreamer is not installed.
54
59
 
55
60
  ### Examples
56
61
 
@@ -1,13 +1,13 @@
1
1
  [project]
2
2
  name = "flet-audio"
3
- version = "1.1.0.dev2"
3
+ version = "1.1.0.dev4"
4
4
  description = "Provides audio integration and playback in Flet apps."
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Flet contributors", email = "hello@flet.dev" }]
7
7
  license = "Apache-2.0"
8
8
  requires-python = ">=3.10"
9
9
  dependencies = [
10
- "flet==1.1.0.dev2",
10
+ "flet==1.1.0.dev4",
11
11
  ]
12
12
 
13
13
  [project.urls]
@@ -1,5 +1,8 @@
1
1
  from flet_audio.audio import Audio
2
2
  from flet_audio.types import (
3
+ AudioContext,
4
+ AudioContextFocus,
5
+ AudioContextRoute,
3
6
  AudioDurationChangeEvent,
4
7
  AudioPositionChangeEvent,
5
8
  AudioState,
@@ -9,6 +12,9 @@ from flet_audio.types import (
9
12
 
10
13
  __all__ = [
11
14
  "Audio",
15
+ "AudioContext",
16
+ "AudioContextFocus",
17
+ "AudioContextRoute",
12
18
  "AudioDurationChangeEvent",
13
19
  "AudioPositionChangeEvent",
14
20
  "AudioState",
@@ -2,6 +2,7 @@ from typing import Optional, Union
2
2
 
3
3
  import flet as ft
4
4
  from flet_audio.types import (
5
+ AudioContext,
5
6
  AudioDurationChangeEvent,
6
7
  AudioPositionChangeEvent,
7
8
  AudioStateChangeEvent,
@@ -75,6 +76,21 @@ class Audio(ft.Service):
75
76
  Defines the release mode.
76
77
  """
77
78
 
79
+ audio_context: Optional[AudioContext] = None
80
+ """
81
+ Configures platform-specific audio session and focus behavior
82
+ (for example mixing or ducking background music on Android/iOS).
83
+
84
+ When unset (`None`), Flet does not apply a custom audio context, so the
85
+ player keeps whatever context it already has. For a new player on mobile,
86
+ that means the usual effective behavior:
87
+ :attr:`~flet_audio.AudioContextRoute.SYSTEM`,
88
+ :attr:`~flet_audio.AudioContextFocus.GAIN`, `respect_silence=False`,
89
+ and `stay_awake=False`.
90
+
91
+ See :class:`~flet_audio.AudioContext`.
92
+ """
93
+
78
94
  on_loaded: Optional[ft.ControlEventHandler["Audio"]] = None
79
95
  """
80
96
  Fires when an audio is loaded/buffered.
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
  from enum import Enum
3
- from typing import TYPE_CHECKING
3
+ from typing import TYPE_CHECKING, Optional
4
4
 
5
5
  import flet as ft
6
6
 
@@ -8,6 +8,9 @@ if TYPE_CHECKING:
8
8
  from flet_audio.audio import Audio # noqa
9
9
 
10
10
  __all__ = [
11
+ "AudioContext",
12
+ "AudioContextFocus",
13
+ "AudioContextRoute",
11
14
  "AudioDurationChangeEvent",
12
15
  "AudioPositionChangeEvent",
13
16
  "AudioState",
@@ -117,3 +120,113 @@ class AudioDurationChangeEvent(ft.Event["Audio"]):
117
120
 
118
121
  duration: ft.Duration
119
122
  """The duration of the audio."""
123
+
124
+
125
+ class AudioContextFocus(Enum):
126
+ """
127
+ How the audio player requests and handles audio focus on mobile platforms.
128
+ """
129
+
130
+ GAIN = "gain"
131
+ """
132
+ Requests permanent audio focus, pausing other background audio apps.
133
+ """
134
+
135
+ DUCK_OTHERS = "duckOthers"
136
+ """
137
+ Lowers the volume of other audio apps while this audio plays.
138
+
139
+ Warning:
140
+ Due to iOS platform limitations, cannot be combined with
141
+ :attr:`~flet_audio.AudioContext.respect_silence` set to `True`.
142
+ """
143
+
144
+ MIX_WITH_OTHERS = "mixWithOthers"
145
+ """
146
+ Mixes with other background audio apps without pausing or ducking them.
147
+
148
+ Warning:
149
+ Due to iOS platform limitations, cannot be combined with
150
+ :attr:`~flet_audio.AudioContext.respect_silence` set to `True`.
151
+ """
152
+
153
+
154
+ class AudioContextRoute(Enum):
155
+ """
156
+ Audio output routing behavior.
157
+ """
158
+
159
+ SYSTEM = "system"
160
+ """Uses the default system audio route."""
161
+
162
+ SPEAKER = "speaker"
163
+ """
164
+ Forces audio output through the built-in speaker.
165
+
166
+ Warning:
167
+ Due to iOS platform limitations, cannot be combined with
168
+ :attr:`~flet_audio.AudioContext.respect_silence` set to `True`.
169
+ """
170
+
171
+ EARPIECE = "earpiece"
172
+ """Routes audio output to the earpiece receiver."""
173
+
174
+
175
+ @ft.value(kw_only=True)
176
+ class AudioContext:
177
+ """
178
+ Cross-platform configuration for native audio session and focus behavior.
179
+
180
+ Unset fields (`None`) are filled in when the context is applied on mobile:
181
+ route as :attr:`~flet_audio.AudioContextRoute.SYSTEM`, focus as
182
+ :attr:`~flet_audio.AudioContextFocus.GAIN`, and `respect_silence` /
183
+ `stay_awake` as `False`.
184
+
185
+ Note:
186
+ On iOS, audio context cannot be handled for each player individually,
187
+ so setting this property on an :class:`~flet_audio.Audio` instance
188
+ applies the context globally for the app.
189
+
190
+ Meaningful mainly on Android and iOS; desktop and web ignore it.
191
+ """
192
+
193
+ route: Optional[AudioContextRoute] = None
194
+ """
195
+ The audio output route (:attr:`~flet_audio.AudioContextRoute.SYSTEM`,
196
+ :attr:`~flet_audio.AudioContextRoute.SPEAKER`, or
197
+ :attr:`~flet_audio.AudioContextRoute.EARPIECE`).
198
+
199
+ If unset (`None`), mobile platforms behave as
200
+ :attr:`~flet_audio.AudioContextRoute.SYSTEM`.
201
+ """
202
+
203
+ focus: Optional[AudioContextFocus] = None
204
+ """
205
+ The audio focus mode (:attr:`~flet_audio.AudioContextFocus.GAIN`,
206
+ :attr:`~flet_audio.AudioContextFocus.DUCK_OTHERS`, or
207
+ :attr:`~flet_audio.AudioContextFocus.MIX_WITH_OTHERS`).
208
+
209
+ If unset (`None`), mobile platforms behave as
210
+ :attr:`~flet_audio.AudioContextFocus.GAIN`.
211
+ """
212
+
213
+ respect_silence: Optional[bool] = None
214
+ """
215
+ Whether the audio should be muted when the device is in silent/ringer mode.
216
+
217
+ If unset (`None`), mobile platforms behave as `False`
218
+ (audio can play while the device is silenced).
219
+
220
+ Warning:
221
+ Due to iOS platform limitations, setting this to `True` cannot be
222
+ combined with :attr:`~flet_audio.AudioContextFocus.DUCK_OTHERS`,
223
+ :attr:`~flet_audio.AudioContextFocus.MIX_WITH_OTHERS`, or
224
+ :attr:`~flet_audio.AudioContextRoute.SPEAKER`.
225
+ """
226
+
227
+ stay_awake: Optional[bool] = None
228
+ """
229
+ Whether to keep the device awake (acquire a wake lock) while playing audio.
230
+
231
+ If unset (`None`), mobile platforms behave as `False`.
232
+ """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flet-audio
3
- Version: 1.1.0.dev2
3
+ Version: 1.1.0.dev4
4
4
  Summary: Provides audio integration and playback in Flet apps.
5
5
  Author-email: Flet contributors <hello@flet.dev>
6
6
  License-Expression: Apache-2.0
@@ -11,7 +11,7 @@ Project-URL: Issues, https://github.com/flet-dev/flet/issues
11
11
  Requires-Python: >=3.10
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: flet==1.1.0.dev2
14
+ Requires-Dist: flet==1.1.0.dev4
15
15
  Dynamic: license-file
16
16
 
17
17
  # flet-audio
@@ -58,15 +58,20 @@ To install the `flet-audio` package and add it to your project dependencies:
58
58
  After this, you will have to manually add this package to your `requirements.txt` or `pyproject.toml`.
59
59
 
60
60
  > [!NOTE]
61
- > On Linux/WSL, you need to install [`GStreamer`](https://github.com/GStreamer/gstreamer) library.
61
+ > On Linux, `Audio` is only available in the **full** desktop client. With the default **light** client,
62
+ > calls such as [`play()`](https://flet.dev/docs/services/audio#flet_audio.Audio.play) fail with `Timeout waiting for invoke method listener` - set
63
+ > [`FLET_DESKTOP_FLAVOR=full`](https://flet.dev/docs/reference/environment-variables#flet_desktop_flavor) or `desktop_flavor = "full"` under `[tool.flet]` in `pyproject.toml`.
62
64
  >
63
- > If you receive `error while loading shared libraries: libgstapp-1.0.so.0`, it means `GStreamer` is not installed in your WSL environment.
64
- >
65
- > To install it, run the following command:
65
+ > The full client needs GStreamer and, because it also contains the `Video` control, `libmpv`.
66
+ > On Debian 12+ and Ubuntu 24.04+:
66
67
  >
67
68
  > ```bash
68
- > apt install -y libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-tools
69
+ > sudo apt install libmpv2 gstreamer1.0-plugins-base gstreamer1.0-plugins-good
69
70
  > ```
71
+ >
72
+ > On Debian 11 and Ubuntu 20.04/22.04, install `libmpv1` instead of `libmpv2`. For more formats, also install
73
+ > `gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav`.
74
+ > If you receive `error while loading shared libraries: libgstapp-1.0.so.0`, GStreamer is not installed.
70
75
 
71
76
  ### Examples
72
77
 
@@ -0,0 +1 @@
1
+ flet==1.1.0.dev4
@@ -20,6 +20,7 @@ class AudioService extends FletService {
20
20
  String? _src;
21
21
  Uint8List? _srcBytes;
22
22
  ReleaseMode? _releaseMode;
23
+ AudioContext? _audioContext;
23
24
  double? _volume;
24
25
  double? _balance;
25
26
  double? _playbackRate;
@@ -121,6 +122,16 @@ class AudioService extends FletService {
121
122
  }
122
123
 
123
124
  final sourceVersion = srcChanged ? ++_sourceVersion : _sourceVersion;
125
+
126
+ // Apply the context before loading: Android re-prepares an existing
127
+ // source when its context changes, without awaiting that preparation.
128
+ final audioContext = parseAudioContext(control.get("audio_context"));
129
+ if (audioContext != null && audioContext != _audioContext) {
130
+ _audioContext = audioContext;
131
+ await player.setAudioContext(audioContext);
132
+ if (sourceVersion != _sourceVersion) return;
133
+ }
134
+
124
135
  if (srcChanged) {
125
136
  try {
126
137
  await _applySource();
@@ -0,0 +1,25 @@
1
+ import 'package:audioplayers/audioplayers.dart';
2
+ import 'package:collection/collection.dart';
3
+ import 'package:flet/flet.dart';
4
+
5
+ ReleaseMode? parseReleaseMode(String? value, [ReleaseMode? defaultValue]) {
6
+ if (value == null) return defaultValue;
7
+ return ReleaseMode.values.firstWhereOrNull(
8
+ (e) => e.name.toLowerCase() == value.toLowerCase()) ??
9
+ defaultValue;
10
+ }
11
+
12
+ AudioContext? parseAudioContext(dynamic value) {
13
+ if (value is! Map) return null;
14
+
15
+ final config = AudioContextConfig(
16
+ route: parseEnum(AudioContextConfigRoute.values, value["route"]?.toString(),
17
+ AudioContextConfigRoute.system)!,
18
+ focus: parseEnum(AudioContextConfigFocus.values, value["focus"]?.toString(),
19
+ AudioContextConfigFocus.gain)!,
20
+ respectSilence: parseBool(value["respect_silence"], false)!,
21
+ stayAwake: parseBool(value["stay_awake"], false)!,
22
+ );
23
+
24
+ return config.build();
25
+ }
@@ -1 +0,0 @@
1
- flet==1.1.0.dev2
@@ -1,9 +0,0 @@
1
- import 'package:audioplayers/audioplayers.dart';
2
- import 'package:collection/collection.dart';
3
-
4
- ReleaseMode? parseReleaseMode(String? value, [ReleaseMode? defaultValue]) {
5
- if (value == null) return defaultValue;
6
- return ReleaseMode.values.firstWhereOrNull(
7
- (e) => e.name.toLowerCase() == value.toLowerCase()) ??
8
- defaultValue;
9
- }
File without changes