soundplayer — n_pbt_soundplayer #
← Referencia de componentes · Índice de la guía
Reproduce un sonido o una música — un archivo del equipo o una URL — de forma asíncrona (eventos) o síncrona (la llamada vuelve cuando el sonido termina), y un pitido puro sin ningún archivo. Todos los formatos que el motor WebView2 decodifica: mp3, wav, ogg, opus, flac, aac, m4a, mp4, webm. Sin DLL de terceros, sin
PlaySoundlimitado a wav.
▶ Verlo en vivo — Aplicación de demostración, mosaico Sound player: los sonidos, el código que los reproduce y esta página, lado a lado.
En resumen #
| Objeto no visual | n_pbt_soundplayer |
| Sirve para | Un carillón antes de un mensaje, una alerta, una música de espera, un mp3 elegido por el usuario, un flujo de Internet |
| Principio | Una página oculta lleva un reproductor; of_play vuelve enseguida y los eventos cuentan el resto, of_play_sync espera el final del sonido |
| Dependencia | El runtime WebView2, ya requerido por la biblioteca — nada más |
Inicio rápido #
// 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")
Los eventos ue_* se entregan por sí solos — el componente los recoge él mismo mientras el reproductor está abierto y los lanza en el componente: nada que cablear, ni receptor ni temporizador.
Archivo o URL, y por qué una pieza larga empieza enseguida #
- Un archivo del equipo es cualquier ruta que PowerBuilder sepa nombrar — absoluta, relativa a la carpeta de la aplicación, de red. La DLL lo sirve al reproductor en flujo, por tramos, con las peticiones de rango que un reproductor emite para desplazarse en la pieza: nada se carga en memoria, y
of_seekes inmediato. - Una URL
httpsse pasa tal cual: el sonido empieza en cuanto llega su comienzo. Una direcciónhttp://se rechaza (ue_failed,REASON_INSECURE): la página del reproductor se sirve en https, y el motor subiría la dirección a https o la bloquearía — un servidor de intranet sin TLS parecería inexistente. Descárguela antes (restclient.of_downloada un archivo temporal). Un medio no está sujeto a CORS, a diferencia de una llamada a una API — vearestclientpara ese caso. - Un pitido (
of_beep,of_beep_sync) no necesita ningún archivo: un oscilador del motor de audio, a la frecuencia y durante el tiempo que usted indique.
Propiedades #
| Propiedad | Tipo | Predeterminado | Función |
|---|---|---|---|
ii_volume | integer | 100 | Volumen en porcentaje, de 0 a 100, entregado con el verbo que lanza un sonido — y es el volumen de ESE sonido: of_play, of_play_sync y of_crossfade ajustan el sonido principal; of_play_over, of_beep y of_play_named reproducen el suyo a ese volumen sin tocar el sonido principal (una alerta a 100 sobre un fondo bajado a 20); un sonido puesto en cola por of_enqueue lo conserva para su turno. Cambiado mientras suena un sonido, espera al verbo siguiente — solo of_fade_to cambia el sonido en curso |
ib_loop | boolean | false | Verdadero para repetir el sonido en bucle hasta of_stop — un timbre, una música de fondo. Se entrega con el sonido siguiente. of_play_sync lo ignora: un sonido síncrono suena una vez, un bucle no tiene final que esperar |
is_last_error | string | "" | Por qué falló la última llamada: archivo ausente, formato no decodificable, dirección http://, URL muda, sin salida de audio. Rellenado también por ue_failed. Tras un of_play_sync que devolvió 0: "stopped" si el sonido fue cortado en lugar de sonar hasta el final |
il_timeout_ms | long | 300000 | La duración máxima de un sonido síncrono (of_play_sync, of_beep_sync, of_play_named_sync); cinco minutos por defecto. Pasado ese plazo la llamada devuelve -4 y el sonido se corta (sigue ue_stopped). 0 o menos: sin límite |
ii_rate | integer | 100 | Velocidad en porcentaje (25 a 400), entregada con el verbo que lanza un sonido, para ESE sonido: el sonido principal, o una superposición (of_play_over) sin cambiar el principal |
ii_pan | integer | 0 | Balance del sonido PRINCIPAL, de -100 (izquierda) a 100 (derecha), entregado con of_play, of_play_sync u of_crossfade, para ARCHIVOS; una URL suena sin balance |
il_fade_ms | long | 0 | Fundido en milisegundos: cada inicio sube desde el silencio, cada parada o pausa se apaga |
ipo_owner | powerobject | null | El objeto visual para el que trabaja este reproductor: la licencia se comprueba en su clase. Necesario solo en la aplicación de demostración; una clave de desarrollo o de ejecución desbloquea el reproductor sin él. Sin desbloquear, el reproductor está en modo demo — solo se reproducen los 10 primeros segundos de un sonido |
Métodos #
| Método | Función |
|---|---|
of_open ( ) → long | Crea el reproductor. Opcional — cada método lo hace — pero llamarlo al abrir la ventana paga el coste una vez. Devuelve el handle (> 0), o -2 si el reproductor no pudo crearse (is_last_error dice por qué) |
of_is_open ( ) → boolean | Verdadero en cuanto existe el reproductor |
of_play (string as_source {, long al_start_ms}) → long | Reproduce sin esperar: un archivo del equipo o una URL https (una dirección http:// se rechaza, REASON_INSECURE), el final llega por ue_ended. al_start_ms hace empezar el sonido en ese punto (en modo demo, nunca más allá de los 10 primeros segundos). El sonido principal en curso se sustituye; un pitido o un sonido con nombre continúa. Devuelve 0 una vez lanzado, -2 si el reproductor no pudo crearse, -4 si la página no respondió |
of_play_sync (string as_source) → long | Reproduce y espera el final: la llamada vuelve cuando el sonido termina (o se detiene). La ventana sigue repintándose, pero pasados 250 ms todos los componentes PBToolboxAI de la aplicación muestran el reloj de arena e ignoran el ratón hasta el retorno: resérvelo para sonidos cortos. Suena una vez, diga lo que diga ib_loop. Devuelve 0 una vez terminado el sonido (is_last_error = "stopped" si fue cortado), -2 si el reproductor no pudo crearse, -4 si no pudo sonar, si il_timeout_ms venció (el sonido se corta) o si otro sonido síncrono ya espera |
of_beep (long al_hz, long al_ms) → long | Un tono puro sin archivo: al_hz (20 a 20 000) durante al_ms milisegundos (10 a 5 000), al volumen ii_volume. Un canal aparte: of_play no lo corta, of_stop sí. Vuelve enseguida; sigue ue_ended. Devuelve 0 una vez lanzado, -2 si el reproductor no pudo crearse |
of_beep_sync (long al_hz, long al_ms) → long | El mismo tono, y la llamada vuelve cuando termina: dos seguidos forman una señal de dos notas. Devuelve 0, -2 si el reproductor no pudo crearse, o -4 sin salida de audio o si otro sonido síncrono ya espera (is_last_error) |
of_stop ( ) | Detiene todo lo que suena el reproductor — el sonido, un pitido, un sonido con nombre, las superposiciones, un fundido encadenado — y vacía la cola; sigue un ue_stopped |
of_pause ( ) → long | Suspende el sonido donde está; of_resume lo retoma. Devuelve 0 una vez hecho, -2 si el reproductor no pudo crearse |
of_resume ( ) → long | Retoma el sonido donde of_pause lo dejó. Devuelve 0 una vez hecho, -2 si el reproductor no pudo crearse |
of_seek (long al_ms) → long | Se coloca en una posición del sonido, en milisegundos desde su inicio. En modo demo, nunca más allá de los 10 primeros segundos. Para EMPEZAR en una posición, of_play acepta una. Devuelve 0 una vez hecho, -5 si no suena ningún sonido (nada que mover), -2 si el reproductor no pudo crearse, -4 si la página no respondió |
of_is_playing ( ) → boolean | Verdadero mientras un sonido, un pitido, un sonido con nombre o una superposición está en curso — un sonido en pausa cuenta, no ha terminado |
of_is_paused ( ) → boolean | Verdadero mientras el sonido está suspendido por of_pause |
of_duration ( ) → long | La longitud del sonido en milisegundos, 0 mientras se desconoce; ue_started también la lleva |
of_position ( ) → long | Dónde va el sonido, en milisegundos — léalo desde un timer para mover una barra de progreso suya |
of_source ( ) → string | Lo que of_play recibió por última vez, tal cual |
of_play_over (string as_source) → long | Reproduce un sonido ENCIMA de lo que suena, sin cortarlo, a ii_volume e ii_rate — los suyos: el fondo conserva los suyos (un fondo bajado por of_fade_to sigue bajo bajo una alerta a 100); ue_ended lo nombra por su fuente, of_stop lo detiene con el resto. Devuelve 0 una vez hecho, -2 si el reproductor no pudo crearse |
of_enqueue (string as_source) → long | Pone un sonido en COLA: suena enseguida si el reproductor está libre, tras el sonido (o el pitido, o el sonido con nombre) en curso si no, nunca cortado. El sonido en cola conserva ii_volume, ii_rate e ib_loop tal como están en la llamada, para su turno. Un sonido que no puede sonar lanza ue_failed y la cola continúa. Devuelve 0 una vez hecho, -2 si el reproductor no pudo crearse |
of_clear_queue ( ) → long | Olvida los sonidos en espera, sin cortar el que suena; ue_queue_done sigue igualmente a su final, es el último sonido de la cola. Devuelve 0 una vez hecho, -2 si el reproductor no pudo crearse |
of_queue_count ( ) → long | Devuelve el número de sonidos aún en espera |
of_preload (string as_source) → long | Carga un sonido sin reproducirlo: el primer of_play de esa fuente arranca al instante. Una fuente ilegible la señala ese of_play, mediante ue_failed. Devuelve 0 una vez hecho, -2 si el reproductor no pudo crearse |
of_fade_to (integer ai_volume, long al_ms) → long | Lleva el volumen a ai_volume (0 a 100) en al_ms ms sobre el sonido que suena; el objetivo pasa a ser ii_volume, y un sonido reproducido encima mientras tanto no interrumpe el fundido. Devuelve 0 una vez hecho, -2 si el reproductor no pudo crearse |
of_play_named (string as_name) → long | Un sonido SINTETIZADO, sin archivo, al volumen ii_volume: SOUND_SUCCESS, SOUND_ERROR, SOUND_WARNING, SOUND_INFO, SOUND_NOTIFY. Un canal aparte: of_play no lo corta, of_stop sí. Devuelve 0 una vez lanzado, -2 si el reproductor no pudo crearse; un nombre desconocido llega por ue_failed (REASON_UNKNOWN) |
of_play_named_sync (string as_name) → long | El mismo sonido, y la llamada vuelve a su final. Devuelve 0, -2 si el reproductor no pudo crearse, -4 con un nombre desconocido, sin salida de audio o si otro sonido síncrono ya espera (is_last_error) |
of_has_output ( ) → boolean | Verdadero si el equipo tiene salida de audio: a preguntar ANTES de una alerta. El sonido va siempre a la salida por defecto de Windows |
of_equalizer (boolean ab_on {, integer ai_gains[]}) → long | Ecualizador de 5 bandas (60 / 230 / 910 / 3600 / 14000 Hz, of_eq_frequencies da los centros), ganancia en dB de -24 a 24 (un valor fuera se lleva al límite más cercano); la sobrecarga pone todas las ganancias, of_equalizer_band una en directo. Archivos LOCALES. Devuelve 0 una vez hecho, -2 si el reproductor no pudo crearse |
of_equalizer_band (integer ai_band, integer ai_gain) → long | Establece la ganancia de UNA banda (ai_band de 1 a 5, ai_gain en dB, de -24 a 24) y la aplica al instante al sonido que suena — un cursor suyo movido en directo; las demás bandas conservan su ganancia. Devuelve 0, -5 si la banda está fuera de rango, -2 si el reproductor no pudo crearse |
of_eq_frequencies (ref long al_freqs[]) → long | Rellena al_freqs con la frecuencia central de cada banda, en Hz y en orden (60, 230, 910, 3600, 14000) — lo que muestra una etiqueta de banda propia. Devuelve el número de bandas, 5 |
of_meter (boolean ab_on {, integer ai_bars}) → long | Enciende un vúmetro / analizador: consulte luego of_level (0 a 100) y of_spectrum (ai_bars barras) desde un temporizador para dibujar su propio visualizador. Archivos LOCALES. Devuelve 0 una vez hecho, -2 si el reproductor no pudo crearse |
of_level ( ) → long | Devuelve el nivel sonoro del instante, 0 a 100, leído en vivo — la aguja de un vúmetro; 0 cuando el medidor (of_meter) está apagado o nada suena. Sondéelo desde un temporizador |
of_spectrum (ref long al_bars[]) → long | Rellena al_bars con el espectro, leído en vivo: tantos valores como pidió of_meter, 0 a 100 cada uno, graves primero — las barras de un analizador propio. Devuelve el número de barras, 0 con el medidor apagado |
of_crossfade (string as_source, long al_ms) → long | Fundido encadenado: el sonido actual se apaga en al_ms mientras la nueva fuente sube — un cambio de pista sin corte; 0 cambia al instante. El nuevo sonido toma ii_volume, ii_rate, ii_pan e ib_loop, y un of_fade_to durante la subida toma el control. of_stop durante el fundido detiene ambos, y un of_play_sync que esperaba el primer sonido vuelve. Devuelve 0 una vez lanzado, -2 si el reproductor no pudo crearse; una fuente vacía llega por ue_failed |
of_process_events ( ) | Vacía la cola de eventos y los lanza en el objeto. El pump interno del componente lo llama por usted mientras el reproductor está abierto — usted nunca lo llama |
of_close ( ) | Libera el reproductor, deteniendo primero el sonido: un sonido que sonaba termina con su ue_stopped, lanzado antes del retorno; se hace por usted al destruir el objeto |
of_reset ( ) | Detiene el sonido y devuelve cada ajuste a su valor por defecto |
Eventos #
| Evento | Cuándo |
|---|---|
ue_started (string as_source, long al_duration_ms) | El sonido empieza de verdad — una URL, cuando han llegado datos suficientes. al_duration_ms es la longitud cuando el archivo la indica, 0 si no |
ue_ended (string as_source, boolean ab_truncated) | El sonido terminó por sí mismo. ab_truncated es verdadero cuando el límite demo lo cortó, nunca con licencia. Un sonido en bucle no termina: se detiene |
ue_failed (string as_source, string as_message, string as_reason) | El sonido no pudo sonar. as_reason es una palabra que comprobar, una constante REASON_*: REASON_INSECURE (dirección http://), REASON_FORMAT (formato rechazado por su nombre), REASON_UNSUPPORTED (archivo ausente, dirección file:// mal formada), REASON_NETWORK, REASON_DECODE, REASON_NO_SOURCE, REASON_UNKNOWN (sonido con nombre inexistente), REASON_UNAVAILABLE (sin salida de audio), REASON_FAILED; as_message es la frase que mostrar. Un sonido de la cola que falla no detiene la cola |
ue_stopped ( ) | Lanzado una vez cuando of_stop (o of_close, o el fin de il_timeout_ms) cortó lo que sonaba — no cuando un sonido termina solo, eso es ue_ended |
ue_paused ( ) / ue_resumed ( ) | El sonido se suspende, luego se reanuda |
ue_progress (long al_position_ms, long al_duration_ms) | Una vez por segundo de reloj durante la reproducción, sea cual sea ii_rate: posición y duración |
ue_queue_done ( ) | El último sonido de la cola (of_enqueue) ha terminado |
Varios sonidos, fundidos, cola #
- El canal principal y la superposición.
of_play,of_pause,of_seek,of_stoppilotan UN sonido: una música, un timbre.of_play_overreproduce un segundo encima, sin cortar nada — una alerta sobre un fondo.ue_endednombra cada uno por su fuente. Cada verbo ajusta SU sonido:ii_volumeeii_rateentregados conof_play_overvalen para la superposición, no para el fondo — una alerta a 100 sobre un fondo bajado a 20 porof_fade_to, el fondo sigue a 20. Los pitidos y los sonidos con nombre son canales aparte:of_playno los corta, soloof_stopcorta todo. - La cola.
of_enqueueespera el final del sonido en curso;ue_queue_donedice cuándo terminó el último. Un sonido que falla (ue_failed) no silencia los siguientes.of_playsigue siendo el verbo que corta. - Los fundidos.
il_fade_mshace subir cada inicio desde el silencio y apagarse cada parada;of_fade_tobaja el fondo durante un anuncio. Nada brusco. - Los sonidos nombrados.
of_play_named(SOUND_SUCCESS)y sus cuatro hermanos están sintetizados: nada que entregar, nada que buscar en el disco. - Antes de la alerta.
of_preloadabre el archivo por adelantado,of_has_outputdice si el equipo tiene salida. El sonido va a la salida por defecto de Windows: el motor solo da el id de una salida a una página con acceso a los medios, que un equipo corriente no concede — elegir una salida no se ofrece, por tanto. - El balance (
ii_pan) vale para archivos del equipo. Una URL suena sin balance: el navegador se niega a meter un sonido de otro sitio en su grafo de audio (CORS), y no es un ajuste. - Sin grabación. Capturar el micrófono es otro componente; este reproduce.
// 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)
Ejemplos #
Una señal de dos notas, sin ningún archivo #
// 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 elegido por el usuario, con una barra de progreso #
// 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
Un timbre en bucle hasta que el usuario actúe #
// 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()
Buenas prácticas #
- Un solo objeto por ventana, abierto con ella (
of_open): el reproductor oculto cuesta unos cientos de milisegundos la primera vez, nada después. of_play_syncbloquea su script, y el ratón pasados 250 ms: la ventana se repinta, pero todos los componentes PBToolboxAI de la aplicación muestran el reloj de arena e ignoran los clics hasta el retorno; y los eventos del componente como los temporizadores de sus ventanas siguen llegando durante la espera — un sonido síncrono pedido desde uno de ellos se rechaza (-4). Resérvelo para sonidos cortos — un carillón, un aviso — y useof_playpara música.- Un archivo ausente no es una excepción:
of_play_syncdevuelve-4,of_playlanzaue_failed, eis_last_errornombra el archivo.