PBToolboxAI v5 ← Site

soundplayer — n_pbt_soundplayer #

← Referência dos componentes · Índice do guia

Toca um som ou uma música — um ficheiro do posto ou um URL — de forma assíncrona (eventos) ou síncrona (a chamada regressa quando o som termina), e um bip puro sem qualquer ficheiro. Todos os formatos que o motor WebView2 descodifica: mp3, wav, ogg, opus, flac, aac, m4a, mp4, webm. Sem DLL de terceiros, sem PlaySound limitado a wav.

▶ Ver ao vivo — Aplicação de demonstração, mosaico Sound player: os sons, o código que os toca e esta página, lado a lado.


Em resumo #

Objeto não visualn_pbt_soundplayer
Serve paraUm carrilhão antes de uma mensagem, um alerta, uma música de espera, um mp3 escolhido pelo utilizador, um fluxo da Internet
PrincípioUma página oculta tem um leitor; of_play regressa de imediato e os eventos contam o resto, of_play_sync espera o fim do som
DependênciaO runtime WebView2, já exigido pela biblioteca — nada mais

Início 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
inv_sound.ii_volume = 60
inv_sound.of_play(/*source*/ "https://example.org/music/lobby.mp3")

// When the window closes : the hidden player goes with the object
destroy inv_sound

Os eventos ue_* são entregues sozinhos — o componente recolhe-os enquanto o leitor está aberto e dispara-os no componente: nada a ligar, nem recetor nem temporizador.

Onde escrever os eventos #

Um objeto criado por create n_pbt_soundplayer serve muito bem os sons síncronos e os que se lançam sem esperar notícias — é o que faz o início rápido —, mas os seus eventos não têm qualquer script: o PowerBuilder não permite escrever ue_ended num objeto criado num script. Para reagir aos eventos, duas vias:

Não destrua o leitor a partir de um dos seus próprios eventos: of_close basta, e a destruição do objeto fá-lo por si.


Ficheiro ou URL, e porque é que uma peça longa começa de imediato #


Propriedades #

PropriedadeTipoPredefiniçãoFunção
ii_volumeinteger100Volume em percentagem, de 0 a 100, entregue com o verbo que lança um som — e é o volume DESSE som: of_play, of_play_sync e of_crossfade regulam o som principal; of_play_over, of_beep e of_play_named tocam o seu a esse volume sem tocar no som principal (um alerta a 100 sobre um fundo baixado para 20); um som posto em fila por of_enqueue guarda-o para a sua vez. Alterado enquanto um som toca, espera pelo verbo seguinte — só of_fade_to muda o som em curso
ib_loopbooleanfalseVerdadeiro para repetir o som em ciclo até of_stop — um toque, uma música de fundo. Entregue com o som seguinte. of_play_sync ignora-o: um som síncrono toca uma vez, um ciclo não tem fim para esperar. Um som em ciclo nunca termina: a fila (of_enqueue) espera atrás dele até of_stop, of_next ou of_stop_sound
il_timeout_mslong300000A duração máxima de um som síncrono (of_play_sync, of_beep_sync, of_play_named_sync); cinco minutos por predefinição. Passado esse prazo a chamada devolve -4 e esse som é cortado (segue-se ue_stopped) — só ele: um fundo, as sobreposições e a fila continuam. 0 ou menos: 24 horas
ii_rateinteger100Velocidade em percentagem (25 a 400), entregue com o verbo que lança um som, para ESSE som: o som principal, ou uma sobreposição (of_play_over) sem mudar o principal
ii_paninteger0Balanço do som PRINCIPAL, de -100 (esquerda) a 100 (direita), entregue com of_play, of_play_sync ou of_crossfade, para FICHEIROS; um URL toca sem balanço
il_fade_mslong0Fundido em milissegundos (10 000 no máximo): cada início sobe do silêncio, cada of_stop ou pausa apaga-se, uma retoma volta a subir; ue_stopped chega na mesma de imediato
ib_gapless_loopbooleanfalseCom ib_loop, um ficheiro CURTO do posto repete-se sem interrupções: descodificado uma vez, encadeia-se sem costura — um toque, um fundo musical. 4 MB e 60 segundos no máximo (além disso, ue_failed com REASON_TOO_LONG); um URL repete-se da forma habitual. Entregue com o verbo, como ib_loop
ib_mutedbooleanfalseTodos os sons do leitor em silêncio de imediato — o som principal, as sobreposições, os bips, os sons com nome — ii_volume mantido: false devolve o som ao mesmo nível. Em direto
ib_queue_repeatbooleanfalseA fila (of_enqueue) recomeça depois do seu último som, uma e outra vez; of_next depois do último vai para o primeiro, of_previous antes do primeiro para o último. Uma fila cujos sons falham todos para na mesma. Em direto
ipo_ownerpowerobjectnullO objeto visual para o qual este leitor trabalha: a licença verifica-se na sua classe. Necessário apenas na aplicação de demonstração; uma chave de desenvolvimento ou de execução desbloqueia o leitor sem ele. Não desbloqueado, o leitor está em modo demo — só os 10 primeiros segundos de um som são tocados

Métodos #

MétodoFunção
of_get_last_error ( ) → stringPorque falhou a última chamada: ficheiro ausente, formato não descodificável, endereço http://, URL muda, sem saída áudio, número de um som que já não está em curso. Preenchido também por ue_failed e após cada -5. Após um of_play_sync que devolveu 0: "stopped" se o som foi cortado em vez de tocado até ao fim
of_open ( ) → longCria o leitor. Facultativo — cada método o faz — mas chamá-lo ao abrir a janela paga o custo uma vez. Devolve o handle (> 0), ou -2 se o leitor não pôde ser criado (of_get_last_error() diz porquê)
of_is_open ( ) → booleanVerdadeiro assim que o leitor existe
of_play (string as_source {, long al_start_ms}) → longToca sem esperar: um ficheiro do posto ou um URL https, o fim chega por ue_ended. al_start_ms faz começar o som nesse ponto (em modo demo, nunca para além dos 10 primeiros segundos). O som principal em curso é substituído, sem evento; um bip ou um som com nome continua. Devolve 0 uma vez lançado, -5 se a fonte for recusada de imediato — vazia, um endereço http://, um endereço file:// mal formado, um formato recusado pelo nome: of_get_last_error() diz qual, o som em curso continua e nenhum ue_failed se segue —, -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_play_sync (string as_source) → longToca e espera pelo fim: a chamada regressa quando o som acabou (ou foi parado). A janela continua a repintar-se, mas passados 250 ms todos os componentes PBToolboxAI da aplicação mostram a ampulheta e ignoram o rato até ao regresso: reserve-o para sons curtos. Toca uma vez, diga o que disser ib_loop. Devolve 0 uma vez terminado o som (of_get_last_error() = "stopped" se foi cortado), -2 se o leitor não pôde ser criado, -4 se não pôde tocar, se il_timeout_ms expirou (só esse som é cortado) ou se outro som síncrono já espera
of_beep (long al_hz, long al_ms) → longUm som puro sem ficheiro: al_hz (20 a 20 000) durante al_ms milissegundos (10 a 5 000), ao volume ii_volume; um valor além de um limite é trazido de volta a ele. Um canal à parte: of_play não o corta, of_stop sim. Regressa de imediato; segue-se ue_ended. Devolve 0 uma vez lançado, -5 se al_hz ou al_ms valer 0 ou menos (uma variável não inicializada não toca um bip predefinido), -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_beep_sync (long al_hz, long al_ms) → longO mesmo som, e a chamada regressa quando acaba: dois seguidos fazem um sinal de duas notas. Devolve 0, -5 se al_hz ou al_ms valer 0 ou menos, -2 se o leitor não pôde ser criado, ou -4 sem saída áudio, se il_timeout_ms expirou (só o bip é cortado) ou se outro som síncrono já espera (of_get_last_error())
of_stop ( ) → longPara tudo o que o leitor toca — o som, um bip, um som com nome, as sobreposições, um fundido encadeado — e esvazia a fila; segue-se um ue_stopped, de imediato. Com il_fade_ms, o som principal apaga-se durante esse tempo em vez de parar de repente Devolve 0 uma vez feito.
of_pause ( ) → longSuspende o som onde está (sobre il_fade_ms); of_resume retoma-o. Devolve 0 uma vez feito, -5 se não houver nada a suspender — nenhum som principal, ou já em pausa; um bip ou uma sobreposição não se suspendem —, -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_resume ( ) → longRetoma o som onde of_pause o deixou. Devolve 0 uma vez feito, -5 se nenhum som estiver em pausa, -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_seek (long al_ms) → longColoca-se numa posição do som, em milissegundos desde o início. Em modo demo, nunca para além dos 10 primeiros segundos. Para COMEÇAR numa posição, of_play aceita uma: o leitor não guarda nenhum som parado onde se deslocar. Devolve 0 uma vez feito, -5 se nenhum som toca (nada a mover), -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_is_playing ( ) → booleanVerdadeiro enquanto um som, um bip, um som com nome ou uma sobreposição está em curso — um som em pausa conta, não terminou
of_is_paused ( ) → booleanVerdadeiro enquanto o som está suspenso por of_pause
of_duration ( ) → longO comprimento do som em milissegundos, 0 enquanto desconhecido; ue_started também o transporta
of_position ( ) → longOnde vai o som, em milissegundos — ler a partir de um timer para fazer avançar uma barra de progresso sua
of_source ( ) → stringO que of_play recebeu por último, tal como está
of_play_over (string as_source) → longToca um som POR CIMA do que toca, sem o cortar, a ii_volume e ii_rate — os seus: o fundo guarda os seus (um fundo baixado por of_fade_to fica baixo sob um alerta a 100); of_stop_sound para-o sozinho, of_stop com o resto. Devolve o número do som (> 0) — os seus eventos transportam-no, duas sobreposições do mesmo ficheiro distinguem-se por ele —, -5 se a fonte for recusada de imediato, -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_enqueue (string as_source) → longPõe um som em FILA: tocado de imediato se o leitor está livre, após o som (ou o bip, ou o som com nome) em curso caso contrário, nunca cortado. O som em fila guarda ii_volume, ii_rate e ib_loop tal como estão na chamada, para a sua vez; um som em ciclo nunca termina, a fila espera atrás dele. Um som que não pode tocar dispara ue_failed na sua vez e a fila continua. A fila guarda o que tocou: of_next, of_previous. Devolve o número do som (> 0), -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_clear_queue ( ) → longEsquece a fila — os sons em espera e os que já tocou —, sem cortar o que toca; ue_queue_done segue-se na mesma ao seu fim. Devolve 0 uma vez feito, -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_queue_count ( ) → longDevolve o número de sons ainda em espera
of_preload (string as_source) → longCarrega um som sem o tocar: o primeiro of_play dessa fonte arranca de imediato. Um ficheiro que se revela ilegível é assinalado por esse of_play, através de ue_failed. Devolve 0 uma vez feito, -5 se a fonte for recusada de imediato (of_get_last_error() diz porquê), -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_fade_to (integer ai_volume, long al_ms) → longLeva o volume a ai_volume (0 a 100) em al_ms ms no som que toca; o alvo passa a ser ii_volume, e um som tocado por cima entretanto não interrompe o fundido. Devolve 0 uma vez feito, -2 se o leitor não pôde ser criado
of_play_named (string as_name) → longUm som SINTETIZADO, sem ficheiro, ao volume ii_volume: SOUND_SUCCESS, SOUND_ERROR, SOUND_WARNING, SOUND_INFO, SOUND_NOTIFY. Um canal à parte: of_play não o corta, of_stop sim. Devolve 0 uma vez lançado, -2 se o leitor não pôde ser criado; um nome desconhecido chega por ue_failed (REASON_UNKNOWN)
of_play_named_sync (string as_name) → longO mesmo som, e a chamada regressa no seu fim. Devolve 0, -2 se o leitor não pôde ser criado, -4 com um nome desconhecido, sem saída áudio ou se outro som síncrono já espera (of_get_last_error())
of_has_output ( ) → booleanVerdadeiro se o posto tem saída áudio: a perguntar ANTES de um alerta. O som vai sempre para a saída predefinida do Windows
of_equalizer (boolean ab_on {, integer ai_gains[]}) → longEqualizador de 5 bandas (60 / 230 / 910 / 3600 / 14000 Hz, of_eq_frequencies dá os centros), ganho em dB de -24 a 24 (um valor fora é trazido ao limite mais próximo); a sobrecarga define todos os ganhos (uma banda que o array não alcança volta a 0), of_equalizer_band um em direto. Ficheiros LOCAIS. Devolve 0 uma vez feito, -2 se o leitor não pôde ser criado
of_equalizer_band (integer ai_band, integer ai_gain) → longDefine o ganho de UMA banda (ai_band de 1 a 5, ai_gain em dB, de -24 a 24) e aplica-o de imediato ao som que toca — um cursor seu movido em direto; as outras bandas mantêm o seu ganho. Devolve 0, -5 se a banda estiver fora dos limites, -2 se o leitor não pôde ser criado
of_eq_frequencies (ref long al_freqs[]) → longPreenche al_freqs com a frequência central de cada banda, em Hz e por ordem (60, 230, 910, 3600, 14000) — o que um rótulo de banda seu mostra. Devolve o número de bandas, 5
of_meter (boolean ab_on {, integer ai_bars}) → longLiga um vúmetro / analisador: consulte depois of_level (0 a 100) e of_spectrum (ai_bars barras) a partir de um temporizador para desenhar o seu próprio visualizador. Ficheiros LOCAIS. Devolve 0 uma vez feito, -5 se ai_bars sair de 1 a 64 (nada muda), -2 se o leitor não pôde ser criado
of_level ( ) → longDevolve o nível sonoro do instante, 0 a 100, lido ao vivo — a agulha de um VU meter; 0 quando o medidor (of_meter) está desligado ou nada toca. Sondar a partir de um temporizador
of_spectrum (ref long al_bars[]) → longPreenche al_bars com o espectro, lido ao vivo: tantos valores quantos of_meter pediu, 0 a 100 cada, graves primeiro — as barras de um analisador seu. Devolve o número de barras, 0 com o medidor desligado
of_crossfade (string as_source, long al_ms) → longFundido encadeado: o som atual apaga-se em al_ms (10 000 no máximo) enquanto a nova fonte sobe — uma mudança de faixa sem corte; 0 muda de imediato. O novo som toma ii_volume, ii_rate, ii_pan e ib_loop, e um of_fade_to durante a subida toma o controlo. of_stop durante o fundido para ambos, e um of_play_sync que esperava o primeiro som regressa; o som substituído não dispara nada. Devolve 0 uma vez lançado, -5 se a fonte for recusada de imediato — o som em curso continua então, intacto —, -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_play_range (string as_source, long al_from_ms, long al_to_ms) → longToca um SEGMENTO de um ficheiro, de al_from_ms a al_to_ms — um banco de sons curtos num só ficheiro, cada um tocado pelos seus limites. Substitui o som principal como of_play, com as suas definições; com ib_loop o segmento volta a tocar desde o início. ue_ended no seu fim. Devolve 0 uma vez lançado, -5 se al_from_ms for negativo, al_to_ms não vier depois, ou a fonte for recusada de imediato, -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_stop_sound (long al_sound) → longPara UM som pelo seu número (of_play_over e of_enqueue devolvem-no, os eventos transportam-no): uma sobreposição — as outras continuam —, o som principal (sobre il_fade_ms, a fila passando ao seguinte), um bip, um som com nome; segue-se um ue_stopped. Um som ainda EM ESPERA é retirado da fila, sem evento. Devolve 0 uma vez feito, -5 se nenhum som tiver agora esse número, -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_next ( ) → longToca de imediato o som SEGUINTE da fila — o som em curso é substituído, sem evento; com ib_queue_repeat, depois do último vem o primeiro. ue_source_changed diz onde está a fila. Devolve 0 uma vez feito, -5 se não houver som seguinte, -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_previous ( ) → longToca o som ANTERIOR ao que toca na fila — a fila guarda o que tocou; com a fila parada, o último tocado de novo. Com ib_queue_repeat, antes do primeiro vem o último. Devolve 0 uma vez feito, -5 se não houver, -2 se o leitor não pôde ser criado, -4 se a página não respondeu
of_queue_index ( ) → longDevolve o lugar na fila (1 = o primeiro som posto em fila) do som que toca, 0 quando esse som não vem da fila ou nada toca
of_is_buffering ( ) → booleanVerdadeiro enquanto o som corre mas espera pelos seus dados — o tempo anunciado por ue_buffering: um fluxo da Internet que congela, um salto longe num ficheiro lido de um URL. Um ficheiro do posto nunca espera
of_process_events ( )Esvazia a fila de eventos e dispara-os no objeto. O pump interno do componente chama-o por si enquanto o leitor está aberto — nunca o chama
of_close ( ) → longLiberta o leitor, parando primeiro o som, de imediato (sem fundido): um som que tocava termina com o seu ue_stopped, disparado antes do regresso; feito por si na destruição do objeto. Não destrua o leitor a partir de um dos seus eventos: of_close basta Devolve 0 uma vez feito.
of_reset ( ) → longPára o som e repõe cada definição no seu valor predefinido Devolve 0 uma vez feito.

Eventos #

EventoQuando
ue_started (string as_source, long al_duration_ms, long al_sound)O som começa realmente — um URL, assim que chegaram dados suficientes. al_duration_ms é o comprimento quando o ficheiro o diz, 0 caso contrário; al_sound é o número do som
ue_ended (string as_source, boolean ab_truncated, long al_sound)O som terminou por si. ab_truncated é verdadeiro quando o limite demo o cortou, nunca com licença. Um som em ciclo não termina: pára. Um som principal SUBSTITUÍDO por outro (of_play, of_crossfade, of_next…) não dispara nada: foi o seu script que o substituiu
ue_failed (string as_source, string as_message, string as_reason, long al_sound)O som não pôde tocar — uma fonte recusada de imediato por um método é o seu -5, não este evento. as_reason é uma palavra a testar, uma constante REASON_*: REASON_INSECURE (endereço http://), REASON_FORMAT (formato recusado pelo nome), REASON_UNSUPPORTED (ficheiro ausente, endereço file:// mal formado), REASON_NETWORK, REASON_DECODE, REASON_NO_SOURCE, REASON_UNKNOWN (som com nome inexistente), REASON_UNAVAILABLE (sem saída áudio), REASON_TOO_LONG (um ciclo sem interrupções de um ficheiro demasiado longo), REASON_FAILED (o resto, um erro de script da página incluído); as_message é a frase a mostrar, na língua de apresentação; al_sound o número do som. Um som da fila que falha não para a fila
ue_stopped ( )Disparado uma vez quando of_stop (ou of_close, of_stop_sound, ou o fim de il_timeout_ms para o som dessa chamada) cortou o que tocava — não quando um som termina sozinho, isso é ue_ended
ue_paused ( ) / ue_resumed ( )O som é suspenso, depois retoma
ue_progress (long al_position_ms, long al_duration_ms)Uma vez por segundo de relógio durante a reprodução, seja qual for ii_rate: posição e duração
ue_queue_done ( )O último som da fila (of_enqueue) terminou — nunca com ib_queue_repeat, a fila recomeça
ue_buffering (boolean ab_on)ab_on verdadeiro: o som corre mas espera pelos seus dados — um fluxo da Internet que congela, um salto longe num ficheiro lido de um URL; falso: volta a correr (ou é posto em pausa, parado, substituído, em erro). Uma espera de menos de um quarto de segundo não diz nada
ue_source_changed (long al_index, string as_source)A fila passa a um dos seus sons — por si, por of_next, of_previous ou ib_queue_repeat: al_index é o seu lugar na fila (1 = o primeiro som posto em fila), as_source o que foi posto em fila

Vários sons, fundidos, fila #

// 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)
// Local variables
long ll_first

// Two alerts of the same file : each one has its own number
ll_first = inv_sound.of_play_over(/*source*/ "C:\Windows\Media\Alarm01.wav")
inv_sound.of_play_over(/*source*/ "C:\Windows\Media\Alarm01.wav")

// Later : the first one stopped alone, the other goes on
inv_sound.of_stop_sound(/*sound*/ ll_first)

// A queue that starts over after its last sound, and the next sound right now
inv_sound.ib_queue_repeat = true
inv_sound.of_next()

// A ring that loops without a gap, then everything silent for a moment
inv_sound.ib_loop = true
inv_sound.ib_gapless_loop = true
inv_sound.of_play(/*source*/ "C:\Windows\Media\Ring05.wav")
inv_sound.ib_muted = true

Exemplos #

Um sinal de duas notas, sem qualquer ficheiro #

// 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)

Um mp3 escolhido pelo utilizador, com uma barra de progresso #

// Local variables
string ls_path, ls_file
constant unsignedlong OFN_EXPLORER = 2
constant unsignedlong OFN_NOCHANGEDIR = 64

// Let the user pick a music file - in the Explorer style, without moving the current folder of the application - then play it
if GetFileOpenName("Music", ls_path, ls_file, "mp3", "Music (*.mp3;*.wav;*.flac),*.mp3;*.wav;*.flac", /*initdir*/ "", OFN_EXPLORER + OFN_NOCHANGEDIR) = 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

Um toque em ciclo até o utilizador agir #

// 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()

Boas práticas #

← Referência dos componentes · Índice do guia