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
- pip
uv add flet-video
pip install flet-video
Requirements
The below sections show the required configurations for each platform.
Android
You may need to declare and request file-system/storage permissions, depending on your use case:
android.permission.READ_MEDIA_AUDIO(optional): Allows to read audio files from external storage. Android 13 or higher.android.permission.READ_MEDIA_VIDEO(optional): Allows to read video files from external storage. Android 13 or higher.android.permission.READ_EXTERNAL_STORAGE(optional): Allows reading from external storage. Android 12 or lower.android.permission.WRITE_EXTERNAL_STORAGE(optional): Allows writing to external storage. Android 12 or lower.
- flet build
- pyproject.toml
flet build apk \
--android-permissions android.permission.READ_MEDIA_AUDIO=true \
--android-permissions android.permission.READ_MEDIA_VIDEO=true \
--android-permissions android.permission.READ_EXTERNAL_STORAGE=true \
--android-permissions android.permission.WRITE_EXTERNAL_STORAGE=true
[tool.flet.android.permission]
"android.permission.READ_MEDIA_AUDIO" = true
"android.permission.READ_MEDIA_VIDEO" = true
"android.permission.READ_EXTERNAL_STORAGE" = true
"android.permission.WRITE_EXTERNAL_STORAGE" = true
Use PermissionHandler to request permissions at runtime.
See also:
Linux
libmpv libraries must be installed and present on the machine running the app.
On Ubuntu/Debian, this can be done with:
sudo apt install libmpv-dev mpv
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
Examples
Basic example
import random
import flet as ft
import flet_video as ftv
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": "*/*",
},
),
]
def main(page: ft.Page):
page.spacing = 20
page.horizontal_alignment = ft.CrossAxisAlignment.CENTER
async def handle_pause(e: ft.Event[ft.Button]):
await video.pause()
async def handle_play_or_pause(e: ft.Event[ft.Button]):
await video.play_or_pause()
async def handle_play(e: ft.Event[ft.Button]):
await video.play()
async def handle_stop(e: ft.Event[ft.Button]):
await video.stop()
async def handle_next(e: ft.Event[ft.Button]):
await video.next()
async def handle_previous(e: ft.Event[ft.Button]):
await video.previous()
def handle_volume_change(e: ft.Event[ft.Slider]):
video.volume = e.control.value
def handle_playback_rate_change(e: ft.Event[ft.Slider]):
video.playback_rate = e.control.value
async def handle_seek(e: ft.Event[ft.Button]):
await video.seek(10000)
async def handle_add_media(e: ft.Event[ft.Button]):
await video.playlist_add(random.choice(sample_media))
async def handle_remove_media(e: ft.Event[ft.Button]):
r = random.randint(0, len(video.playlist) - 1)
await video.playlist_remove(r)
async def handle_jump(e: ft.Event[ft.Button]):
await video.jump_to(0)
async def handle_fullscreen(e: ft.Event[ft.Button]):
video.fullscreen = True
page.add(
ft.SafeArea(
expand=True,
content=ft.Column(
expand=True,
controls=[
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("Entered fullscreen!"),
on_exit_fullscreen=lambda e: print("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.Button("Enter Fullscreen", on_click=handle_fullscreen),
],
),
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="Playback rate = {value}X",
divisions=6,
width=400,
on_change=handle_playback_rate_change,
),
],
),
)
)
if __name__ == "__main__":
ft.run(main)
Description
A control that displays a video from a playlist.
Inherits: LayoutControl
Properties
alignment- Defines the Alignment of the viewport.autoplay- Whether the video should start playing automatically.configuration- Additional configuration for the video player.fill_color- Defines the color used to fill the video background.filter_quality- Filter quality of the texture used to render the video output.fit- The box fit to use for the video.fullscreen- Whether the video player is presented in fullscreen mode.muted- Defines whether the video player should be started in muted state.pause_upon_entering_background_mode- Whether to pause the video when application enters background mode.pitch- Defines the relative pitch of the video player.playback_rate- Defines the playback rate of the video player.playlist- A list ofVideoMedias representing the video files to be played.playlist_mode- Represents the mode of playback for the playlist.resume_upon_entering_foreground_mode- Whether to resume the video when application enters foreground mode.show_controls- Whether to show the video player controls.shuffle_playlist- Defines whether the playlist should be shuffled.subtitle_configuration- Defines the subtitle configuration for the video player.subtitle_track- Defines the subtitle track for the video player.title- Defines the name of the underlying window & process for native backend.volume- Defines the volume of the video player.wakelock- Whether to acquire wake lock while playing the video.
Events
on_complete- Fires when a video player completes.on_enter_fullscreen- Fires when the video player enters fullscreen.on_error- Fires when an error occurs.on_exit_fullscreen- Fires when the video player exits fullscreenon_load- Fires when the video player is initialized and ready for playback.on_track_change- Fires when a video track changes.
Methods
get_current_position- Returns: The current position of the currently playing media.get_duration- Returns: The duration of the currently playing media.is_completed- Returns:Trueif video player has reached the end of the currently playing media,Falseotherwise.is_playing- Returns:Trueif the video player is currently playing,Falseotherwise.jump_to- Jumps to theVideoMediaat the specifiedmedia_indexin theplaylist.next- Jumps to the nextVideoMediain theplaylist.pause- Pauses the video player.play- Starts playing the video.play_or_pause- Cycles between play and pause states of the video player, i.e., plays if paused and pauses if playing.playlist_add- Appends/Adds the providedmediato theplaylist.playlist_remove- Removes the providedmediafrom theplaylist.previous- Jumps to the previousVideoMediain theplaylist.seek- Seeks the currently playingVideoMediafrom theplaylistat the specifiedposition.stop- Stops the video player.
Properties
alignmentclass-attributeinstance-attribute
alignment: Alignment = field(default_factory=(lambda: Alignment.CENTER))Defines the Alignment of the viewport.
autoplayclass-attributeinstance-attribute
autoplay: bool = FalseWhether the video should start playing automatically.
configurationclass-attributeinstance-attribute
configuration: VideoConfiguration = field(default_factory=(lambda: VideoConfiguration()))Additional configuration for the video player.
fill_colorclass-attributeinstance-attribute
fill_color: ColorValue = Colors.BLACKDefines the color used to fill the video background.
filter_qualityclass-attributeinstance-attribute
filter_quality: FilterQuality = FilterQuality.LOWFilter quality of the texture used to render the video output.
Android was reported to show blurry images when using
FilterQuality.HIGH.
Prefer the usage of FilterQuality.MEDIUM
on this platform.
fullscreenclass-attributeinstance-attribute
fullscreen: bool = FalseWhether the video player is presented in fullscreen mode.
Set to True to enter fullscreen or False to exit fullscreen programmatically.
mutedclass-attributeinstance-attribute
muted: bool = FalseDefines whether the video player should be started in muted state.
pause_upon_entering_background_modeclass-attributeinstance-attribute
pause_upon_entering_background_mode: bool = TrueWhether to pause the video when application enters background mode.
pitchclass-attributeinstance-attribute
pitch: Number = 1.0Defines the relative pitch of the video player.
playback_rateclass-attributeinstance-attribute
playback_rate: Number = 1.0Defines the playback rate of the video player.
playlistclass-attributeinstance-attribute
playlist: list[VideoMedia] = field(default_factory=list)A list of VideoMedias representing the video files to be played.