video — u_pbt_video #
← Référence des composants · Sommaire du guide
Lecteur vidéo : un fichier du poste — servi en flux par la DLL, un long film démarre tout de suite — ou une URL, avec la barre de transport du composant, qui suit le thème : lecture, recherche, temps, muet, volume. Sous-titres WebVTT, affiche avant lecture, boucle, vitesse, cadrage, capture de l'image courante en PNG ou JPEG. Tout ce que l'utilisateur fait sur la barre, votre application le sait.
▶ Le voir en vrai — Application de démonstration, tuile Video player : le film, le code qui le pilote et cette page, côte à côte (le film d'exemple est livré avec la démonstration ; seul l'exemple 3 vient d'Internet).
En bref #
| Userobject | u_pbt_video |
| Classe d'items | — (composant sans items) |
| Sert à | Un film de formation dans l'application, la vidéo d'un produit, la relecture d'un enregistrement, une boucle de présentation sur un stand |
| Principe | Un <video> du moteur WebView2 : tous les formats qu'il décode (mp4, webm, m4v, mov, mkv). La barre est celle du composant ; ses gestes passent par les mêmes verbes que vos appels, donc les mêmes événements |
| Dépendance | Le runtime WebView2, déjà requis par la bibliothèque — rien d'autre |
Démarrage rapide #
// 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
// The film and ITS subtitles in one call : the subtitles belong to this film
uo_video.of_play(/*source*/ "films\training.mp4", /*subtitles*/ "films\training.vtt")
// A URL plays the same way
uo_video.of_play(/*source*/ "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(/*ms*/ 90000) // to 1:30, in milliseconds
Tout ce qui se règle est une propriété (is_source, ii_volume, ib_loop…), lue en direct sur le composant ; ce qui se fait est une méthode (of_play, of_pause, of_stop, of_seek, of_capture) ; ce qui arrive est un événement (ue_started, ue_ended, ue_progress…). Un fichier absent n'est pas une exception : ue_failed le dit, et le message s'affiche sur l'image.
Propriétés #
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
is_source | string | "" | Le film : un fichier du poste (n'importe quel chemin, servi en flux) ou une URL https. Une adresse http:// est refusée (ue_failed, REASON_INSECURE) : le moteur la promeut en https et échoue — téléchargez le film d'abord (restclient, of_download). Formats : mp4, webm, m4v, mov (un film d'iPhone ou de caméra en H.264), mkv, et les formats audio ; avi, wmv et flv sont refusés par leur nom (REASON_FORMAT). Le poser arrête ce qui jouait ; ib_autoplay décide si le nouveau démarre seul. Un film de n'importe quelle taille, en 32 bits aussi : la DLL le sert par tranches, jamais le fichier entier d'un coup ; un film que le moteur ne décode pas est signalé par ue_failed. Un NOUVEAU film laisse derrière lui ce qui appartenait à l'ancien : son segment, ses sous-titres, ses marqueurs et ses chapitres (posés avant tout film, ils attendent le premier) ; un film de la liste de lecture garde ses propres sous-titres. Posez donc ses sous-titres, marqueurs et chapitres APRÈS lui — ou donnez les sous-titres avec lui : of_play(source, subtitles). Le MÊME film reposé n'est pas rechargé : il continue d'où il est |
ib_autoplay | boolean | false | Démarre le film dès que is_source est posé ; sinon il attend of_play, la barre ou le clavier, et montre is_poster |
ib_muted | boolean | false | Coupe le son, volume conservé ; le bouton de la barre et la touche M le posent aussi |
ii_volume | integer | 100 | Volume en pour cent, 0 à 100 ; le curseur de la barre et les flèches haut/bas aussi |
ib_loop | boolean | false | Rejoue le film en boucle jusqu'à of_stop ; un film en boucle ne lève jamais ue_ended |
ii_rate | integer | 100 | Vitesse en pour cent, 25 à 400 : 50 = moitié, 200 = double, le son suit |
is_stretch | string | "uniform" | Cadrage : STRETCH_NONE, STRETCH_FILL, STRETCH_UNIFORM, STRETCH_UNIFORMTOFILL — les quatre modes d'une image |
ib_controls | boolean | true | La barre de transport du composant, au thème. false la masque : votre fenêtre pilote le film |
is_poster | string | "" | L'affiche montrée avant le film : fichier, URL ou pack.dll:NOM, comme la source d'une image. Un préfixe mono:/tint:/white:/black: recolore une image monochrome au thème. https seulement : une adresse http:// est refusée, rien ne s'affiche et la propriété se relit vide |
is_subtitles | string | "" | Un fichier de sous-titres, local ou URL https : WebVTT (.vtt) ou SubRip (.srt, converti — UTF-8, UTF-16 ou la page de code ANSI du poste). Une URL est TÉLÉCHARGÉE par le composant : son serveur doit autoriser CORS (GitHub, un CDN le font) ; un refus, ou une URL http://, est dit par ue_subtitles_failed et le film continue. Une piste ; of_add_subtitles en empile plusieurs. Il appartient au film : un nouvel is_source le retire — posez-le donc APRÈS is_source, ou utilisez of_play(source, subtitles). Un fichier du poste introuvable est dit de même (ue_subtitles_failed, REASON_NOT_FOUND) ; une piste refusée laisse la propriété vide |
is_subtitle_lang | string | "" | La piste de sous-titres affichée (langue d'of_add_subtitles) ; vide = aucune |
ii_fps | integer | 25 | Images par seconde du film, pour of_step_frames |
ib_remember_position | boolean | false | Retient où chaque film est laissé — une pause, un arrêt, et toutes les 5 secondes pendant la lecture (fermer la fenêtre peut perdre ces dernières secondes) — et y reprend au prochain of_play de la même source, quelle que soit l'écriture du chemin. Gardé par le moteur sur ce poste, par utilisateur, pour les 200 derniers films |
is_theme_style | string | "" | Style visuel du composant (constantes THEME_STYLE_*) ; vide = celui de l'application, suivi à chaque changement |
is_theme_mode | string | "" | Variante claire ou sombre (constantes THEME_MODE_*) ; vide = celle de l'application, suivie à chaque changement |
il_theme_accent | long | -1 | Couleur d'accent de ce composant (-1 = l'accent de l'application, ou celui du thème) |
is_tooltip | string | "" | Info-bulle simple affichée au survol du composant |
is_super_tooltip_title | string | "" | Titre de l'info-bulle enrichie (prend le pas sur is_tooltip) |
is_super_tooltip_text | string | "" | Texte de l'info-bulle enrichie (balisage riche accepté) |
is_super_tooltip_image | string | "" | Image de l'info-bulle enrichie |
ib_enabled | boolean | true | false : image assombrie, barre et clavier inertes — sauf Échap en plein écran : on peut toujours en sortir ; votre code commande toujours |
ib_scrub_preview | boolean | true | Une bulle de temps suit le curseur sur la barre de défilement (true, par défaut), avec le chapitre s'il y en a. false la masque |
ib_pause_when_hidden | boolean | true | Met le film en pause quand le composant est MASQUÉ (une autre page d'un tab ou d'un dock PBToolboxAI, PBT_SetVisible) : ue_paused suit, et le film attend of_play, il ne reprend jamais seul. false le laisse jouer (un mur d'écrans). Un Tab NATIF de PowerBuilder ne prévient pas le composant : appelez of_pause dans son SelectionChanged |
ib_forward_seek | boolean | true | Un film de formation à REGARDER : false empêche l'utilisateur de chercher au-delà du point le plus loin déjà joué — la barre, les flèches, Fin, un marqueur, les touches image par image ; revenir en arrière reste libre, et votre code (of_seek) n'est pas retenu. of_watched_ms / of_watched_percent lisent ce qui a été joué, ue_watched_completely dit quand tout l'a été |
ib_skip_failed | boolean | false | Une liste de lecture qui avance SEULE passe un film qui ne peut pas jouer (son ue_failed est levé, après ue_source_changed) au lieu de s'y arrêter |
Un clic sur l'image met en pause, un second reprend. Clavier, quand le film a le focus : Espace ou K lecture/pause, ←/→ cinq secondes, ↑/↓ volume, M muet, Début/Fin. Les touches . et , avancent et reculent d'une image, Échap quitte le plein écran ou ferme le menu de vitesse. Dans le menu de vitesse : ↑/↓, Début/Fin, Entrée choisit, Échap et Tab le ferment. Sur un lecteur sans film, Espace et le bouton Lecture ne font rien.
Méthodes #
| Méthode | Rôle | |
|---|---|---|
of_play ( ) → long | Joue is_source là où il en est : depuis le début la première fois, depuis la pause ensuite (ue_resumed). Rend 0 une fois lancé, -5 quand le lecteur ne peut rien jouer — aucune source, ou une source refusée tout de suite (http://, un format refusé par son nom) : of_get_last_error dit laquelle et aucun ue_failed ne suit —, -2 quand le composant n'est pas créé, -4 quand la page n'a pas répondu | |
of_play (string as_source) → long | Pose la source et la joue : le même appel que le lecteur de sons. Le MÊME film n'est pas rechargé : en pause, il reprend où il est (of_seek(0) le fait repartir du début). Rend 0 une fois lancé, -5 quand la source est refusée tout de suite — vide, http:// (téléchargez-la d'abord : restclient.of_download), un format refusé par son nom : of_get_last_error dit laquelle, le film en cours continue et aucun ue_failed ne suit —, -2 quand le composant n'est pas créé, -4 quand la page n'a pas répondu | |
of_play (string as_source, string as_subtitles) → long | Pose le film ET son fichier de sous-titres (.vtt, ou .srt converti par la DLL), puis le joue : les sous-titres appartiennent au film, donnez-les AVEC lui — posés avant un deuxième film, ils partaient avec le premier. "" : pas de sous-titres. Les mêmes codes que of_play(source) ; un fichier de sous-titres illisible est dit par ue_subtitles_failed, le film continue | |
of_pause ( ) → long | Suspend le film où il est ; of_play le reprend. Rend 0 une fois envoyé, -2 quand le composant n'est pas créé | |
of_stop ( ) → long | Arrête le film et revient à son début ; ue_stopped suit. Rend 0, -2 quand le composant n'est pas créé | |
of_seek (long al_ms) → long | Se place à une position du film, en millisecondes, en lecture ou non ; un fichier local cherche tout de suite. ue_seeked suit, comme pour la barre. Rend 0 une fois envoyé, -2 si le composant n'est pas créé. Tant qu'un segment est posé (of_play_range), la position reste dedans ; ib_forward_seek ne retient pas votre code, seulement l'utilisateur | |
of_is_playing ( ) → boolean | Vrai tant qu'un film est en cours — en pause compris, il n'est pas fini | |
of_is_paused ( ) → boolean | Vrai tant que le film est suspendu — par of_pause, la barre ou le clavier | |
of_is_buffering ( ) → boolean | Vrai tant que le film TOURNE mais attend ses données — le temps que ue_buffering a annoncé. Lu dans le composant, jamais dans une copie | |
of_duration ( ) → long | Rend le nombre de millisecondes que dure le film, 0 tant qu'il est inconnu | |
of_position ( ) → long | Rend le nombre de millisecondes lues depuis le début ; ue_progress l'apporte aussi chaque seconde | |
of_capture (string as_path) → long | Enregistre l'image montrée maintenant, à la taille du film : of_capture(as_path, 0). L'EXTENSION choisit le format : .jpg ou .jpeg écrit un JPEG, tout le reste un PNG ; attend la première image décodée (10 s au plus), donc peut suivre of_play directement. Rend 0 une fois écrite, -4 sans film, avec un film qui n'a pas pu se charger, sans image à temps, quand un film d'un autre site refuse ses pixels ou quand le fichier ne peut pas être écrit, -5 sur un chemin vide ou qui dépend du dossier courant (\x, C:x), -2 si le composant n'est pas créé ; après un retour négatif, of_get_last_error dit pourquoi. Un chemin relatif s'écrit dans le dossier où l'application a démarré (le dossier courant au chargement de la bibliothèque, le même dans l'IDE et compilé) | |
of_capture (string as_path, long al_max_width) → long | La même capture, RÉDUITE à al_max_width pixels de large (hauteur en proportion) : la vignette d'un film 4K n'est pas une image 4K. 0 garde la taille du film. Mêmes retours qu'of_capture(as_path) | |
of_fullscreen (boolean ab_on) → long | Le film sur TOUT le moniteur (la DLL déplace le contrôle dans une fenêtre à elle ; votre fenêtre n'est pas touchée), ou de retour. Au-dessus de tout tant qu'il est la fenêtre active : Alt+Tab vers une autre application la fait passer devant, et revenir à votre application ramène le film au-dessus de tout. Double-clic, le bouton de la barre, Échap, Alt+F4. Échap sort même quand ib_enabled est faux. Ces gestes et cet appel lèvent ue_fullscreen_changed (of_is_fullscreen le lit). Rend 0, -2 si le composant n'est pas créé | |
of_is_fullscreen ( ) → boolean | Vrai tant que le film couvre le moniteur | |
of_add_marker (long al_ms, string as_label) → long | Un MARQUEUR sur la barre : un repère cliquable, et ue_marker_reached quand le film le passe. Rend 0, -5 sur une position négative, -2 si le composant n'est pas créé. Il appartient au film À L'ÉCRAN : un nouvel is_source le retire, ajoutez-le APRÈS le film. ue_marker_reached ne part que pour le film qui JOUE | |
of_clear_markers ( ) → long | Retire tous les marqueurs. Rend 0, -2 si le composant n'est pas créé | |
of_marker_count ( ) → long | Rend le nombre de marqueurs | |
of_play_range (long al_from_ms, long al_to_ms) → long | Joue UN segment : à sa fin, ue_ended, ou avec ib_loop le segment repart. Tant qu'il est posé, toute recherche — celle de l'utilisateur (la barre, les touches, un marqueur) comme of_seek — reste DEDANS : Début mène à son début, un clic au-delà de sa fin à sa fin ; le film ne quitte jamais l'extrait. Rend 0 une fois lancé, -5 quand les bornes n'ont pas de sens ou que le lecteur n'a pas de film jouable (of_get_last_error dit pourquoi), -2 quand le composant n'est pas créé, -4 quand la page n'a pas répondu | |
of_clear_range ( ) → long | Libère le film de son segment. Rend 0, -2 si le composant n'est pas créé | |
of_step_frames (long al_frames) → long | Avance ou recule d'al_frames images (ii_fps) et met en pause ; touches . et , sur l'image. ue_seeked suit, comme pour les touches. Rend 0, -2 si le composant n'est pas créé | |
of_add_source (string as_source) → long | Ajoute un film à la LISTE DE LECTURE : le premier devient is_source (par-dessus un film posé avant, sauf s'il JOUE : la liste le suit alors à sa fin), les suivants s'enchaînent d'eux-mêmes (ue_source_changed pour chaque film qui suit, et pour le premier quand cet appel le charge). Rend 0, -5 sur une source vide, -2 si le composant n'est pas créé | |
of_add_source (string as_source, string as_subtitles) → long | Ajoute un film AVEC son fichier de sous-titres (.vtt ou .srt, converti par la DLL) : le sous-titre appartient à ce film et s'affiche seulement quand il passe. La façon simple et sans ambiguïté de sous-titrer une liste. Rend 0, -5 sur une source vide, -2 quand le composant n'est pas créé | |
of_clear_playlist ( ) → long | Vide la liste ; le film en cours continue. Rend 0, -2 si le composant n'est pas créé | |
of_next ( ) / of_previous ( ) → long | Le film suivant ou précédent de la liste ; of_playlist_index dit où elle en est, et ue_source_changed suit. Rend 0, -2 si le composant n'est pas créé | |
of_playlist_count ( ) → long | Rend le nombre de films de la liste | |
of_playlist_index ( ) → long | Rend l'indice (depuis 1) du film de la liste en cours, 0 hors liste | |
of_add_subtitles (string as_lang, string as_source) → long | Une piste de sous-titres par langue : .vtt, ou .srt converti, du poste ou d'une URL https (téléchargée : CORS requis, voir ue_subtitles_failed). Le bouton CC de la barre les fait défiler. Rend 0, -5 sur une source vide, une langue déjà posée sur le film (of_remove_subtitles d'abord) ou qui contient / ou ` | , -2` si le composant n'est pas créé |
of_remove_subtitles (string as_lang) → long | Retire la piste d'une langue du film à l'écran (et du film de la liste qui joue : elle ne revient pas sur of_previous). La piste d'is_subtitles s'appelle default. Rend 0, -5 pour une langue que le film ne porte pas, -2 si le composant n'est pas créé | |
of_subtitle_count ( ) → long | Rend le nombre de pistes de sous-titres | |
of_remembered_position ( ) → long | Rend le nombre de millisecondes où is_source a été laissé (ib_remember_position), 0 sinon | |
of_watched_ms ( ) → long | Rend le nombre de millisecondes du film réellement JOUÉES — chaque partie comptée une fois, une recherche ne regarde rien. 0 pour un nouveau film | |
of_watched_percent ( ) → long | Rend la part du film JOUÉE, de 0 à 100 : un film de formation à regarder en entier (avec ib_forward_seek = false). ue_watched_completely dit quand elle atteint 100 ; coupé en mode démo, il dit ce qui a été vu | |
of_has_output ( ) → boolean | Vrai si le poste a une sortie audio | |
of_add_chapter (long al_ms, string as_title) → long | Un CHAPITRE (table des matières) : ue_chapter_changed quand la lecture y entre. of_go_chapter y saute (à partir de 1), of_next_chapter / of_previous_chapter les parcourent (chaque saut lève ue_seeked et ue_chapter_changed), of_chapter_count / of_chapter_index / of_chapters les lisent, of_clear_chapters les vide. Rend 0, -5 si négatif (numéros à partir de 1), -2 quand le composant n'est pas créé. Il appartient au film À L'ÉCRAN : ajoutez-le APRÈS le film | |
of_clear_chapters ( ) → long | Retire tous les chapitres ; la bulle de survol les oublie. Rend 0, -2 si le composant n'est pas créé | |
of_go_chapter (long al_index) → long | Saute au chapitre al_index (à partir de 1, dans l'ordre de of_add_chapter) ; of_chapter_index le lit aussitôt, et ue_seeked puis ue_chapter_changed suivent, comme pour un clic sur la barre. Rend 0, -5 pour un numéro inférieur à 1 ou supérieur à of_chapter_count(), -2 si le composant n'est pas créé | |
of_next_chapter ( ) → long | Saute au chapitre qui suit la position courante; of_chapter_index le lit aussitôt, et ue_seeked puis ue_chapter_changed suivent. Rien ne bouge depuis le dernier chapitre. Rend 0, -2 si le composant n'est pas créé | |
of_previous_chapter ( ) → long | Saute au chapitre qui précède celui où se trouve la lecture; of_chapter_index le lit aussitôt, et ue_seeked puis ue_chapter_changed suivent. Rien ne bouge depuis le premier chapitre. Rend 0, -2 si le composant n'est pas créé | |
of_chapter_count ( ) → long | Rend le nombre de chapitres du film (of_add_chapter), 0 sans | |
of_chapter_index ( ) → long | Rend le numéro (à partir de 1) du chapitre où se trouve la lecture, 0 avant le premier ou sans chapitre. Lu en direct | |
of_chapters (ref long al_ms[], ref string as_titles[]) → long | Remplit les chapitres dans l'ordre — la position de chacun en ms dans al_ms, son titre dans as_titles — pour bâtir un menu à vous ; un titre peut contenir n'importe quel caractère. Rend le nombre de chapitres, 0 sans | |
of_picture_in_picture (boolean ab_on) → long | Le film dans une fenêtre flottante à lui (true) ou de retour (false) ; ue_pip_changed suit, comme quand l'utilisateur ferme la petite fenêtre. of_is_pip dit s'il flotte, of_pip_available si le poste l'autorise. Rend 0, -2 si le composant n'est pas créé | |
of_is_pip ( ) → boolean | Vrai tant que le film flotte dans sa fenêtre Picture-in-Picture ; faux de nouveau quand l'utilisateur la ferme | |
of_pip_available ( ) → boolean | Vrai si le moteur et le poste autorisent le Picture-in-Picture : à demander avant d'offrir le bouton |
Événements #
| Événement | Quand |
|---|---|
ue_started (long al_duration_ms) | Le film démarre vraiment ; la longueur quand le fichier la dit, 0 sinon |
ue_ended (boolean ab_truncated) | Le film est fini de lui-même ; ab_truncated vrai quand la limite démo l'a coupé |
ue_failed (string as_message, string as_reason) | Le film n'a pas pu jouer. as_reason le dit en un mot que votre code teste : REASON_INSECURE (source http://), REASON_FORMAT (avi, wmv, flv, ou un format que le moteur déclare illisible), REASON_UNSUPPORTED (fichier absent ou conteneur non décodable), REASON_DECODE, REASON_NETWORK, REASON_NO_SOURCE, REASON_FAILED ; as_message est le texte affiché sur l'image. of_play ne le lève pas pour une source refusée tout de suite : il rend -5. Une entrée de liste qui ne peut pas jouer le lève UNE fois, après ue_source_changed |
ue_stopped ( ) | of_stop a coupé un film en cours |
ue_paused ( ) / ue_resumed ( ) | Le film est suspendu, puis reprend — par votre code, la barre ou le clavier, indifféremment ; aussi quand le composant est masqué (ib_pause_when_hidden) |
ue_progress (long al_position_ms, long al_duration_ms) | Une fois par seconde pendant la lecture : ce qu'une barre de progression à vous attend, sans timer |
ue_seeked (long al_position_ms) | La position a bougé : l'utilisateur (barre, flèches, marqueur) ou votre code — of_seek, of_step_frames et les fonctions de chapitre le lèvent aussi, comme le geste |
ue_volume_changed (long al_percent) | L'utilisateur a tourné le volume ; jamais ii_volume |
ue_rate_changed (long al_percent) | L'utilisateur a choisi une vitesse sur la barre ; jamais ii_rate |
ue_subtitles_changed (string as_lang) | L'utilisateur a fait défiler les sous-titres (CC) ; vide = aucun |
ue_muted_changed (boolean ab_on) | L'utilisateur a coupé (true) ou rendu (false) le son — le haut-parleur de la barre, la touche M ; jamais ib_muted |
ue_fullscreen_changed (boolean ab_on) | Le film est passé plein écran, ou en est revenu : double-clic, le bouton, Échap, Alt+F4, ou of_fullscreen. of_reset ne le lève jamais |
ue_marker_reached (long al_ms, string as_label) | Le film, EN LECTURE, passe un marqueur ; une recherche pendant une pause ne lève que ue_seeked |
ue_source_changed (long al_index, string as_source) | La liste de lecture passe à un autre film : d'elle-même, le précédent ayant fini, ou par of_next, of_previous et le premier of_add_source |
ue_chapter_changed (long al_index, string as_title) | La lecture entre dans un autre chapitre (of_add_chapter) : son numéro (à partir de 1, 0 avant le premier) et son titre ; aussi quand l'utilisateur ou votre code (of_go_chapter, of_next_chapter, of_previous_chapter) y saute |
ue_pip_changed (boolean ab_on) | Le film est entré (true) dans la fenêtre Picture-in-Picture ou en est sorti (false) : l'utilisateur l'a fermée, le moteur y a mis le film de lui-même, ou of_picture_in_picture l'a demandé (of_is_pip le lit) |
ue_subtitles_failed (string as_lang, string as_reason) | Un fichier de sous-titres n'a pas pu se charger : une URL https dont le serveur refuse CORS ou répond une erreur (REASON_NETWORK, REASON_NOT_FOUND), une URL http:// (REASON_INSECURE). La piste est retirée, le film continue. Un fichier du poste introuvable aussi (REASON_NOT_FOUND) |
ue_buffering (boolean ab_on) | Le film TOURNE mais doit attendre ses données plus d'un quart de seconde (true) — un réseau lent, un saut loin dans un film d'une URL : un anneau à l'accent du thème tourne sur l'image — puis l'attente prend fin (false) : le film repart, ou a été mis en pause, arrêté, remplacé, ou a échoué. of_reset ne le lève jamais |
ue_watched_completely ( ) | Toutes les parties du film ont été JOUÉES (une recherche ne regarde rien) — une fois par film : un film de formation vu en entier |
Plein écran, marqueurs, segment, image par image #
- Plein écran.
of_fullscreen(true), un double-clic sur l'image ou le dernier bouton de la barre. La DLL déplace le contrôle dans une fenêtre à elle qui couvre le moniteur ; votre fenêtre PowerBuilder n'est pas touchée, et Échap (ou Alt+F4) ramène le film. Il n'est au-dessus de tout que tant qu'il est la fenêtre active : Alt+Tab vers une autre application la fait passer devant, et revenir à votre application ramène le film au-dessus de tout. Échap sort même quandib_enabledest faux.ue_fullscreen_changeddit chaque passage, dans les deux sens : ces gestes de l'utilisateur commeof_fullscreen. - Marqueurs.
of_add_marker(ms, libellé)pose un repère sur la barre : l'utilisateur le voit, le survole (le libellé), le clique (le film y saute,ue_seeked), etue_marker_reachedarrive quand le film le passe. Chapitres d'une formation, points à contrôler, défauts relevés. - Segment.
of_play_range(de, à)ne joue qu'un extrait ; avecib_loopil le rejoue jusqu'àof_clear_range. Toute recherche reste dans l'extrait : Début mène à son début, un clic au-delà de sa fin à sa fin. En plein écran, la barre se montre aussi au clavier (Tab). - Image par image.
of_step_frames(±n)avance ou recule de n images àii_fpspar seconde et met en pause ; les touches . et , font de même. Le moteur ne dit pas la cadence d'un film : dites-la. - La barre parle. Chaque geste a son événement :
ue_seeked,ue_volume_changed,ue_rate_changed(le bouton de vitesse, 0,5× à 2×),ue_subtitles_changed(le bouton CC),ue_muted_changed(le haut-parleur, la touche M). Un déplacement demandé par votre code lève le même que le geste :of_seek,of_step_frameset les fonctions de chapitre lèventue_seeked. Une VALEUR posée par votre code reste muette, commeSetItem:ii_volume,ii_rate,is_subtitle_lang,ib_muted.
// Chapters on the bar, then one extract in a loop
uo_video.of_add_marker(/*ms*/ 2000, /*label*/ "Intro")
uo_video.of_add_marker(/*ms*/ 5000, /*label*/ "The bunny")
uo_video.ib_loop = true
uo_video.of_play_range(/*from_ms*/ 2000, /*to_ms*/ 8000)
// Surveillance : back one picture at a time
uo_video.ii_fps = 30
uo_video.of_step_frames(/*frames*/ -1)
Liste de lecture, sous-titres, reprise, formats #
- Liste de lecture.
of_add_sourceempile des films ; le premier devientis_source, les suivants s'enchaînent d'eux-mêmes à la fin de chacun,ue_source_changednomme chaque passage.of_nextetof_previousà la main, avec le même événement :of_playlist_indexdit où en est la liste. Avecib_skip_failed, la liste qui avance seule passe un film qui ne peut pas jouer (sonue_failedest levé une fois) ; la langue de sous-titres choisie suit d'un film à l'autre quand le suivant la porte. - Ce qui appartient à un film. Son segment, ses sous-titres, ses marqueurs et ses chapitres : un nouvel
is_sourceles laisse derrière lui (posés avant tout film, ils attendent le premier). La liste de lecture garde les siens : le sous-titre donné àof_add_source(film, sous-titre)revient avec son film. Posez-les donc APRÈS le film, ou donnez les sous-titres avec lui :of_play(film, sous-titre). - Plusieurs pistes de sous-titres.
of_add_subtitles(langue, fichier)par langue,of_remove_subtitles(langue)pour en retirer une ;is_subtitle_langchoisit, le bouton CC de la barre fait défiler. Un.srtest converti en WebVTT au moment de le servir : rien à convertir chez vous. Un sous-titre donné par URLhttpsest téléchargé par le composant : son serveur doit autoriser CORS, sinonue_subtitles_failedle dit et le film continue sans lui. - Reprise.
ib_remember_position = true: là où un film est laissé (pause, arrêt) est retenu par le moteur sur ce poste, par utilisateur, et le prochainof_playde la même source y reprend. Un film vu jusqu'au bout repart du début. Aussi toutes les 5 secondes pendant la lecture ; les 200 derniers films sont gardés. - Formats. Ce que WebView2 décode : mp4 (H.264, AAC), webm (VP8, VP9, AV1), mov (le H.264 d'un iPhone ou d'une caméra), mkv (un enregistrement OBS), et les formats audio (mp3, wav, ogg, opus, flac, aac, m4a). Pas le H.265/HEVC sans l'extension Windows (un
.movHEVC finit enue_failed, qui nomme l'extension), ni l'AVI, le WMV, le FLV : le composant les refuse par leur nom (REASON_FORMAT) au lieu d'un écran noir. Ni HLS ni DASH : une caméra IP passe par un flux mp4 ou webm. Seulementhttps: une adressehttp://d'intranet est refusée (REASON_INSECURE) — téléchargez le film d'abord (restclient,of_download) ou servez-le par un partage\\serveur\…. - Pistes audio multiples. Chromium les cache derrière un drapeau : non exposées.
// A playlist, each film WITH its subtitles, the position remembered
uo_video.ib_remember_position = true
uo_video.of_add_source(/*source*/ "intro.mp4", /*subtitles*/ "intro.en.vtt")
uo_video.of_add_source(/*source*/ "lesson-1.mp4", /*subtitles*/ "lesson-1.en.srt") // .srt : converted by the DLL
uo_video.of_play()
// A second language for the film on screen : it stays with that film
uo_video.of_add_subtitles(/*lang*/ "fr", /*source*/ "intro.fr.vtt")
uo_video.is_subtitle_lang = "fr"
Un film de formation à regarder en entier #
Une formation obligatoire, une consigne de sécurité : ib_forward_seek = false empêche l'utilisateur de sauter en avant au-delà de ce qu'il a déjà vu — la barre, les flèches, Fin, un marqueur — sans l'empêcher de revenir en arrière. of_watched_ms et of_watched_percent disent ce qui a été réellement joué (une recherche ne regarde rien), ue_watched_completely arrive une fois quand tout l'a été. En mode démo le film s'arrête à 10 secondes, et le pourcentage dit ce qui a été vu.
// Local variables
long ll_percent
// A training film the user must watch whole : no skipping ahead
uo_video.ib_forward_seek = false
uo_video.of_play(/*source*/ "films\safety-training.mp4", /*subtitles*/ "films\safety-training.srt")
// When the window closes : how much was really seen (ue_watched_completely says 100)
ll_percent = uo_video.of_watched_percent()
Venir du contrôle Windows Media Player #
Beaucoup d'applications PowerBuilder embarquent l'OCX de Windows Media Player dans un OLECustomControl — un contrôle que Microsoft classe « hérité », et qui fait planter plus d'une application. u_pbt_video le remplace membre à membre. Deux différences à retenir : les positions sont en millisecondes (WMP compte en secondes) et la vitesse en pourcent (ii_rate = 150 pour settings.rate = 1.5).
| Windows Media Player | u_pbt_video |
|---|---|
URL | is_source · of_play(source) |
controls.play() · controls.pause() · controls.stop() | of_play() · of_pause() · of_stop() |
controls.currentPosition | of_position() · of_seek(al_ms) |
currentMedia.duration | of_duration() |
settings.volume · settings.mute | ii_volume · ib_muted |
settings.rate | ii_rate |
settings.autoStart | ib_autoplay |
settings.setMode("loop", true) | ib_loop |
uiMode = "none" | ib_controls = false |
fullScreen | of_fullscreen() · of_is_fullscreen() |
stretchToFit | is_stretch |
closedCaption.SAMIFileName | is_subtitles (.vtt, .srt) |
currentPlaylist | of_add_source · of_next · of_previous · of_playlist_index |
PlayStateChange | ue_started · ue_paused · ue_resumed · ue_stopped · ue_ended |
PositionChange | ue_seeked |
MarkerHit | ue_marker_reached (of_add_marker) |
Buffering | ue_buffering |
MediaError | ue_failed |
Exemples #
Une boucle de présentation, silencieuse, sans barre #
// A silent showcase film, in a loop, without its 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(/*source*/ "films\showcase.mp4")
Vos propres boutons et une barre de progression #
// 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)
Une vignette du film pour un rapport #
// Stop the film on the picture to keep
uo_video.of_play(/*source*/ "films\training.mp4")
uo_video.of_pause()
uo_video.of_seek(/*ms*/ 15000) // the frame at 0:15
// of_capture waits for the picture itself (10 s at most) : no timer to write.
// A .jpg path writes a JPEG ; 320 : a thumbnail 320 pixels wide.
// A relative path goes to the folder the application started in.
if uo_video.of_capture(/*path*/ "C:\Reports\training.jpg", /*max_width*/ 320) < 0 then MessageBox("Capture", uo_video.of_get_last_error())
Bonnes pratiques #
- Un fichier du poste plutôt qu'une URL dès que vous le pouvez : servi en flux par la DLL, il démarre tout de suite, cherche sans recharger, et
of_capturepeut lire ses pixels — ce qu'un film d'un autre site refuse. - Scriptez
ue_failedsur tout film dont le chemin dépend des données : c'est votre seul filet, et le message est déjà à l'écran. - Ne posez
ib_autoplayque pour une boucle de présentation : un film qui démarre seul avec le son surprend l'utilisateur ; ailleurs, l'affiche et le bouton de lecture suffisent. ue_progressremplace un timer : une fois par seconde, position et longueur, uniquement pendant la lecture.
Hérité du socle commun #
Ces membres existent sur tous les composants visuels — ils ne sont pas propres à celui-ci. Ils sont détaillés une seule fois, dans les chapitres transverses ; cette table dit seulement où les lire.
| Membres | Rôle | Détaillé dans |
|---|---|---|
of_reset | Remettre le composant à zéro | 3.6 Remettre un composant à zéro : of_reset() |
of_register_shortcut · of_clear_shortcuts | Raccourcis clavier du composant | 3.5 Les raccourcis clavier |
of_is_created · of_is_ready · of_get_last_error | S'il est né, s'il est prêt, ce qui a échoué | 3.7 Diagnostic |
of_save_as_png · of_save_as_jpg | Exporter le rendu en image | 3.8 Exporter le rendu en image |
of_set_redraw | Grouper les modifications en un seul repaint | 3.10 Bonnes pratiques |
of_preload_icons | Icônes affichées sans délai | Affichage instantané : of_icon |
of_set_translation | Traduire un libellé du composant | 5.2 Adapter un libellé : of_set_translation |
of_focus_webview | Donner le focus au composant | 6.4 Clavier et focus |
of_print · of_print_to_pdf | Imprimer, ou écrire un PDF | 6.9 Imprimer |
of_set_property · of_get_property · of_component_name | Piloter une propriété par son nom | 3.1 Le moteur de propriétés |
is_accessible_name · is_accessible_description | Le nom et la description que dit un lecteur d'écran | 3.4 Propriétés et events optionnels |