Audio Control

Overview

The Audio control enables playing audio within Flet applications. It inherits from flet.Service and can play multiple audio sources simultaneously.

Platform Support

  • Windows: ✅
  • macOS: ✅
  • Linux: ✅
  • iOS: ✅
  • Android: ✅
  • Web: ✅
  • Installation

    Install the flet-audio package:

    pip install flet-audio
    

    Ensure the package is added to your project's dependencies (requirements.txt or pyproject.toml).

    Linux/WSL Specifics

    For audio playback on Linux/WSL, install the GStreamer library:

    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
    

    Properties

  • **src**: str | bytes | None
  • - The audio source. Can be a URL, local asset path, base64 string, or raw bytes. - Supported formats depend on the underlying platform. Refer to [audioplayers troubleshooting](https://github.com/bluefireteam/audioplayers/blob/main/troubleshooting.md#supported-formats--encodings).
  • **autoplay**: bool (default: False)
  • - Starts playing audio automatically when added to the page. - Note: Autoplay is restricted in some browsers (e.g., Chrome/Edge).
  • **volume**: Number (default: 1.0)
  • - Sets the audio volume, ranging from 0.0 (mute) to 1.0 (maximum).
  • **balance**: Number (default: 0.0)
  • - Defines stereo balance: -1 (left full), 1 (right full), 0 (centered).
  • **playback_rate**: Number (default: 1.0)
  • - Sets the playback speed. - iOS/macOS limits: 0.5x to 2x. - Android SDK >= 23 required.
  • **release_mode**: ReleaseMode (default: ReleaseMode.RELEASE)
  • - Controls how resources are released.

    Events

  • **on_duration_change**: EventHandler[AudioDurationChangeEvent] | None
  • - Fires when the audio duration becomes available.
  • **on_loaded**: ControlEventHandler[Audio] | None
  • - Fires when the audio is loaded or buffered.
  • **on_position_change**: EventHandler[AudioPositionChangeEvent] | None
  • - Fires approximately every second when the audio is playing, indicating the current playback position.
  • **on_seek_complete**: ControlEventHandler[Audio] | None
  • - Fires when a seek operation completes.
  • **on_state_change**: EventHandler[AudioStateChangeEvent] | None
  • - Fires when the audio player's state changes (e.g., playing, paused, completed).

    Methods

  • **play(position: DurationValue = 0)**: async
  • - Starts or resumes audio playback from the specified position (in seconds or Duration object).
  • **pause()**: async
  • - Pauses the current audio playback.
  • **resume()**: async
  • - Resumes playback from where it was paused.
  • **seek(position: DurationValue)**: async
  • - Moves the playback cursor to the specified position.
  • **stop()**: async (Implicitly called by release or when source changes)
  • - Stops playback and releases resources.
  • **release()**: async
  • - Releases all media player resources. Resources are re-fetched/buffered upon subsequent playback actions.
  • **get_duration()**: async -> Duration | None
  • - Retrieves the total duration of the audio.
  • **get_current_position()**: async -> Duration | None
  • - Retrieves the current playback position.

    Example

    import flet as ft
    import flet_audio as fta

    def main(page: ft.Page): url = "https://github.com/mdn/webaudio-examples/blob/main/audio-analyser/viper.mp3?raw=true"

    async def play(): await audio.play() async def pause(): await audio.pause() async def resume(): await audio.resume() async def release(): await audio.release() def set_volume(value: float): audio.volume += value def set_balance(value: float): audio.balance += value async def seek_2s(): await audio.seek(ft.Duration(seconds=2)) async def get_duration(): duration = await audio.get_duration(); print("Duration:", duration) async def on_get_current_position(): position = await audio.get_current_position(); print("Current position:", position)

    audio = fta.Audio( src=url, autoplay=False, volume=1, balance=0, on_loaded=lambda _: print("Loaded"), on_duration_change=lambda e: print("Duration changed:", e.duration), on_position_change=lambda e: print("Position changed:", e.position), on_state_change=lambda e: print("State changed:", e.state), on_seek_complete=lambda _: print("Seek complete"), )

    page.add( ft.Button("Play", on_click=play), ft.Button("Pause", on_click=pause), ft.Button("Resume", on_click=resume), ft.Button("Release", on_click=release), ft.Button("Seek 2s", on_click=seek_2s), ft.Row([ ft.Button("Volume down", on_click=lambda _: set_volume(-0.1)), ft.Button("Volume up", on_click=lambda _: set_volume(0.1)), ]), ft.Row([ ft.Button("Balance left", on_click=lambda _: set_balance(-0.1)), ft.Button("Balance right", on_click=lambda _: set_balance(0.1)), ]), ft.Button("Get duration", on_click=get_duration), ft.Button("Get current position", on_click=on_get_current_position), )

    ft.run(main)