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 #

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

Defines the Alignment of the viewport.

autoplay #

autoplay: bool = False

Whether the video should start playing automatically.

configuration #

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

Additional configuration for the video player.

fill_color #

fill_color: ColorValue = BLACK

Defines the color used to fill the video background.

filter_quality #

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 #

fit: BoxFit = CONTAIN

The box fit to use for the video.

muted #

muted: bool = False

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

pause_upon_entering_background_mode #

pause_upon_entering_background_mode: bool = True

Whether to pause the video when application enters background mode.

pitch #

pitch: Number = 1.0

Defines the relative pitch of the video player.

playback_rate #

playback_rate: Number = 1.0

Defines the playback rate of the video player.

playlist #

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

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

playlist_mode #

playlist_mode: PlaylistMode | None = None

Represents the mode of playback for the playlist.

resume_upon_entering_foreground_mode #

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 #

show_controls: bool = True

Whether to show the video player controls.

shuffle_playlist #

shuffle_playlist: bool = False

Defines whether the playlist should be shuffled.

subtitle_configuration #

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

Defines the subtitle configuration for the video player.

subtitle_track #

subtitle_track: VideoSubtitleTrack | None = None

Defines the subtitle track for the video player.

title #

title: str = 'flet-video'

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

volume #

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:

wakelock #

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 #

on_complete: ControlEventHandler[Video] | None = None

Fires when a video player completes.

on_enter_fullscreen #

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

Fires when the video player enters fullscreen.

on_error #

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 #

on_exit_fullscreen: ControlEventHandler[Video] | None = None

Fires when the video player exits fullscreen

on_load #

on_load: ControlEventHandler[Video] | None = None

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

on_track_change #

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 #

get_current_position() -> Duration

Returns:

  • Duration

    The current position of the currently playing media.

get_duration #

get_duration() -> Duration

Returns:

  • Duration

    The duration of the currently playing media.

is_completed #

is_completed() -> bool

Returns:

  • bool

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

is_playing #

is_playing() -> bool

Returns:

  • bool

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

jump_to #

jump_to(media_index: int)

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

next #

next()

Jumps to the next VideoMedia in the playlist.

pause #

pause()

Pauses the video player.

play #

play()

Starts playing the video.

play_or_pause #

play_or_pause()

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

playlist_add #

playlist_add(media: VideoMedia)

Appends/Adds the provided media to the playlist.

playlist_remove #

playlist_remove(media_index: int)

Removes the provided media from the playlist.

previous #

previous()

Jumps to the previous VideoMedia in the playlist.

seek #

seek(position: DurationValue)

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

stop #

stop()

Stops the video player.