2025, Nov 23 15:00
Make Kivy VideoPlayer Fill BoxLayout Space: set fit_mode in options (fill or contain)
Video stretching issues in Kivy? Learn why VideoPlayer won't fill BoxLayout and how to fix it by setting fit_mode in options (fill or contain). KV example.
When embedding VideoPlayer in a Kivy layout, it’s easy to expect the video to stretch to the available space as you resize the window. Yet sometimes it hits a limit and refuses to fill the BoxLayout, leaving visible gaps around the texture. The issue usually comes from how stretch-related options are passed to the underlying video widget.
Reproducing the issue
The snippet below shows a screen with a VideoPlayer that won’t expand to fill the container as expected. It looks correct at a glance, but the video texture stops growing after a point.
Screen:
name: "ClipPanel"
id: pane_clip
BoxLayout:
orientation: 'vertical'
VideoPlayer:
id: vp_node
allow_stretch: True
size_hint: (1, .9)
source: ''
allow_fullscreen: True
options: {'eos': 'stop'}
keep_ratio: False
player_state: 'play'
Button:
size_hint: (1,.1)
text: "Close"
on_press:
vp_node.state = "stop"
vp_node.source = ""
on_release: root.open_main()
What’s actually happening
Stretching behavior is controlled by the video texture configuration, not by the container’s size alone. The key detail is that stretch-related options must be provided via the options dictionary, because they are options of the underlying Video instance used by VideoPlayer. Simply setting properties like allow_stretch or relying on container resizing isn’t enough to drive how the texture is fitted inside the widget.
In practice, this means you have to pass the fit mode through options so the video texture knows whether to fill the space or preserve ratio within bounds.
Fix: set fit_mode through options
To make the video fill its allocated area, add fit_mode to options. Use fill to occupy all available space, or use contain if you want to preserve aspect ratio within the widget.
Screen:
name: "ClipPanel"
id: pane_clip
BoxLayout:
orientation: 'vertical'
VideoPlayer:
id: vp_node
allow_stretch: True
size_hint: (1, .9)
source: ''
allow_fullscreen: True
options: {'eos': 'stop', 'fit_mode': 'fill'}
keep_ratio: False
player_state: 'play'
Button:
size_hint: (1,.1)
text: "Close"
on_press:
vp_node.state = "stop"
vp_node.source = ""
on_release: root.open_main()
If you prefer the video not to distort while scaling, replace fill with contain.
Why this matters
Without the correct fit configuration passed via options, the video texture won’t track the widget’s geometry as you resize the window, leading to wasted screen real estate or awkward layout gaps. This is especially visible in UI screens where the video is intended to be the dominant element. The same layout sensitivity is noticeable with local files and network streams alike.
Takeaways
Always configure stretch and fit behavior through the options dictionary on VideoPlayer so that the underlying Video instance gets the correct directives. Choose fit_mode: 'fill' if your goal is to occupy all available space, and switch to 'contain' when maintaining aspect ratio is more important. If you’re diagnosing layout issues, test with a minimal, runnable KV setup and a known source to quickly validate that the texture is responding to fit_mode as intended.
With the correct options in place, VideoPlayer will scale predictably and fill its container the way your layout suggests.