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
PlaySoundlimitado 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 visual | n_pbt_soundplayer |
| Serve para | Um carrilhão antes de uma mensagem, um alerta, uma música de espera, um mp3 escolhido pelo utilizador, um fluxo da Internet |
| Princípio | Uma 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ência | O 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. 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")
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.
Ficheiro ou URL, e porque é que uma peça longa começa de imediato #
- Um ficheiro do posto é qualquer caminho que o PowerBuilder saiba nomear — absoluto, relativo à pasta da aplicação, de rede. A DLL serve-o ao leitor em fluxo, por fatias, com os pedidos de intervalo que um leitor emite para avançar na peça: nada é carregado em memória, e
of_seeké imediato. - Um URL
httpsé passado tal como está: o som começa assim que o seu início chegou. Um endereçohttp://é recusado (ue_failed,REASON_INSECURE): a página do leitor é servida em https, e o motor subiria o endereço para https ou bloqueá-lo-ia — um servidor de intranet sem TLS pareceria inexistente. Transfira-o primeiro (restclient.of_downloadpara um ficheiro temporário). Um média não está sujeito ao CORS, ao contrário de uma chamada a uma API — vejarestclientpara esse caso. - Um bip (
of_beep,of_beep_sync) não precisa de qualquer ficheiro: um oscilador do motor áudio, à frequência e pela duração que indicar.
Propriedades #
| Propriedade | Tipo | Predefinição | Função |
|---|---|---|---|
ii_volume | integer | 100 | Volume 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_loop | boolean | false | Verdadeiro 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 |
is_last_error | string | "" | Porque falhou a última chamada: ficheiro ausente, formato não descodificável, endereço http://, URL muda, sem saída áudio. Preenchido também por ue_failed. Após um of_play_sync que devolveu 0: "stopped" se o som foi cortado em vez de tocado até ao fim |
il_timeout_ms | long | 300000 | A 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 o som é cortado (segue-se ue_stopped). 0 ou menos: sem limite |
ii_rate | integer | 100 | Velocidade 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_pan | integer | 0 | Balanç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_ms | long | 0 | Fundido em milissegundos: cada início sobe do silêncio, cada paragem ou pausa apaga-se |
ipo_owner | powerobject | null | O 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étodo | Função |
|---|---|
of_open ( ) → long | Cria 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 (is_last_error diz porquê) |
of_is_open ( ) → boolean | Verdadeiro assim que o leitor existe |
of_play (string as_source {, long al_start_ms}) → long | Toca sem esperar: um ficheiro do posto ou um URL https (um endereço http:// é recusado, REASON_INSECURE), 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; um bip ou um som com nome continua. Devolve 0 uma vez lançado, -2 se o leitor não pôde ser criado, -4 se a página não respondeu |
of_play_sync (string as_source) → long | Toca 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 (is_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 (o som é cortado) ou se outro som síncrono já espera |
of_beep (long al_hz, long al_ms) → long | Um som puro sem ficheiro: al_hz (20 a 20 000) durante al_ms milissegundos (10 a 5 000), ao volume ii_volume. 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, -2 se o leitor não pôde ser criado |
of_beep_sync (long al_hz, long al_ms) → long | O mesmo som, e a chamada regressa quando acaba: dois seguidos fazem um sinal de duas notas. Devolve 0, -2 se o leitor não pôde ser criado, ou -4 sem saída áudio ou se outro som síncrono já espera (is_last_error) |
of_stop ( ) | Para 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 |
of_pause ( ) → long | Suspende o som onde está; of_resume retoma-o. Devolve 0 uma vez feito, -2 se o leitor não pôde ser criado |
of_resume ( ) → long | Retoma o som onde of_pause o deixou. Devolve 0 uma vez feito, -2 se o leitor não pôde ser criado |
of_seek (long al_ms) → long | Coloca-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. 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 ( ) → boolean | Verdadeiro 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 ( ) → boolean | Verdadeiro enquanto o som está suspenso por of_pause |
of_duration ( ) → long | O comprimento do som em milissegundos, 0 enquanto desconhecido; ue_started também o transporta |
of_position ( ) → long | Onde vai o som, em milissegundos — ler a partir de um timer para fazer avançar uma barra de progresso sua |
of_source ( ) → string | O que of_play recebeu por último, tal como está |
of_play_over (string as_source) → long | Toca 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); ue_ended nomeia-o pela sua fonte, of_stop para-o com o resto. Devolve 0 uma vez feito, -2 se o leitor não pôde ser criado |
of_enqueue (string as_source) → long | Põ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 que não pode tocar dispara ue_failed e a fila continua. Devolve 0 uma vez feito, -2 se o leitor não pôde ser criado |
of_clear_queue ( ) → long | Esquece os sons em espera, sem cortar o que toca; ue_queue_done segue-se na mesma ao seu fim, é o último som da fila. Devolve 0 uma vez feito, -2 se o leitor não pôde ser criado |
of_queue_count ( ) → long | Devolve o número de sons ainda em espera |
of_preload (string as_source) → long | Carrega um som sem o tocar: o primeiro of_play dessa fonte arranca de imediato. Uma fonte ilegível é assinalada por esse of_play, através de ue_failed. Devolve 0 uma vez feito, -2 se o leitor não pôde ser criado |
of_fade_to (integer ai_volume, long al_ms) → long | Leva 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) → long | Um 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) → long | O 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 (is_last_error) |
of_has_output ( ) → boolean | Verdadeiro 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[]}) → long | Equalizador 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, 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) → long | Define 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[]) → long | Preenche 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}) → long | Liga 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, -2 se o leitor não pôde ser criado |
of_level ( ) → long | Devolve 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[]) → long | Preenche 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) → long | Fundido encadeado: o som atual apaga-se em al_ms 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. Devolve 0 uma vez lançado, -2 se o leitor não pôde ser criado; uma fonte vazia chega por ue_failed |
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 ( ) | Liberta o leitor, parando primeiro o som: um som que tocava termina com o seu ue_stopped, disparado antes do regresso; feito por si na destruição do objeto |
of_reset ( ) | Pára o som e repõe cada definição no seu valor predefinido |
Eventos #
| Evento | Quando |
|---|---|
ue_started (string as_source, long al_duration_ms) | 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 |
ue_ended (string as_source, boolean ab_truncated) | 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 |
ue_failed (string as_source, string as_message, string as_reason) | O som não pôde tocar. 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_FAILED; as_message é a frase a mostrar. Um som da fila que falha não para a fila |
ue_stopped ( ) | Disparado uma vez quando of_stop (ou of_close, ou o fim de il_timeout_ms) 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 |
Vários sons, fundidos, fila #
- O canal principal e a sobreposição.
of_play,of_pause,of_seek,of_stoppilotam UM som: uma música, um toque.of_play_overtoca um segundo por cima, sem cortar nada — um alerta sobre um fundo.ue_endednomeia cada um pela sua fonte. Cada verbo regula o SEU som:ii_volumeeii_rateentregues comof_play_overvalem para a sobreposição, não para o fundo — um alerta a 100 sobre um fundo baixado para 20 porof_fade_to, o fundo fica a 20. Os bips e os sons com nome são canais à parte:of_playnão os corta, sóof_stopcorta tudo. - A fila.
of_enqueueespera o fim do som em curso;ue_queue_donediz quando o último acabou. Um som que falha (ue_failed) não silencia os seguintes.of_playcontinua a ser o verbo que corta. - Os fundidos.
il_fade_msfaz subir cada início do silêncio e apagar cada paragem;of_fade_tobaixa o fundo durante um anúncio. Nada brusco. - Os sons nomeados.
of_play_named(SOUND_SUCCESS)e os seus quatro irmãos são sintetizados: nada a entregar, nada a procurar no disco. - Antes do alerta.
of_preloadabre o ficheiro antecipadamente,of_has_outputdiz se o posto tem saída. O som vai para a saída predefinida do Windows: o motor só dá o id de uma saída a uma página com acesso aos média, que um posto comum não concede — escolher uma saída não é, portanto, proposto. - O balanço (
ii_pan) vale para ficheiros do posto. Um URL toca sem balanço: o navegador recusa-se a meter um som de outro site no seu grafo áudio (CORS), e isso não é uma definição. - Sem gravação. Captar o microfone é outro componente; este toca.
// 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)
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
// 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
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 #
- Um só objeto por janela, aberto com ela (
of_open): o leitor oculto custa algumas centenas de milissegundos na primeira vez, nada depois. of_play_syncbloqueia o seu script, e o rato passados 250 ms: a janela repinta-se, mas todos os componentes PBToolboxAI da aplicação mostram a ampulheta e ignoram os cliques até ao regresso; e os eventos do componente como os temporizadores das suas janelas continuam a chegar durante a espera — um som síncrono pedido a partir de um deles é recusado (-4). Reserve-o para sons curtos — um carrilhão, um aviso — e useof_playpara música.- Um ficheiro ausente não é uma exceção:
of_play_syncdevolve-4,of_playdisparaue_failed, eis_last_errornomeia o ficheiro.