Skip to content

Video#

Embed a full-featured video player in your Flet app with playlist support, hardware acceleration controls, and subtitle configuration.

It is powered by the media_kit Flutter package.

Platform Support#

Platform Windows macOS Linux iOS Android Web
Supported

Usage#

Add the flet-video package to your project dependencies:

uv add flet-video
pip install flet-video  # (1)!
  1. After this, you will have to manually add this package to your requirements.txt or pyproject.toml.

Windows Subsystem for Linux (WSL)

Install the libmpv library when running on WSL. If you encounter libmpv.so.1 load errors, run:

sudo apt update
sudo apt install libmpv-dev libmpv2
sudo ln -s /usr/lib/x86_64-linux-gnu/libmpv.so /usr/lib/libmpv.so.1

Example#

import random

import flet_video as ftv

import flet as ft


def main(page: ft.Page):
    page.theme_mode = ft.ThemeMode.LIGHT
    page.title = "TheEthicalVideo"
    page.window.always_on_top = True
    page.spacing = 20
    page.horizontal_alignment = ft.CrossAxisAlignment.CENTER

    async def handle_pause(e):
        await video.pause()
        print("Video.pause()")

    async def handle_play_or_pause(e):
        await video.play_or_pause()
        print("Video.play_or_pause()")

    async def handle_play(e):
        await video.play()
        print("Video.play()")

    async def handle_stop(e):
        await video.stop()
        print("Video.stop()")

    async def handle_next(e):
        await video.next()
        print("Video.next()")

    async def handle_previous(e):
        await video.previous()
        print("Video.previous()")

    def handle_volume_change(e):
        video.volume = e.control.value
        print(f"Video.volume = {e.control.value}")

    def handle_playback_rate_change(e):
        video.playback_rate = e.control.value
        print(f"Video.playback_rate = {e.control.value}")

    async def handle_seek(e):
        await video.seek(10000)
        print("Video.seek(10000)")

    async def handle_add_media(e):
        await video.playlist_add(random.choice(sample_media))
        print("Video.playlist_add(random.choice(sample_media))")

    async def handle_remove_media(e):
        r = random.randint(0, len(video.playlist) - 1)
        await video.playlist_remove(r)
        print(f"Popped Item at index: {r} (position {r + 1})")

    async def handle_jump(e):
        print("Video.jump_to(0)")
        await video.jump_to(0)

    sample_media = [
        ftv.VideoMedia(
            "https://user-images.githubusercontent.com/28951144/229373720-14d69157-1a56-4a78-a2f4-d7a134d7c3e9.mp4"
        ),
        ftv.VideoMedia(
            "https://user-images.githubusercontent.com/28951144/229373718-86ce5e1d-d195-45d5-baa6-ef94041d0b90.mp4"
        ),
        ftv.VideoMedia(
            "https://user-images.githubusercontent.com/28951144/229373716-76da0a4e-225a-44e4-9ee7-3e9006dbc3e3.mp4"
        ),
        ftv.VideoMedia(
            "https://user-images.githubusercontent.com/28951144/229373695-22f88f13-d18f-4288-9bf1-c3e078d83722.mp4"
        ),
        ftv.VideoMedia(
            "https://user-images.githubusercontent.com/28951144/229373709-603a7a89-2105-4e1b-a5a5-a6c3567c9a59.mp4",
            extras={
                "artist": "Thousand Foot Krutch",
                "album": "The End Is Where We Begin",
            },
            http_headers={
                "Foo": "Bar",
                "Accept": "*/*",
            },
        ),
    ]

    page.add(
        video := ftv.Video(
            expand=True,
            playlist=sample_media[0:2],
            playlist_mode=ftv.PlaylistMode.LOOP,
            fill_color=ft.Colors.BLUE_400,
            aspect_ratio=16 / 9,
            volume=100,
            autoplay=False,
            filter_quality=ft.FilterQuality.HIGH,
            muted=False,
            on_load=lambda e: print("Video loaded successfully!"),
            on_enter_fullscreen=lambda e: print("Video entered fullscreen!"),
            on_exit_fullscreen=lambda e: print("Video exited fullscreen!"),
        ),
        ft.Row(
            wrap=True,
            alignment=ft.MainAxisAlignment.CENTER,
            controls=[
                ft.Button("Play", on_click=handle_play),
                ft.Button("Pause", on_click=handle_pause),
                ft.Button("Play Or Pause", on_click=handle_play_or_pause),
                ft.Button("Stop", on_click=handle_stop),
                ft.Button("Next", on_click=handle_next),
                ft.Button("Previous", on_click=handle_previous),
                ft.Button("Seek s=10", on_click=handle_seek),
                ft.Button("Jump to first Media", on_click=handle_jump),
                ft.Button("Add Random Media", on_click=handle_add_media),
                ft.Button("Remove Random Media", on_click=handle_remove_media),
            ],
        ),
        ft.Slider(
            min=0,
            value=100,
            max=100,
            label="Volume = {value}%",
            divisions=10,
            width=400,
            on_change=handle_volume_change,
        ),
        ft.Slider(
            min=1,
            value=1,
            max=3,
            label="PlaybackRate = {value}X",
            divisions=6,
            width=400,
            on_change=handle_playback_rate_change,
        ),
    )


ft.run(main)

Description#

Inherits: LayoutControl

A control that displays a video from a playlist.

Properties

Events

Methods

Properties#

alignment class-attribute instance-attribute #

alignment: Alignment = field(default_factory=lambda: CENTER)

Defines the Alignment of the viewport.

autoplay class-attribute instance-attribute #

autoplay: bool = False

Whether the video should start playing automatically.

configuration class-attribute instance-attribute #

configuration: VideoConfiguration = field(
    default_factory=lambda: VideoConfiguration()
)

Additional configuration for the video player.

fill_color class-attribute instance-attribute #

fill_color: ColorValue = BLACK

Defines the color used to fill the video background.

filter_quality class-attribute instance-attribute #

filter_quality: FilterQuality = LOW

Filter quality of the texture used to render the video output.

Note

Android was reported to show blurry images when using FilterQuality.HIGH. Prefer the usage of FilterQuality.MEDIUM on this platform.

fit class-attribute instance-attribute #

fit: BoxFit = CONTAIN

The box fit to use for the video.

muted class-attribute instance-attribute #

muted: bool = False

Defines whether the video player should be started in muted state.

pause_upon_entering_background_mode class-attribute instance-attribute #

pause_upon_entering_background_mode: bool = True

Whether to pause the video when application enters background mode.

pitch class-attribute instance-attribute #

pitch: Number = 1.0

Defines the relative pitch of the video player.

playback_rate class-attribute instance-attribute #

playback_rate: Number = 1.0

Defines the playback rate of the video player.

playlist class-attribute instance-attribute #

playlist: list[VideoMedia] = field(default_factory=list)

A list of VideoMedias representing the video files to be played.

playlist_mode class-attribute instance-attribute #

playlist_mode: PlaylistMode | None = None

Represents the mode of playback for the playlist.

resume_upon_entering_foreground_mode class-attribute instance-attribute #

resume_upon_entering_foreground_mode: bool = False

Whether to resume the video when application enters foreground mode. Has effect only if pause_upon_entering_background_mode is also set to True.

show_controls class-attribute instance-attribute #

show_controls: bool = True

Whether to show the video player controls.

shuffle_playlist class-attribute instance-attribute #

shuffle_playlist: bool = False

Defines whether the playlist should be shuffled.

subtitle_configuration class-attribute instance-attribute #

subtitle_configuration: VideoSubtitleConfiguration = field(
    default_factory=lambda: VideoSubtitleConfiguration()
)

Defines the subtitle configuration for the video player.

subtitle_track class-attribute instance-attribute #

subtitle_track: VideoSubtitleTrack | None = None

Defines the subtitle track for the video player.

title class-attribute instance-attribute #

title: str = 'flet-video'

Defines the name of the underlying window & process for native backend. This is visible inside the windows' volume mixer.

volume class-attribute instance-attribute #

volume: Number = 100.0

Defines the volume of the video player.

Note

It's value ranges between 0.0 to 100.0 (inclusive), where 0.0 is muted and 100.0 is the maximum volume. An exception will be raised if the value is outside this range.

Raises:

  • ValueError

    If its value is not between 0.0 and 100.0 (inclusive).

wakelock class-attribute instance-attribute #

wakelock: bool = True

Whether to acquire wake lock while playing the video. When True, device's display will not go to standby/sleep while the video is playing.

Events#

on_complete class-attribute instance-attribute #

on_complete: ControlEventHandler[Video] | None = None

Fires when a video player completes.

on_enter_fullscreen class-attribute instance-attribute #

on_enter_fullscreen: ControlEventHandler[Video] | None = (
    None
)

Fires when the video player enters fullscreen.

on_error class-attribute instance-attribute #

on_error: ControlEventHandler[Video] | None = None

Fires when an error occurs.

Event handler argument's data property contains information about the error.

on_exit_fullscreen class-attribute instance-attribute #

on_exit_fullscreen: ControlEventHandler[Video] | None = None

Fires when the video player exits fullscreen

on_load class-attribute instance-attribute #

on_load: ControlEventHandler[Video] | None = None

Fires when the video player is initialized and ready for playback.

on_track_change class-attribute instance-attribute #

on_track_change: ControlEventHandler[Video] | None = None

Fires when a video track changes.

Event handler argument's data property contains the index of the new track.

Methods#

get_current_position async #

get_current_position() -> Duration

Returns:

  • Duration

    The current position of the currently playing media.

get_duration async #

get_duration() -> Duration

Returns:

  • Duration

    The duration of the currently playing media.

is_completed async #

is_completed() -> bool

Returns:

  • bool

    True if video player has reached the end of the currently playing media, False otherwise.

is_playing async #

is_playing() -> bool

Returns:

  • bool

    True if the video player is currently playing, False otherwise.

jump_to async #

jump_to(media_index: int)

Jumps to the VideoMedia at the specified media_index in the playlist.

next async #

next()

Jumps to the next VideoMedia in the playlist.

pause async #

pause()

Pauses the video player.

play async #

play()

Starts playing the video.

play_or_pause async #

play_or_pause()

Cycles between play and pause states of the video player, i.e., plays if paused and pauses if playing.

playlist_add async #

playlist_add(media: VideoMedia)

Appends/Adds the provided media to the playlist.

playlist_remove async #

playlist_remove(media_index: int)

Removes the provided media from the playlist.

previous async #

previous()

Jumps to the previous VideoMedia in the playlist.

seek async #

seek(position: DurationValue)

Seeks the currently playing VideoMedia from the playlist at the specified position.

stop async #

stop()

Stops the video player.