R

ReflexKR

Reflex Docs

The Component Workshop: Reflex's 100 Library Components

·

Course overview

Layout

·

Box

·

Flex

·

Stack

·

Grid

·

Container

·

Section

·

Center

·

Spacer

·

Separator

·

Card

·

Inset

·

Aspect Ratio

·

Fragment

Typography

·

Text

·

Heading

·

Link

·

Code

·

Markdown

·

Blockquote

·

Quote

·

Strong

·

Em

·

Kbd

Forms

·

Button

·

Input

·

Text Area

·

Checkbox

·

Switch

·

Radio Group

·

Select

·

Slider

·

Form

·

Upload

Data display

·

Badge

·

Avatar

·

Icon

·

Callout

·

List

·

Data List

·

Code Block

·

Progress

·

Spinner

·

Scroll Area

·

Moment

Disclosure

·

Tabs

·

Accordion

·

Segmented Control

Overlay

·

Tooltip

·

Popover

·

Hover Card

·

Dialog

·

Alert Dialog

·

Drawer

·

Dropdown Menu

·

Context Menu

·

Toast

Dynamic rendering

·

Cond

·

Match

·

Foreach

·

Auto Scroll

Media

·

Image

·

Audio

·

Video

Tables and data grids

·

Table

·

Data Table

·

Data Editor

Charts

·

Area Chart

·

Bar Chart

·

Line Chart

·

Composed Chart

·

Pie Chart

·

Radar Chart

·

Radial Bar Chart

·

Scatter Chart

·

Funnel Chart

·

Treemap

·

Sankey Chart

·

Error Bar

Chart parts

·

Axis

·

Cartesian Grid

·

Chart Tooltip

·

Legend

·

Label

·

Reference

·

Brush

Other chart libraries

·

Plotly

·

Pyplot

HTML elements

·

HTML

·

HTML Text

·

HTML Layout

·

HTML Forms

·

HTML Media

·

HTML Tables

·

SVG

Other tools

·

Theme

·

Skeleton

·

Clipboard

·

Html Embed

·

Script

·

Memo

The Component Workshop: Reflex's 100 Library Components
Media

Audio

Workshop order

In the settings of the store admin screen, add a section for previewing the new-order alert sound and adjusting its volume.

rx.audio is a player for sound files. Put the sound's address in src. It can be an external address, and for test.mp3 in the assets folder it is src="/test.mp3". Under the hood it is react-player, the same part as rx.video, so the props and events are exactly the same.

rx.audio(
    src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3",
    width="100%",
    height="54px",
)

Try the props

Play and pause are props too. Turn playing on and it plays; turn it off and it stops. Turn controls off and the browser's playback bar disappears, so you control it yourself with State and buttons.

Try the props

playing

loop

controls

muted

volume

0.8

rx.audio(src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3", playing=False, loop=False, controls=True, muted=False, volume=0.8, width="100%", height="54px")
playing sets play and stop, volume (0 to 1) sets the volume. With loop on, it starts again from the beginning when it ends.
PropValuesDefaultUse
srcaddress, list of addresses, list of {"src": …, "type": …}noneThe sound to play
playingTrue / FalseFalsePlay / pause
controlsTrue / FalseTrueShows the browser's playback bar
loopTrue / FalseFalseStarts over when it ends
volume0 ~ 11Volume
mutedTrue / FalseFalseMutes the sound
configdictnoneSettings per player type ({"youtube": {…}} and so on)
disable_remote_playbackTrue / FalseFalseTurns off playing on another device (casting)
lightTrue / FalseFalseShows only a preview instead of the player and opens the player on click (see the Video page)
width · heightCSS sizecontent sizePlayer size
EventPassesWhen
on_readynothingFinished loading and ready to play
on_startnothingPlayback starts for the first time
on_play · on_pausenothingPlayed · paused
on_playing · on_waitingnothingSound actually starts · waiting while buffering
on_duration_changeduration (seconds, float)The total length becomes known
on_time_updatecurrent position (seconds, float)The playback position changes (about 4 times a second)
on_progress{played, playedSeconds, loaded, loadedSeconds, duration}While data is downloading
on_seeking · on_seekednothing · position (seconds)Seeking · seeked
on_rate_changeplayback rate (float)The playback rate changes
on_endednothingPlayed to the end (does not fire with loop)
on_errornothingAn error during playback
on_click_previewnothingThe light preview is clicked
on_enter_picture_in_picture · on_leave_picture_in_picturenothingEntering · leaving picture-in-picture

Reflex sets controls to True by default (react-player's own default is False). Older prop names such as url, on_duration and on_seek became src, on_duration_change and on_seeked in 0.10; the old names still work with a warning and are moved to the new ones.

Tracking playback with events

Keep playing as a State value and buttons can play and stop the sound. So State stays correct when someone stops it with the browser's playback bar too, update the value in on_play and on_pause. on_time_update fires about 4 times a second, so .throttle(500) sends it to the server only once every 0.5 seconds.

loading

0 / 0 s

Finished: 0

class AudioPlayerState(rx.State):
    playing: bool = False
    status: str = "loading"
    duration: float = 0.0
    position: float = 0.0
    finished: int = 0

    @rx.event
    def toggle(self):
        self.playing = not self.playing

    @rx.event
    def mark_ready(self):
        self.status = "ready"

    @rx.event
    def mark_play(self):
        self.playing = True
        self.status = "playing"

    @rx.event
    def mark_pause(self):
        self.playing = False
        self.status = "paused"

    @rx.event
    def mark_ended(self):
        self.playing = False
        self.status = "ended"
        self.finished += 1

    @rx.event
    def got_duration(self, seconds: float):
        self.duration = round(seconds, 1)

    @rx.event
    def got_time(self, seconds: float):
        self.position = round(seconds, 1)


rx.vstack(
    rx.audio(
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3",
        playing=AudioPlayerState.playing,
        width="100%",
        height="54px",
        on_ready=AudioPlayerState.mark_ready,
        on_play=AudioPlayerState.mark_play,
        on_pause=AudioPlayerState.mark_pause,
        on_ended=AudioPlayerState.mark_ended,
        on_duration_change=AudioPlayerState.got_duration,
        on_time_update=AudioPlayerState.got_time.throttle(500),
    ),
    rx.flex(
        rx.button(
            rx.cond(AudioPlayerState.playing, rx.icon("pause"), rx.icon("play")),
            rx.cond(AudioPlayerState.playing, "Pause", "Play"),
            on_click=AudioPlayerState.toggle,
        ),
        rx.badge(AudioPlayerState.status, variant="soft"),
        rx.text(AudioPlayerState.position, " / ", AudioPlayerState.duration, " s", size="2"),
        rx.text("Finished: ", AudioPlayerState.finished, size="2", color_scheme="gray"),
        spacing="3",
        align="center",
        wrap="wrap",
    ),
    width="100%",
    spacing="3",
)

Browser autoplay rules

Browsers block autoplay of sound until the user has clicked something on the page. So trying to make a sound with playing=True as soon as the page opens may not play. It is safest to play sound after a button click. Starting without sound is allowed only with muted=True.

To let users upload sound files, see the Upload page. The full flow of uploading, processing in Python, playing and downloading is in the audio workflow example in the official docs.

Filling the order

The playback bar is hidden (controls=False, size 0), and only the preview button and the volume buttons show. When playback ends, on_ended resets playing so the button can be pressed again.

Order alert sound

0.5

class AudioChimeState(rx.State):
    playing: bool = False
    volume: float = 0.5

    @rx.event
    def play(self):
        self.playing = True

    @rx.event
    def stop(self):
        self.playing = False

    @rx.event
    def change_volume(self, step: float):
        self.volume = min(1.0, max(0.0, round(self.volume + step, 1)))


rx.card(
    rx.flex(
        rx.icon("bell-ring", color=rx.color("indigo", 10)),
        rx.text("Order alert sound", weight="medium"),
        rx.spacer(),
        rx.icon_button(rx.icon("volume-1"), on_click=AudioChimeState.change_volume(-0.1), variant="soft", size="1", aria_label="Quieter"),
        rx.text(AudioChimeState.volume, size="2", min_width="2em", text_align="center"),
        rx.icon_button(rx.icon("volume-2"), on_click=AudioChimeState.change_volume(0.1), variant="soft", size="1", aria_label="Louder"),
        rx.button(rx.icon("play"), "Preview", on_click=AudioChimeState.play, size="1", loading=AudioChimeState.playing),
        spacing="2",
        align="center",
    ),
    rx.audio(
        src="https://interactive-examples.mdn.mozilla.net/media/cc0-audio/t-rex-roar.mp3",
        playing=AudioChimeState.playing,
        volume=AudioChimeState.volume,
        controls=False,
        on_ended=AudioChimeState.stop,
        on_pause=AudioChimeState.stop,
        width="0",
        height="0",
    ),
    max_width="420px",
)

Workshop notes

  • rx.audio(src="…"). An external address or an assets path (/test.mp3). It is the same part as rx.video.

  • Control playing, loop, muted and volume (0 to 1) with State values. controls defaults to True.

  • Keep State in sync with on_play, on_pause and on_ended; slow on_time_update down with .throttle.

  • Browsers block sound autoplay. Play after the user clicks.

  • Names in 0.10: src, on_duration_change, on_seeked (url, on_duration and on_seek are the old names).

← Previous

Media · Image

Next →

Media · Video

Get news about new lessons

We'll email you when this course gets new lessons or a follow-up course opens.

We collect: your email address · Purpose: news about new lessons or the launch of this course · Kept until: you ask us to remove it. We never use it for anything else or share it. Reply to any notice email and we'll delete it right away.

Questions & answers

Ask anything about this lesson. Questions from every language version of this page appear together.

Shown as plain text, without links or formatting.

R

ReflexKR

Learn Python and Reflex by doing. Every example was run and verified on Reflex 0.10.0.

ReflexKR is free, with no banner ads. If it helped you, you can support it with a coffee. ☕ Buy us a coffee

Affiliate disclosure
한국어English日本語简体中文EspañolDeutsch

© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0

Built with Reflex