soundplayer — n_pbt_soundplayer #
← Référence des composants · Sommaire du guide
Joue un son ou une musique — un fichier du poste ou une URL — de manière asynchrone (des événements) ou synchrone (l'appel revient quand le son est fini), et un bip pur sans aucun fichier. Tous les formats que le moteur WebView2 décode : mp3, wav, ogg, opus, flac, aac, m4a, mp4, webm. Aucune DLL tierce, aucun
PlaySoundlimité au wav.
▶ Le voir en vrai — Application de démonstration, tuile Sound player : les sons, le code qui les joue et cette page, côte à côte.
En bref #
| Objet non visuel | n_pbt_soundplayer |
| Sert à | Un carillon avant un message, une alerte, une musique d'attente, un mp3 choisi par l'utilisateur, un flux d'Internet |
| Principe | Une page cachée porte un lecteur ; of_play revient tout de suite et les événements racontent la suite, of_play_sync attend la fin du son |
| Dépendance | Le runtime WebView2, déjà requis par la bibliothèque — rien d'autre |
Démarrage rapide #
// In the window : the object
n_pbt_soundplayer inv_sound
inv_sound = create n_pbt_soundplayer
// Synchronous : the next line runs after the chime
inv_sound.of_play_sync(/*source*/ "C:\Windows\Media\chimes.wav")
MessageBox("Orders", "Order 4152 shipped.")
// Asynchronous : a music from the Internet, the window stays alive. The ue_started /
// ue_ended events arrive on their own - nothing else to wire.
inv_sound.ii_volume = 60
inv_sound.of_play(/*source*/ "https://example.org/music/lobby.mp3")
Les événements ue_* sont livrés tout seuls — le composant les draine lui-même tant que le lecteur est ouvert et les lève sur le composant : rien à câbler, ni receveur ni timer.
Fichier ou URL, et pourquoi un long morceau démarre tout de suite #
- Un fichier du poste est n'importe quel chemin que PowerBuilder sait nommer — absolu, relatif au dossier de l'application, réseau. La DLL le sert au lecteur en flux, par tranches, avec les requêtes de plage qu'un lecteur émet pour avancer dans le morceau : rien n'est chargé en mémoire, et
of_seekest immédiat. - Une URL
httpsest passée telle quelle : le son démarre dès que le début est arrivé. Une adressehttp://est refusée (ue_failed,REASON_INSECURE) : la page du lecteur est servie en https, et le moteur « monterait » l'adresse en https ou la bloquerait — un serveur d'intranet sans TLS passerait pour introuvable. Téléchargez-la d'abord (restclient.of_downloadvers un fichier temporaire). Un média n'est pas soumis au CORS, contrairement à un appel d'API — voirrestclientpour ce cas-là. - Un bip (
of_beep,of_beep_sync) n'a besoin d'aucun fichier : un oscillateur du moteur audio, à la fréquence et pour la durée que vous donnez.
Propriétés #
| Propriété | Type | Défaut | Rôle |
|---|---|---|---|
ii_volume | integer | 100 | Volume en pour cent, 0 à 100, remis avec le verbe qui lance un son — et c'est le volume de CE son : of_play, of_play_sync et of_crossfade règlent le son principal ; of_play_over, of_beep et of_play_named jouent le leur à ce volume sans toucher au son principal (une alerte à 100 sur un fond baissé à 20) ; un son mis en file par of_enqueue le garde pour son tour. Changé pendant qu'un son joue, il attend le verbe suivant — seul of_fade_to change le son qui joue |
ib_loop | boolean | false | Vrai pour rejouer le son en boucle jusqu'à of_stop — une sonnerie, une musique de fond. Remis avec le son suivant. of_play_sync l'ignore : un son synchrone joue une fois, une boucle n'a pas de fin à attendre |
is_last_error | string | "" | Pourquoi le dernier appel a échoué : fichier absent, format non décodable, adresse http://, URL muette, pas de sortie audio. Rempli aussi par ue_failed. Après un of_play_sync qui a rendu 0 : "stopped" si le son a été coupé plutôt que joué jusqu'au bout |
il_timeout_ms | long | 300000 | Durée maximale d'un son synchrone (of_play_sync, of_beep_sync, of_play_named_sync) ; cinq minutes par défaut. Passé ce délai l'appel rend -4 et le son est coupé (ue_stopped suit). 0 ou moins : sans limite |
ii_rate | integer | 100 | Vitesse en pour cent (25 à 400), remise avec le verbe qui lance un son, pour CE son : le son principal, ou une superposition (of_play_over) sans changer le principal |
ii_pan | integer | 0 | Balance du son PRINCIPAL, de -100 (gauche) à 100 (droite), remise avec of_play, of_play_sync ou of_crossfade, pour les FICHIERS ; une URL joue sans balance |
il_fade_ms | long | 0 | Fondu en millisecondes : chaque départ monte du silence, chaque arrêt ou pause s'éteint |
ipo_owner | powerobject | null | L'objet visuel pour lequel ce lecteur travaille : la licence se vérifie sur sa classe. Nécessaire seulement dans l'application de démonstration ; une clé de développement ou d'exécution débride le lecteur sans lui. Non débridé, le lecteur est en mode démo — seules les 10 premières secondes d'un son sont jouées |
Méthodes #
| Méthode | Rôle |
|---|---|
of_open ( ) → long | Crée le lecteur. Facultatif — chaque méthode le fait — mais l'appeler à l'ouverture de la fenêtre paie le coût une fois. Rend le handle (> 0), ou -2 si le lecteur n'a pas pu naître (is_last_error dit pourquoi) |
of_is_open ( ) → boolean | Vrai dès que le lecteur existe |
of_play (string as_source {, long al_start_ms}) → long | Joue sans attendre : fichier du poste ou URL https (une adresse http:// est refusée, REASON_INSECURE), la fin vient par ue_ended. al_start_ms fait partir le son de ce point (en mode démo, jamais au-delà des 10 premières secondes). Le son principal en cours est remplacé ; un bip ou un son nommé continue. Rend 0 une fois lancé, -2 si le lecteur n'a pas pu naître, -4 si la page n'a pas répondu |
of_play_sync (string as_source) → long | Joue et attend la fin : l'appel revient quand le son est fini (ou arrêté). La fenêtre continue de se peindre, mais passé 250 ms tous les composants PBToolboxAI de l'application montrent le sablier et ignorent la souris jusqu'au retour : réservez-le aux sons courts. Joue une fois, quoi que dise ib_loop. Rend 0 une fois le son terminé (is_last_error = "stopped" s'il a été coupé), -2 si le lecteur n'a pas pu naître, -4 s'il n'a pas pu jouer, si il_timeout_ms est écoulé (le son est coupé) ou si un autre son synchrone attend déjà |
of_beep (long al_hz, long al_ms) → long | Un son pur sans fichier : al_hz (20 à 20 000) pendant al_ms millisecondes (10 à 5 000), au volume ii_volume. Un canal à part : of_play ne le coupe pas, of_stop si. Revient tout de suite ; ue_ended suit. Rend 0 une fois lancé, -2 si le lecteur n'a pas pu naître |
of_beep_sync (long al_hz, long al_ms) → long | Le même son, et l'appel revient quand il est fini : deux de suite font un signal à deux notes. Rend 0, -2 si le lecteur n'a pas pu naître, ou -4 sans sortie audio ou si un autre son synchrone attend déjà (is_last_error) |
of_stop ( ) | Arrête tout ce que joue le lecteur — le son, un bip, un son nommé, les superpositions, un fondu enchaîné — et vide la file ; un ue_stopped suit |
of_pause ( ) → long | Suspend le son où il est ; of_resume le reprend. Rend 0 une fois fait, -2 si le lecteur n'a pas pu naître |
of_resume ( ) → long | Reprend le son où of_pause l'a laissé. Rend 0 une fois fait, -2 si le lecteur n'a pas pu naître |
of_seek (long al_ms) → long | Se place à une position du son, en millisecondes depuis son début. En mode démo, jamais au-delà des 10 premières secondes. Pour PARTIR d'une position, of_play en prend une. Rend 0 une fois fait, -5 si aucun son ne joue (rien à déplacer), -2 si le lecteur n'a pas pu naître, -4 si la page n'a pas répondu |
of_is_playing ( ) → boolean | Vrai tant qu'un son, un bip, un son nommé ou une superposition est en cours — un son en pause compte, il n'est pas fini |
of_is_paused ( ) → boolean | Vrai tant que le son est suspendu par of_pause |
of_duration ( ) → long | La longueur du son en millisecondes, 0 tant qu'elle est inconnue ; ue_started la porte aussi |
of_position ( ) → long | Où en est le son, en millisecondes — à lire depuis un timer pour faire avancer une barre de progression à vous |
of_source ( ) → string | Ce que of_play a reçu en dernier, tel quel |
of_play_over (string as_source) → long | Joue un son PAR-DESSUS ce qui joue, sans le couper, à ii_volume et ii_rate — les siens : le fond garde les siens (un fond baissé par of_fade_to reste bas sous une alerte à 100) ; ue_ended le nomme par sa source, of_stop l'arrête avec le reste. Rend 0 une fois fait, -2 si le lecteur n'a pas pu naître |
of_enqueue (string as_source) → long | Met un son en FILE : joué tout de suite si le lecteur est libre, après le son (ou le bip, ou le son nommé) en cours sinon, jamais coupé. Le son mis en file garde ii_volume, ii_rate et ib_loop tels qu'ils sont à l'appel, pour son tour. Un son qui ne peut pas jouer lève ue_failed et la file continue. Rend 0 une fois fait, -2 si le lecteur n'a pas pu naître |
of_clear_queue ( ) → long | Oublie les sons en attente, sans couper celui qui joue ; ue_queue_done suit quand même sa fin, c'est le dernier son de la file. Rend 0 une fois fait, -2 si le lecteur n'a pas pu naître |
of_queue_count ( ) → long | Rend le nombre de sons encore en attente |
of_preload (string as_source) → long | Charge un son sans le jouer : le premier of_play de cette source démarre instantanément. Une source illisible est signalée par cet of_play, via ue_failed. Rend 0 une fois fait, -2 si le lecteur n'a pas pu naître |
of_fade_to (integer ai_volume, long al_ms) → long | Amène le volume à ai_volume (0 à 100) en al_ms ms sur le son qui joue ; la cible devient ii_volume, et un son joué par-dessus pendant ce temps n'interrompt pas le fondu. Rend 0 une fois fait, -2 si le lecteur n'a pas pu naître |
of_play_named (string as_name) → long | Un son SYNTHÉTISÉ, sans fichier, au volume ii_volume : SOUND_SUCCESS, SOUND_ERROR, SOUND_WARNING, SOUND_INFO, SOUND_NOTIFY. Un canal à part : of_play ne le coupe pas, of_stop si. Rend 0 une fois lancé, -2 si le lecteur n'a pas pu naître ; un nom inconnu passe par ue_failed (REASON_UNKNOWN) |
of_play_named_sync (string as_name) → long | Le même son, et l'appel rend la main à sa fin. Rend 0, -2 si le lecteur n'a pas pu naître, -4 sur un nom inconnu, sans sortie audio ou si un autre son synchrone attend déjà (is_last_error) |
of_has_output ( ) → boolean | Vrai si le poste a une sortie audio : à demander AVANT une alerte. Le son part toujours sur la sortie par défaut de Windows |
of_equalizer (boolean ab_on {, integer ai_gains[]}) → long | Égaliseur 5 bandes (60 / 230 / 910 / 3600 / 14000 Hz, of_eq_frequencies donne les centres), gain en dB de -24 à 24 (une valeur hors bornes est ramenée à la plus proche) ; la surcharge pose tous les gains, of_equalizer_band en pose un en direct. Fichiers LOCAUX. Rend 0 une fois fait, -2 si le lecteur n'a pas pu naître |
of_equalizer_band (integer ai_band, integer ai_gain) → long | Pose le gain d'UNE bande (ai_band 1 à 5, ai_gain en dB, -24 à 24) et l'applique aussitôt au son qui joue — un curseur à vous bougé en direct ; les autres bandes gardent leur gain. Rend 0, -5 si la bande est hors bornes, -2 si le lecteur n'a pas pu naître |
of_eq_frequencies (ref long al_freqs[]) → long | Remplit al_freqs avec la fréquence centrale de chaque bande, en Hz et dans l'ordre (60, 230, 910, 3600, 14000) — ce qu'une étiquette de bande à vous affiche. Rend le nombre de bandes, 5 |
of_meter (boolean ab_on {, integer ai_bars}) → long | Allume un vumètre / analyseur : sondez ensuite of_level (0 à 100) et of_spectrum (ai_bars barres) depuis un timer pour dessiner votre propre visualiseur. Fichiers LOCAUX. Rend 0 une fois fait, -2 si le lecteur n'a pas pu naître |
of_level ( ) → long | Rend le niveau sonore de l'instant, 0 à 100, lu en direct — l'aiguille d'un vumètre ; 0 quand le vumètre (of_meter) est éteint ou que rien ne joue. À sonder depuis un timer |
of_spectrum (ref long al_bars[]) → long | Remplit al_bars avec le spectre, lu en direct : autant de valeurs que of_meter a demandé, 0 à 100 chacune, graves d'abord — les barres d'un analyseur à vous. Rend le nombre de barres, 0 vumètre éteint |
of_crossfade (string as_source, long al_ms) → long | Fondu enchaîné : le son courant s'éteint en al_ms pendant que la nouvelle source monte — un changement de piste sans coupure ; 0 bascule tout de suite. Le nouveau son prend ii_volume, ii_rate, ii_pan et ib_loop, et un of_fade_to pendant la montée prend la main. of_stop pendant le fondu arrête les deux, et un of_play_sync qui attendait le premier son rend la main. Rend 0 une fois lancé, -2 si le lecteur n'a pas pu naître ; une source vide passe par ue_failed |
of_process_events ( ) | Vide la file des événements et les lève sur l'objet. Le pump interne du composant l'appelle pour vous tant que le lecteur est ouvert — vous ne l'appelez jamais |
of_close ( ) | Libère le lecteur, en arrêtant le son d'abord : un son qui jouait finit sur son ue_stopped, levé avant le retour ; fait pour vous à la destruction de l'objet |
of_reset ( ) | Arrête le son et remet chaque réglage à sa valeur par défaut |
Événements #
| Événement | Quand |
|---|---|
ue_started (string as_source, long al_duration_ms) | Le son démarre vraiment — une URL, une fois assez de données reçues. al_duration_ms est la longueur quand le fichier la dit, 0 sinon |
ue_ended (string as_source, boolean ab_truncated) | Le son est fini, de lui-même. ab_truncated est vrai quand la limite démo l'a coupé, jamais sous licence. Un son en boucle ne finit pas : il s'arrête |
ue_failed (string as_source, string as_message, string as_reason) | Le son n'a pas pu jouer. as_reason est un mot à tester, une constante REASON_* : REASON_INSECURE (adresse http://), REASON_FORMAT (format refusé par son nom), REASON_UNSUPPORTED (fichier absent, adresse file:// mal formée), REASON_NETWORK, REASON_DECODE, REASON_NO_SOURCE, REASON_UNKNOWN (son nommé inexistant), REASON_UNAVAILABLE (pas de sortie audio), REASON_FAILED ; as_message est la phrase à montrer. Un son de la file qui échoue n'arrête pas la file |
ue_stopped ( ) | Levé une fois quand of_stop (ou of_close, ou la fin de il_timeout_ms) a coupé ce qui jouait — pas quand un son finit de lui-même, c'est ue_ended |
ue_paused ( ) / ue_resumed ( ) | Le son est suspendu, puis reprend |
ue_progress (long al_position_ms, long al_duration_ms) | Une fois par seconde d'horloge pendant la lecture, quelle que soit ii_rate : position et durée |
ue_queue_done ( ) | Le dernier son de la file (of_enqueue) est fini |
Plusieurs sons, fondus, file d'attente #
- Le canal principal et la superposition.
of_play,of_pause,of_seek,of_stoppilotent UN son : une musique, une sonnerie.of_play_overen joue un second par-dessus, sans rien couper — une alerte sur un fond.ue_endednomme chacun par sa source. Chaque verbe règle SON son :ii_volumeetii_rateremis avecof_play_overvalent pour la superposition, pas pour le fond — une alerte à 100 sur un fond baissé à 20 parof_fade_to, le fond reste à 20. Les bips et les sons nommés sont des canaux à part :of_playne les coupe pas, seulof_stopcoupe tout. - La file.
of_enqueueattend la fin du son en cours ;ue_queue_donedit quand le dernier est fini. Un son qui échoue (ue_failed) ne fait pas taire les suivants.of_playreste le verbe qui coupe, comme la lecture à voix haute du speechout. - Les fondus.
il_fade_msfait monter chaque départ depuis le silence et mourir chaque arrêt ;of_fade_tobaisse le fond pendant une annonce. Rien de brutal. - Les sons nommés.
of_play_named(SOUND_SUCCESS)et ses quatre frères sont synthétisés : rien à livrer, rien à chercher sur le disque. - Avant l'alerte.
of_preloadouvre le fichier à l'avance,of_has_outputdit si le poste a une sortie. Le son part sur la sortie par défaut de Windows : le moteur ne donne l'identifiant d'une sortie qu'à une page autorisée à accéder aux médias, ce qu'un poste ordinaire n'accorde pas — choisir une sortie n'est donc pas proposé. - La balance (
ii_pan) vaut pour les fichiers du poste. Une URL joue sans balance : le navigateur refuse de faire entrer un son d'un autre site dans son graphe audio (CORS), et ce n'est pas un réglage. - Pas d'enregistrement. Capturer le micro est un autre composant ; celui-ci joue.
// A background in a loop, faded in ; an alert over it, the background lowered meanwhile
inv_sound.il_fade_ms = 1500
inv_sound.ib_loop = true
inv_sound.of_play(/*source*/ "C:\Windows\Media\Ring05.wav")
inv_sound.of_fade_to(/*volume*/ 20, /*ms*/ 500)
// The alert has its own volume : the background stays at 20
inv_sound.ii_volume = 100
inv_sound.of_play_over(/*source*/ "C:\Windows\Media\Alarm01.wav")
// Announcements in a row : each one waits for the previous
inv_sound.of_enqueue(/*source*/ "order-4152.mp3")
inv_sound.of_enqueue(/*source*/ "order-4153.mp3")
// A confirmation with no file at all
inv_sound.of_play_named(/*name*/ n_pbt_soundplayer.SOUND_SUCCESS)
Exemples #
Un signal à deux notes, sans aucun fichier #
// Each call waits for its tone : the second starts when the first is over
inv_sound.of_beep_sync(/*hz*/ 660, /*ms*/ 180)
inv_sound.of_beep_sync(/*hz*/ 990, /*ms*/ 220)
Un mp3 choisi par l'utilisateur, avec une barre de progression #
// Local variables
string ls_path, ls_file
// Let the user pick a music file, then play it
if GetFileOpenName("Music", ls_path, ls_file, "mp3", "Music (*.mp3;*.wav;*.flac),*.mp3;*.wav;*.flac") = 1 then
inv_sound.of_play(/*source*/ ls_path) // returns at once ; ue_started brings the length
Timer(0.5) // in the window's timer event :
end if
// event timer of the window
if inv_sound.of_is_playing() then
hpb_progress.Position = inv_sound.of_position() * 100 / Max(inv_sound.of_duration(), 1)
end if
Une sonnerie en boucle jusqu'à l'action de l'utilisateur #
// A ring at 40 %, in a loop until it is stopped
inv_sound.ii_volume = 40
inv_sound.ib_loop = true
inv_sound.of_play(/*source*/ "C:\Windows\Media\Ring01.wav")
// ... later, in the button that acknowledges the call :
inv_sound.of_stop()
Bonnes pratiques #
- Un seul objet par fenêtre, ouvert avec elle (
of_open) : le lecteur caché coûte quelques centaines de millisecondes la première fois, rien ensuite. of_play_syncbloque votre script, et la souris au-delà de 250 ms : la fenêtre se repeint, mais tous les composants PBToolboxAI de l'application montrent le sablier et ignorent les clics jusqu'au retour ; et les événements du composant comme les timers de vos fenêtres continuent d'arriver pendant l'attente — un son synchrone demandé depuis l'un d'eux est refusé (-4). Réservez-le aux sons courts — un carillon, une invite — et gardezof_playpour une musique.- Un fichier absent n'est pas une exception :
of_play_syncrend-4,of_playlèveue_failed, etis_last_errornomme le fichier.