reflex-dev / reflex

🕸️ Web apps in pure Python 🐍
https://reflex.dev
Apache License 2.0
20.14k stars 1.16k forks source link

Safari specific Audio "playing" prop bug. #3736

Open s-kruschel opened 3 months ago

s-kruschel commented 3 months ago

Describe the bug Using the Audio component I realized it is not possible to have "autoplay" (playing=True) in Safari. Nor, is it possible to start the audio via e.g. a button which sets playing=True. However, if you once click the "play" control of the Audio component itself, then it is possible to start and stop the audio using the button.

To Reproduce Just use this code e.g. in Safari nothing happens if you just press the button. In Chrome however, the Audio starts to play.

import reflex as rx

class AudioState(rx.State):
    """The audio state."""

    is_playing: bool = False

    def toggle_playing(self):
        self.is_playing = ~self.is_playing

def index() -> rx.Component:
    return rx.container(
        rx.button("Toggle Play", on_click=AudioState.toggle_playing()),
        rx.audio(
            url="https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3",
            width="100%",
            height="32px",
            playing=AudioState.is_playing,
            on_ended=AudioState.toggle_playing(),
        ),
        style={"width": "100%", "> *": {"width": "100%"}},
        size="1",
        margin_y="2em",
    )

Add state and page to the app.

app = rx.App() app.add_page(index)

Expected behavior I would expect that I can directly manipulate the state of the Audio component in Safari to have e.g. autoplay.

Specifics (please complete the following information):

dimritium commented 3 months ago

@s-kruschel I have tested this with 0.5.9 and wasn't able to reproduce. Autoplay for videos work correctly and playing audio has no issue on Safari.

Autoplay on a YouTube Video image

Snippet:

import reflex as rx
from ..templates import template

class AudioState(rx.State):
    """The audio state."""

    is_playing: bool = False

    def toggle_playing(self):
        self.is_playing = not self.is_playing

@template(route="/test", title="TestBug")
def test() -> rx.Component:
    """Generates page for testing bug.

    Returns:
        rx.Component: _description_
    """
    return rx.container(
        rx.button("Toggle Play", on_click=AudioState.toggle_playing()),
        rx.audio(
            url="https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3",
            width="100%",
            height="32px",
            playing=AudioState.is_playing,
            on_ended=AudioState.toggle_playing(),
            muted=True,
        ),
        rx.video(
            url='https://youtu.be/dQw4w9WgXcQ',
            muted=True,
            controls=True,
            playing=True
        ),
        style={"width": "100%", "> *": {"width": "100%"}},
        size="1",
        margin_y="2em",
    )