video — u_pbt_video #
← Component reference · Guide contents
Video player: a file of the workstation — streamed by the DLL, a long film starts at once — or a URL, with the component's own transport bar, which follows the theme: play, seek, time, mute, volume. WebVTT subtitles, a poster before playback, loop, speed, framing, capture of the current picture as PNG. Whatever the user does on the bar, your application knows.
▶ See it live — Demo application, Video player tile: the film, the code driving it and this page, side by side (Internet connection needed for the sample film).
At a glance #
| Userobject | u_pbt_video |
| Item class | — (component without items) |
| Used for | A training film in the application, a product video, the replay of a recording, a showcase loop on a stand |
| Principle | A <video> of the WebView2 engine: every format it decodes (mp4, webm, ogv, m4v). The bar is the component's; its gestures go through the same verbs as your calls, hence the same events |
| Dependency | The WebView2 runtime, already required by the library — nothing else |
Quick start #
// A film of the workstation, streamed by the DLL : starts at once
uo_video.is_poster = "img\packimages.dll:PNG/COVER" // shown until the film starts
uo_video.is_subtitles = "films\training.vtt"
uo_video.of_play("films\training.mp4")
// A URL plays the same way
uo_video.of_play("https://www.w3schools.com/html/mov_bbb.mp4")
// The user pauses from the bar, or your code does : either way ue_paused fires
uo_video.of_pause()
uo_video.of_seek(90000) // to 1:30, in milliseconds
Everything you set is a property (is_source, ii_volume, ib_loop…), read live from the component; everything you do is a method (of_play, of_pause, of_stop, of_seek, of_capture); everything that happens is an event (ue_started, ue_ended, ue_progress…). A missing file is not an exception: ue_failed says so, and the message shows on the picture.
Properties #
| Property | Type | Default | Role |
|---|---|---|---|
is_source | string | "" | The film: a file of the workstation (any path, streamed) or an http(s) URL. Setting it stops what was playing; ib_autoplay decides whether the new one starts by itself. A film of any size, in a 32-bit application too: the DLL streams it by slices, never the whole file at once; a film the engine cannot decode is reported by ue_failed |
ib_autoplay | boolean | false | Starts the film as soon as is_source is set; otherwise it waits for of_play, the bar or the keyboard, and shows is_poster |
ib_muted | boolean | false | Cuts the sound, volume kept; the bar button and the M key set it too |
ii_volume | integer | 100 | Volume in percent, 0 to 100; the bar slider and the up/down arrows too |
ib_loop | boolean | false | Plays the film again and again until of_stop; a looping film never raises ue_ended |
ii_rate | integer | 100 | Speed in percent, 25 to 400: 50 = half, 200 = twice, the sound follows |
is_stretch | string | "uniform" | Framing: STRETCH_NONE, STRETCH_FILL, STRETCH_UNIFORM, STRETCH_UNIFORMTOFILL — the four modes of a picture |
ib_controls | boolean | true | The component's transport bar, themed. false hides it: your window drives the film |
is_poster | string | "" | The poster shown before the film: a file, a URL or pack.dll:NAME, like a picture's source. A mono:/tint:/white:/black: prefix recolours a monochrome image to the theme |
is_subtitles | string | "" | A subtitle file, local or URL: WebVTT (.vtt) or SubRip (.srt, converted by the DLL). One track; of_add_subtitles piles up several |
is_subtitle_lang | string | "" | The subtitle track shown (a language of of_add_subtitles); empty = none |
ii_fps | integer | 25 | Pictures per second of the film, for of_step_frames |
ib_remember_position | boolean | false | Remembers where each film is left and resumes there at the next of_play of the same source |
is_theme_style | string | fluent | Visual style of the component (THEME_STYLE_* constants) |
is_theme_mode | string | light | Light or dark variant (THEME_MODE_* constants) |
il_theme_accent | long | -1 | Accent color of this component (-1 = the theme accent) |
is_tooltip | string | "" | Simple tooltip shown when hovering the component |
is_super_tooltip_title | string | "" | Title of the rich tooltip (takes precedence over is_tooltip) |
is_super_tooltip_text | string | "" | Text of the rich tooltip (rich markup accepted) |
is_super_tooltip_image | string | "" | Image of the rich tooltip |
ib_enabled | boolean | true | false: dimmed picture, bar and keyboard inert; your code still commands |
ib_scrub_preview | boolean | true | A time bubble follows the cursor over the seek bar (true, the default), with the chapter when there are any. false hides it |
A click on the picture pauses, a second one resumes. Keyboard, when the film has the focus: Space or K play/pause, ←/→ five seconds, ↑/↓ volume, M mute, Home/End.
Methods #
| Method | Role |
|---|---|
of_play ( ) → long | Plays is_source from where it is: from the start the first time, from the pause afterwards (ue_resumed). Returns 0 once sent, -1 when the component is not created |
of_play (string as_source) → long | Sets is_source and plays it: the same call as the sound player's. Returns 0 once sent, -1 without a component |
of_pause ( ) → long | Suspends the film where it is; of_play picks it up. Returns 0 once sent, -1 without a component |
of_stop ( ) | Stops the film and goes back to its start; ue_stopped follows |
of_seek (long al_ms) → long | Moves to a position of the film, in milliseconds, playing or not; a local file seeks at once. Returns 0 once sent, -1 without a component |
of_is_playing ( ) → boolean | True while a film is under way — paused included, it has not finished |
of_is_paused ( ) → boolean | True while the film is suspended — by of_pause, the bar or the keyboard |
of_duration ( ) → long | Returns the number of milliseconds the film lasts, 0 while unknown |
of_position ( ) → long | Returns the number of milliseconds played since the start; ue_progress brings it every second too |
of_capture (string as_path) → long | Saves the picture shown now as PNG ; waits for the first decoded picture (10 s at most), so it can follow of_play directly. Returns 0 once written, -4 without a film, without a picture in time, or when a film from another site refuses its pixels, -5 on an empty or unwritable path |
of_fullscreen (boolean ab_on) → long | The film on the WHOLE monitor (the DLL moves the control into a window of its own; your window is not touched), or back. Double click, the bar's button, Escape. Returns 0, -1 when the component is not created |
of_is_fullscreen ( ) → boolean | True while the film covers the monitor |
of_add_marker (long al_ms, string as_label) → long | A MARKER on the bar: a clickable tick, and ue_marker_reached when the film passes it. Returns 0, -5 on a negative position, -1 when the component is not created |
of_clear_markers ( ) → long | Removes every marker. Returns 0, -1 when the component is not created |
of_marker_count ( ) → long | Returns the number of markers |
of_play_range (long al_from_ms, long al_to_ms) → long | Plays ONE segment: at its end, ue_ended, or with ib_loop the segment starts again. Returns 0, -5 when the bounds make no sense, -1 when the component is not created |
of_clear_range ( ) → long | Frees the film from its segment. Returns 0, -1 when the component is not created |
of_step_frames (long al_frames) → long | Moves by al_frames pictures (ii_fps), back when negative, and pauses; keys . and , on the picture. Returns 0, -1 when the component is not created |
of_add_source (string as_source) → long | Adds a film to the PLAYLIST: the first becomes is_source, the next ones follow by themselves (ue_source_changed). Returns 0, -5 on an empty source, -1 when the component is not created |
of_add_source (string as_source, string as_subtitles) → long | Adds a film WITH its subtitle file (.vtt or .srt, converted by the DLL): the subtitle belongs to that film and shows only when it plays. The simple, unambiguous way to subtitle a playlist. Returns 0, -5 on an empty source |
of_clear_playlist ( ) → long | Empties the playlist; the film playing goes on. Returns 0, -1 when the component is not created |
of_next ( ) / of_previous ( ) → long | The next or previous film of the playlist. Returns 0, -1 when the component is not created |
of_playlist_count ( ) → long | Returns the number of films in the playlist |
of_playlist_index ( ) → long | Returns the index (from 1) of the playlist film playing, 0 when off the list |
of_add_subtitles (string as_lang, string as_source) → long | A subtitle track per language: .vtt, or .srt converted by the DLL. The bar's CC button cycles them. Returns 0, -5 on an empty source, -1 when the component is not created |
of_subtitle_count ( ) → long | Returns the number of subtitle tracks |
of_remembered_position ( ) → long | Returns the number of milliseconds where is_source was left (ib_remember_position), 0 otherwise |
of_has_output ( ) → boolean | True when the workstation has an audio output |
of_add_chapter (long al_ms, string as_title) → long | A CHAPTER (table of contents): ue_chapter_changed when playback enters one. of_go_chapter jumps (1-based), of_next_chapter / of_previous_chapter walk them, of_chapter_count / of_chapter_index / of_chapters read them, of_clear_chapters empties them. Returns 0, -5 if negative |
of_clear_chapters ( ) → long | Removes every chapter; the bar and the scrub bubble forget them. Returns 0, -1 when the component is not created |
of_go_chapter (long al_index) → long | Jumps to chapter al_index (1-based, in the order of of_add_chapter) and plays from there; ue_seeked follows. Returns 0, -5 for a number below 1 |
of_next_chapter ( ) → long | Jumps to the chapter after the current position; ue_seeked follows. Nothing moves from the last chapter. Returns 0, -1 when the component is not created |
of_previous_chapter ( ) → long | Jumps to the chapter before the one the playhead is in; ue_seeked follows. Nothing moves from the first chapter. Returns 0, -1 when the component is not created |
of_chapter_count ( ) → long | Returns how many chapters the film carries (of_add_chapter), 0 with none |
of_chapter_index ( ) → long | Returns the number (1-based) of the chapter the playhead is in, 0 before the first one or with no chapter. Read live |
of_chapters (ref long al_ms[], ref string as_titles[]) → long | Fills the chapters in order — the position of each in ms into al_ms, its title into as_titles — to build a menu of yours. Returns how many there are, 0 with none |
of_picture_in_picture (boolean ab_on) → long | The film in a floating window of its own (true) or back (false); ue_pip_changed follows. of_is_pip tells if it floats, of_pip_available if the workstation allows it. Returns 0, -1 when the component is not created |
of_is_pip ( ) → boolean | True while the film floats in its Picture-in-Picture window; false again once the user closes it |
of_pip_available ( ) → boolean | True when the engine and the workstation allow Picture-in-Picture at all: ask before offering the button |
Events #
| Event | When |
|---|---|
ue_started (long al_duration_ms) | The film really starts; the length when the file says it, 0 otherwise |
ue_ended (boolean ab_truncated) | The film ended of itself; ab_truncated true when the demo limit cut it |
ue_failed (string as_message) | The film could not play: missing file, undecodable format, silent URL; the message shows on the picture too |
ue_stopped ( ) | of_stop cut a film under way |
ue_paused ( ) / ue_resumed ( ) | The film is suspended, then picks up — by your code, the bar or the keyboard alike |
ue_progress (long al_position_ms, long al_duration_ms) | Once a second while playing: what a progress bar of yours needs, without a timer |
ue_seeked (long al_position_ms) | The USER moved the position (bar, arrows, marker); never of_seek |
ue_volume_changed (long al_percent) | The user turned the volume; never ii_volume |
ue_rate_changed (long al_percent) | The user picked a speed on the bar; never ii_rate |
ue_subtitles_changed (string as_lang) | The user cycled the subtitles (CC); empty = none |
ue_fullscreen_changed (boolean ab_on) | The film went full screen, or came back |
ue_marker_reached (long al_ms, string as_label) | The film passes a marker |
ue_source_changed (long al_index, string as_source) | The playlist moves to another film |
ue_chapter_changed (long al_index, string as_title) | Playback enters another chapter (of_add_chapter): its number (1-based, 0 before the first) and its title |
ue_pip_changed (boolean ab_on) | The film enters (true) or leaves (false) the Picture-in-Picture window — by of_picture_in_picture or by the user closing it |
Full screen, markers, segment, frame by frame #
- Full screen.
of_fullscreen(true), a double click on the picture or the bar's last button. The DLL moves the control into a window of its own covering the monitor; your PowerBuilder window is not touched, and Escape brings the film back.ue_fullscreen_changedsays it both ways. - Markers.
of_add_marker(ms, label)puts a tick on the bar: the user sees it, hovers it (the label), clicks it (the film jumps there,ue_seeked), andue_marker_reachedarrives when the film passes it. Chapters of a training, points to check, defects found. - Segment.
of_play_range(from, to)plays one extract only; withib_loopit replays it untilof_clear_range. - Frame by frame.
of_step_frames(±n)moves by n pictures atii_fpsa second and pauses; the keys . and , do the same. The engine does not say a film's rate: you do. - The bar speaks. What only the user can do is reported by an event of its own:
ue_seeked,ue_volume_changed,ue_rate_changed(the speed button, 0.5× to 2×),ue_subtitles_changed(the CC button). What your code does, it already knows:of_seekraises nothing.
// Chapters on the bar, then one extract in a loop
uo_video.of_add_marker(2000, "Intro")
uo_video.of_add_marker(5000, "The bunny")
uo_video.ib_loop = true
uo_video.of_play_range(2000, 8000)
// Surveillance : back one picture at a time
uo_video.ii_fps = 30
uo_video.of_step_frames(-1)
Playlist, subtitles, resuming, formats #
- Playlist.
of_add_sourcepiles up films; the first becomesis_source, the next ones follow by themselves at the end of each,ue_source_changednames every move.of_nextandof_previousby hand. - Several subtitle tracks.
of_add_subtitles(language, file)per language;is_subtitle_langpicks, the bar's CC button cycles. A.srtis converted to WebVTT by the DLL when served: nothing to convert on your side. - Resuming.
ib_remember_position = true: where a film is left (pause, stop) is kept by the engine on this workstation, per user, and the nextof_playof the same source resumes there. A film watched to its end starts over. - Formats. What WebView2 decodes: mp4 (H.264, AAC), webm (VP8, VP9, AV1), ogv (Theora), and the audio formats (mp3, wav, ogg, flac, aac, m4a). No H.265/HEVC without the Windows extension, no old AVI, WMV, MKV, MOV: the component refuses them by name (
ue_failednames the extension) rather than showing a black screen. No HLS nor DASH: an IP camera goes through an mp4 or webm stream. - Several audio tracks. Chromium hides them behind a flag: not exposed.
// A playlist with two subtitle tracks, the position remembered
uo_video.ib_remember_position = true
uo_video.of_add_subtitles("en", "film.en.vtt")
uo_video.of_add_subtitles("fr", "film.fr.srt") // .srt : converted by the DLL
uo_video.is_subtitle_lang = "fr"
uo_video.of_add_source("intro.mp4")
uo_video.of_add_source("lesson-1.mp4")
uo_video.of_play()
Examples #
A silent showcase loop, without a bar #
uo_video.ib_controls = false
uo_video.ib_muted = true
uo_video.ib_loop = true
uo_video.is_stretch = u_pbt_video.STRETCH_UNIFORMTOFILL
uo_video.of_play("films\showcase.mp4")
Your own buttons and a progress bar #
// cb_play.clicked
if uo_video.of_is_paused() or not uo_video.of_is_playing() then uo_video.of_play() else uo_video.of_pause()
// uo_video.ue_progress : once a second, no timer needed
hpb_progress.Position = al_position_ms * 100 / Max(al_duration_ms, 1)
A thumbnail of the film for a report #
uo_video.of_play("films\training.mp4")
uo_video.of_pause()
uo_video.of_seek(15000) // the frame at 0:15
// of_capture waits for the picture itself (10 s at most) : no timer to write
if uo_video.of_capture("report\training.png") <> 0 then MessageBox("Capture", uo_video.of_get_last_error())
Good practice #
- A file of the workstation rather than a URL whenever you can: streamed by the DLL, it starts at once, seeks without reloading, and
of_capturemay read its pixels — which a film from another site refuses. - Script
ue_failedon any film whose path depends on data: it is your only net, and the message is already on screen. - Set
ib_autoplayonly for a showcase loop: a film that starts by itself with sound surprises the user; elsewhere the poster and the play button are enough. ue_progressreplaces a timer: once a second, position and length, only while playing.
Inherited from the common base #
These members exist on every visual component — they are not specific to this one. They are detailed once, in the transverse chapters; this table only says where to read them.
| Members | Role | Detailed in |
|---|---|---|
of_reset | Put the component back to zero | 3.6 Resetting a component: of_reset() |
of_register_shortcut · of_clear_shortcuts | The component's keyboard chords | 3.5 Keyboard shortcuts |
of_is_created · of_is_ready · of_get_last_error | Whether it was born, whether it is ready, what failed | 3.7 Diagnostics |
of_save_as_png · of_save_as_jpg | Export the rendering as an image | 3.8 Exporting the rendering as an image |
of_set_redraw | Group changes into a single repaint | 3.10 Best practices |
of_preload_icons | Icons shown with no delay | Instant display: of_icon |
of_set_translation | Translate one of the component's labels | 5.2 Adapting a label: of_set_translation |
of_focus_webview | Give the component the focus | 6.4 Keyboard and focus |
of_print · of_print_to_pdf | Print, or write a PDF | 6.9 Printing |
of_set_property · of_get_property · of_component_name | Driving a property by its name | 3.1 The property engine |