MyGo 云音乐
Go와 MyGo로 만든 서드파티 네이버 클라우드 뮤직 데스크톱 클라이언트
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Pads de som que tocam no instante do toque, direto no navegador — incluindo o Safari do iPhone. No iPhone: abra esse endereço no Safari e faça Compartilhar → Adicionar à Tela de Início. Vira um app em tela cheia que funciona offline. O terminal mostra dois endereços: um para este Mac e um para o iPhone (precisa estar no mesmo Wi-Fi). Não há dependências nem build — é HTML, CSS e JS puros, então o que roda local é exatamente o que está publicado. Publicar uma mudança é só git push: o GitHub Pages serve a branch main.README 전문 보기 ↗
Pads de som que tocam no instante do toque, direto no navegador — incluindo o Safari do iPhone.
No ar em https://ruansantos01.github.io/SoundPad/
No iPhone: abra esse endereço no Safari e faça Compartilhar → Adicionar à Tela de Início. Vira um app em tela cheia que funciona offline.
node serve.mjs
O terminal mostra dois endereços: um para este Mac e um para o iPhone (precisa estar no mesmo Wi-Fi). Não há dependências nem build — é HTML, CSS e JS puros, então o que roda local é exatamente o que está publicado.
Publicar uma mudança é só git push: o GitHub Pages serve a branch main.
Eles ficam no IndexedDB, no navegador daquele aparelho. Três riscos, em ordem de probabilidade:
Contra os dois primeiros o app pede navigator.storage.persist() ao abrir. Medido no
Safari do iOS (simulador, iPhone 16 Pro):
| Como o app foi aberto | persist() |
|---|---|
| Aba normal do Safari | negado |
| Ícone na Tela de Início (standalone) | concedido |
Ou seja: adicionar à Tela de Início é o que protege os sons, não só conforto de tela cheia. Quando o pedido é negado e existem sons próprios carregados, o app mostra um aviso.
Contra o terceiro risco (limpeza manual, ou apagar o ícone) não há API que ajude — só uma cópia dos arquivos originais resolve.
O iOS abre toda página com o áudio suspenso, e suspende de novo toda vez que o app vai para segundo plano (trocar de app, ligação, bloquear a tela). O indicador ao lado do título fica cinza quando isso acontece.
O toque seguinte resolve, e o som desse toque sai — não é um toque desperdiçado. Isso
exigiu cuidado: medido no Safari do iOS, com o contexto suspenso o start() não toca nada
e o onended nunca dispara, ou seja, a voz é descartada em silêncio. Como resume()
é assíncrono, "retomar e tocar na linha seguinte" era uma corrida que às vezes perdia — era
essa a causa do som falhar de forma intermitente.
Hoje o trigger() dispara na hora quando o contexto está de pé, e quando não está,
destrava dentro do gesto e só solta a voz depois que o contexto volta.
Cada pasta é uma situação — uma live, um podcast, um set — com 16 pads próprios.
A barra logo abaixo do título lista as pastas; o + cria mais.
← e → trocam de pasta.disparo — toca até o fimsegurar — toca enquanto o dedo estiver no padloop — toca em ciclo; o segundo toque desliga1234 QWER ASDF ZXCV tocam os 16 pads.Para montar uma pasta de 16 sons sem repetir o mesmo caminho 16 vezes: Editar → toque no nome da pasta → Carregar vários sons… → selecione tudo de uma vez. Os arquivos entram nos pads vazios, na ordem, e o nome de cada pad vira o nome do arquivo. Pads que já têm som são preservados. Se sobrarem arquivos além dos 16 pads, o app diz quantos ficaram de fora; se algum arquivo não puder ser lido, ele diz qual.
A pasta "Bateria" vem com 16 sons sintetizados pelo próprio navegador — nenhum arquivo para baixar. Seus arquivos (MP3, M4A, WAV, AAC) ficam salvos no aparelho, no IndexedDB, e voltam sempre que você reabrir.
Web Audio API com o áudio já decodificado na memória. Um <audio>.play() no iOS
custa de dezenas a centenas de milissegundos; AudioBufferSourceNode.start() dispara no
próximo bloco de áudio.
Evento touchstart, não click. O iOS só emite click no fim do toque, e com
atraso. Medido aqui: 0,2 ms entre o toque e o disparo.
latencyHint: 'interactive' pede ao sistema o menor buffer de saída possível.
Não forçamos navigator.audioSession.type. A tentação é usar 'playback' para
tocar com a chavinha de silencioso ligada. Medido no Safari do iOS, com dois contextos
novos e idênticos:
audioSession | estado | tocou |
|---|---|---|
auto (padrão) | running | sim, imediato |
playback | interrupted | não |
O buffer de saída é o mesmo nos dois (2,7 ms): 'playback' simplesmente derruba a
sessão. Preço de ficar no padrão: com o silencioso ligado o iOS pode calar o som —
se um pad não sair, confira a chavinha lateral.
O limitador é um WaveShaper, não um DynamicsCompressor. Medido nos dois motores, o compressor custa 6 ms de atraso na entrada e 6 ms de cauda depois que a fonte para — ele atrasa tudo para antecipar picos. O WaveShaper satura amostra a amostra: zero atraso, zero cauda, e ainda segura pico de 2,5 em 0,93.
O que sobra é a latência do próprio hardware de saída. Entre em Editar para ver o número
do seu aparelho — o app mostra saída ~N ms. Alto-falante ou fone com fio ficam na casa
de 10–40 ms; fone Bluetooth costuma somar 150–300 ms, e nenhuma linha de código muda isso.
index.html | estrutura da tela |
app.js | motor de áudio, pastas, pads, toque, persistência |
styles.css | visual |
sw.js + manifest.webmanifest | instalação na tela de início e uso offline |
serve.mjs | servidor local para testar no iPhone |
vercel.json | cabeçalhos do deploy na Vercel (ver abaixo) |
O app é estático: qualquer host serve. Hoje está no GitHub Pages, publicado a cada
git push na main.
O vercel.json existe para três coisas que quebram um PWA se ficarem no padrão:
sw.js sem cache. Se o service worker vier de cache, uma versão antiga do app fica
presa no aparelho e nenhum deploy novo chega.manifest.webmanifest com application/manifest+json. Sem o tipo certo o iOS
ignora o manifest e o "Adicionar à Tela de Início" perde nome e ícone.app.js / styles.css revalidando sempre. Os nomes não têm hash, então sem isso o
navegador segura a versão velha.Atenção ao trocar de endereço: cada domínio tem seu próprio armazenamento. Os sons
ficam no IndexedDB, que é por origem — o que você carregou em github.io não aparece em
vercel.app. Escolha um endereço e fique nele.