HTML5-compatible video player with native Flutter performance for your WebF applications
Version 1.0.0
Familiar HTML5 video element API with play, pause, seek, volume, and playback rate controls. Works just like a standard video element.
Play videos from network URLs (HTTP/HTTPS), Flutter assets, or local files. Supports HLS streaming for live content.
Built-in controls with optional custom UI. Adjust volume, playback speed (0.25x to 2x), and toggle loop mode.
Display a poster image before playback starts. Supports various object-fit modes: contain, cover, fill, and none.
Standard HTML5 video events: play, pause, ended, timeupdate, seeking, volumechange, error, and more.
Built on Flutter's video_player for smooth 60fps playback with hardware acceleration and efficient memory usage.
1dependencies:
2 webf_video_player: ^1.0.01import 'package:webf/webf.dart';
2import 'package:webf_video_player/webf_video_player.dart';
3
4void main() {
5 // Register the video player custom element
6 installWebFVideoPlayer();
7 runApp(MyApp());
8}React:
1npm install @openwebf/react-video-playerVue (type-only package):
1npm install @openwebf/vue-video-player1import { useRef } from 'react';
2import { WebFVideoPlayer, WebFVideoPlayerElement } from '@openwebf/react-video-player';
3
4function BasicPlayer() {
5 const videoRef = useRef<WebFVideoPlayerElement>(null);
6
7 return (
8 <WebFVideoPlayer
9 ref={videoRef}
10 src="https://example.com/video.mp4"
11 controls
12 style={{ width: '100%', height: 'auto' }}
13 onPlay={() => console.log('Playing')}
14 onPause={() => console.log('Paused')}
15 onEnded={() => console.log('Ended')}
16 />
17 );
18}1import { useRef, useState } from 'react';
2import { WebFVideoPlayer, WebFVideoPlayerElement } from '@openwebf/react-video-player';
3
4function CustomControls() {
5 const videoRef = useRef<WebFVideoPlayerElement>(null);
6 const [isPlaying, setIsPlaying] = useState(false);
7 const [currentTime, setCurrentTime] = useState(0);
8 const [duration, setDuration] = useState(0);
9
10 const togglePlay = () => {
11 if (isPlaying) {
12 videoRef.current?.pause();
13 } else {
14 videoRef.current?.play();
15 }
16 };
17
18 const handleSeek = (e: React.ChangeEvent<HTMLInputElement>) => {
19 const time = parseFloat(e.target.value);
20 if (videoRef.current) {
21 videoRef.current.currentTime = time;
22 }
23 };
24
25 return (
26 <div>
27 <WebFVideoPlayer
28 ref={videoRef}
29 src="https://example.com/video.mp4"
30 poster="https://example.com/poster.jpg"
31 controls={false}
32 onPlay={() => setIsPlaying(true)}
33 onPause={() => setIsPlaying(false)}
34 onLoadedmetadata={(e) => setDuration(e.detail.duration)}
35 onTimeupdate={(e) => setCurrentTime(e.detail.currentTime)}
36 />
37 <div className="controls">
38 <button onClick={togglePlay}>
39 {isPlaying ? 'Pause' : 'Play'}
40 </button>
41 <input
42 type="range"
43 min={0}
44 max={duration}
45 value={currentTime}
46 onChange={handleSeek}
47 />
48 <span>{Math.floor(currentTime)}s / {Math.floor(duration)}s</span>
49 </div>
50 </div>
51 );
52}1import { useRef, useState } from 'react';
2import { WebFVideoPlayer, WebFVideoPlayerElement } from '@openwebf/react-video-player';
3
4function PlaybackSpeed() {
5 const videoRef = useRef<WebFVideoPlayerElement>(null);
6 const [playbackRate, setPlaybackRate] = useState(1.0);
7
8 const speeds = [0.5, 0.75, 1.0, 1.25, 1.5, 2.0];
9
10 const changeSpeed = (rate: number) => {
11 if (videoRef.current) {
12 videoRef.current.playbackRate = rate;
13 setPlaybackRate(rate);
14 }
15 };
16
17 return (
18 <div>
19 <WebFVideoPlayer
20 ref={videoRef}
21 src="https://example.com/video.mp4"
22 controls
23 playbackRate={playbackRate}
24 onRatechange={(e) => setPlaybackRate(e.detail.playbackRate)}
25 />
26 <div className="speed-controls">
27 {speeds.map((speed) => (
28 <button
29 key={speed}
30 onClick={() => changeSpeed(speed)}
31 className={playbackRate === speed ? 'active' : ''}
32 >
33 {speed}x
34 </button>
35 ))}
36 </div>
37 </div>
38 );
39}1import { useRef, useState } from 'react';
2import { WebFVideoPlayer, WebFVideoPlayerElement } from '@openwebf/react-video-player';
3
4function VolumeControl() {
5 const videoRef = useRef<WebFVideoPlayerElement>(null);
6 const [volume, setVolume] = useState(1.0);
7 const [muted, setMuted] = useState(false);
8
9 const handleVolumeChange = (e: React.ChangeEvent<HTMLInputElement>) => {
10 const newVolume = parseFloat(e.target.value);
11 if (videoRef.current) {
12 videoRef.current.volume = newVolume;
13 setVolume(newVolume);
14 }
15 };
16
17 const toggleMute = () => {
18 if (videoRef.current) {
19 videoRef.current.muted = !muted;
20 setMuted(!muted);
21 }
22 };
23
24 return (
25 <div>
26 <WebFVideoPlayer
27 ref={videoRef}
28 src="https://example.com/video.mp4"
29 controls
30 volume={volume}
31 muted={muted}
32 onVolumechange={(e) => {
33 setVolume(e.detail.volume);
34 setMuted(e.detail.muted);
35 }}
36 />
37 <div className="volume-controls">
38 <button onClick={toggleMute}>
39 {muted ? '🔇' : '🔊'}
40 </button>
41 <input
42 type="range"
43 min={0}
44 max={1}
45 step={0.1}
46 value={muted ? 0 : volume}
47 onChange={handleVolumeChange}
48 />
49 </div>
50 </div>
51 );
52}| Property | Type | Default | Description |
|---|---|---|---|
| src | string | - | Video source URL (http, https, asset, file) |
| poster | string | - | Poster image URL |
| controls | boolean | true | Show playback controls |
| autoplay | boolean | false | Auto-start playback |
| loop | boolean | false | Loop video continuously |
| muted | boolean | false | Mute audio |
| volume | number | 1.0 | Volume level (0.0 to 1.0) |
| playbackRate | number | 1.0 | Playback speed (0.25 to 2.0) |
| currentTime | number | 0 | Current position in seconds (read/write) |
| objectFit | 'contain' | 'cover' | 'fill' | 'none' | 'contain' | Video sizing mode |
| Property | Type | Description |
|---|---|---|
| duration | number | Total duration in seconds |
| paused | boolean | Whether playback is paused |
| ended | boolean | Whether playback has ended |
| videoWidth | number | Natural video width in pixels |
| videoHeight | number | Natural video height in pixels |
play()Start video playback.
pause()Pause video playback.
load()Reload the video source.
canPlayType(mimeType: string)Check MIME type support. Returns '', 'maybe', or 'probably'.
onPlay / onPause / onEndedPlayback state events.
onTimeupdateFired ~4x per second during playback. Detail:{currentTime, duration}
onLoadedmetadataFired when metadata is loaded. Detail:{duration, videoWidth, videoHeight}
onVolumechangeFired when volume or muted state changes. Detail:{volume, muted}
onRatechangeFired when playback rate changes. Detail:{playbackRate}
onErrorFired on error. Detail:{code, message}
| Format | iOS | Android | Description |
|---|---|---|---|
| MP4 (H.264) | ✓ | ✓ | Most compatible format |
| WebM | ✗ | ✓ | Android only |
| HLS | ✓ | ✓ | Streaming format for live content |
Requires internet permission for network video playback.
1<uses-permission android:name="android.permission.INTERNET" />For HTTP (non-HTTPS) video sources, add App Transport Security exception to Info.plist.
1<key>NSAppTransportSecurity</key>
2<dict>
3 <key>NSAllowsArbitraryLoads</key>
4 <true/>
5</dict>This WebF native UI component is built on top of the official video_player Flutter package from the Flutter team. It provides a platform interface for iOS and Android for playing back video on a Widget surface.