METAPHI
Markdown ↗
00 / Componentes: YouTube Jukeboxv3.0.0

Componente · Áudio · Web Component

Metaphi: YouTube Jukebox V3

Toca-discos de música de fundo para sites e sistemas: um disco no canto da tela, um leque de capas em 3D e o som do YouTube num player invisível. Um arquivo, JavaScript puro, sem dependências, que entra em qualquer página com uma linha.

Instalar

Clique em qualquer lugar da página para ouvir

Arquivo único
metaphi-jukebox.js
Tamanho
49 KB gzip
Dependências
0
API do YouTube
sem script · sem chave

Nesta página

O toca-discos já está aqui, no canto da tela.

Esta página usa o próprio componente, o mesmo arquivo que você instala. Abra o Customize e mude cores, posição, leque, reprodução e os recursos para sistemas: o disco do canto muda na hora, e o código acompanha.

Carregando o componente…

—

Eventos

    01

    Instalação

    Um arquivo só. Baixe para o seu projeto (recomendado: você controla a versão e não depende de outro site) ou carregue direto do metaphi.tech.

    1. Baixe para a pasta pública do projeto (public/, static/, www/…):

      Terminal
      curl -fsSL https://metaphi.tech/jukebox/v3/metaphi-jukebox.min.js -o metaphi-jukebox.js
    2. Carregue como módulo, uma vez por página, perto do fim do <body>:

      HTML
      <script type="module" src="/metaphi-jukebox.js"></script>
    3. Adicione o <metaphi-jukebox> com as suas músicas (veja Músicas) ou monte o seu no Customize e copie o código.

    02

    Músicas

    Cada música é um disco no leque. Use o id do vídeo ou o link inteiro. Um disco com playlist toca vários vídeos em sequência, e o próprio player passa de um ao outro (no celular, sem precisar de outro toque).

    HTML
    <metaphi-jukebox accent="#2d81ff" position="bottom-left">
      <script type="application/json">
        {
          "tracks": [
            { "id": "https://youtu.be/Wv5kt7d8p1A", "title": "City Ghosts", "subtitle": "NEROX · Gangster Trap" },
            { "id": "7MHgdIu7FlI", "title": "Soft Collision", "subtitle": "Titan Beats · Deep House Mix" },
            {
              "title": "Playlist da casa",
              "subtitle": "Shuffle · 3 faixas",
              "playlist": ["Tx9zMFodNtA", "SAd_oy2Sc3Y", "NEMsIHVejWM"],
              "cover": { "lg": "/musica/capa.webp", "sm": "/musica/capa-sm.webp" }
            }
          ]
        }
      </script>
    </metaphi-jukebox>
    CampoTipoDescrição
    idtextoId do vídeo (11 caracteres) ou o link inteiro (youtube.com/watch?v=…, youtu.be/…, /shorts/…, /live/…).
    titletextoTítulo no leque e no leitor de tela.
    subtitletextoLinha de baixo: artista, gênero, duração.
    playlisttexto[]Disco-playlist: vários vídeos, tocados em sequência pelo próprio player (sem precisar de outro toque no celular), com capa empilhada e selo "Playlist · N".
    covertexto | { lg, sm }Capa própria. Sem ela, a miniatura do YouTube (i.ytimg.com); na mídia própria, uma capa desenhada com o título.
    srctextoMídia própria: o endereço de um arquivo de áudio (mp3, m4a, ogg…) no seu servidor, no lugar do vídeo do YouTube. Toca por <audio>, sem bloqueios do YouTube, e pode tocar em segundo plano (background).

    Músicas sem direitos autorais já usadas

    Mixes da FreeWave Music, marcados pelo canal como "No Copyright" e já usados pelo autor em outro sistema. Confira sempre a licença na descrição do vídeo antes de usar.

    Playlist com músicas curtas

    Músicas comuns, de 3 a 5 minutos, acabam rápido e pediriam um toque a cada troca. O disco-playlist resolve: um disco só, com a pilha de capas e o selo "Playlist · N", que toca vários vídeos em sequência. A lista vai inteira para o player do YouTube, que passa de uma faixa à outra sozinho (no celular, sem precisar de outro toque) e recomeça no fim. É o que a METAPHI Playlist desta página faz, com 11 faixas.

    1. Crie um disco com playlist: a lista dos vídeos, por id ou link (youtu.be, watch?v=, /shorts). Dê um title, um subtitle e, de preferência, uma cover própria (sem ela, vale a miniatura do primeiro vídeo).

    2. A ordem é sorteada a cada vez que o disco começa (shuffle, ligado por padrão). Para tocar na ordem da lista, use shuffle="false".

    3. Vídeo indisponível dentro da lista é pulado. Para esconder os discos-playlist sem tirá-los do código, use show-playlists="false" (o Customize desta página tem as duas chaves no grupo Playlist).

    HTML
    <metaphi-jukebox shuffle>
      <script type="application/json">
        {
          "tracks": [
            { "id": "Wv5kt7d8p1A", "title": "City Ghosts", "subtitle": "NEROX · Gangster Trap" },
            {
              "title": "Playlist da casa",
              "subtitle": "Shuffle · 4 faixas",
              "cover": { "lg": "/musica/playlist.webp", "sm": "/musica/playlist-sm.webp" },
              "playlist": [
                "https://youtu.be/SAd_oy2Sc3Y",
                "https://www.youtube.com/watch?v=NEMsIHVejWM",
                "6QBy_Oa5ZmM",
                "YrLk4vdY28Q"
              ]
            }
          ]
        }
      </script>
    </metaphi-jukebox>

    Links de playlist do YouTube (list=…) não servem: liste os vídeos um a um. Dá para ter mais de um disco-playlist no leque. Com "continuar de onde parou", a playlist volta no mesmo disco, com a ordem sorteada de novo.

    Mídia própria (arquivos de áudio)

    No lugar do vídeo, use src com o endereço de um arquivo de áudio no seu servidor (mp3, m4a, ogg). O disco toca por<audio>: sem bloqueios do YouTube e com os controles do sistema na tela de bloqueio (Media Session). Com a opçãobackground, a música continua com a página em segundo plano ou a tela bloqueada. Discos do YouTube e de mídia própria podem ficar juntos no mesmo leque.

    HTML
    <metaphi-jukebox background>
      <script type="application/json">
        {
          "tracks": [
            { "src": "/musica/abertura.mp3", "title": "Abertura", "subtitle": "Trilha da casa", "cover": "/musica/abertura.webp" },
            { "src": "/musica/foco.m4a", "title": "Foco", "subtitle": "Trilha da casa" },
            { "id": "_3cu8xOA-Tk", "title": "Morning Chill House #12", "subtitle": "FreeWave Music · No Copyright" }
          ]
        }
      </script>
    </metaphi-jukebox>
    YouTubeMídia própria
    Bloqueio pelo YouTube ou pelo donoPode acontecerNão
    Segundo plano (outra aba, tela bloqueada)Não no celular: o navegador pausa o playerSim, com background
    Controles na tela de bloqueioNãoSim (Media Session)
    Banda e hospedagemDo YouTubeDo seu servidor
    CapaMiniatura do vídeocover ou uma capa desenhada com o título

    O servidor precisa responder pedidos com Range (status 206), como fazem os servidores de arquivos estáticos e as CDNs: o Safari exige isso para tocar áudio. No iPhone, o volume é o do aparelho (o Safari ignora o volume definido pela página).

    03

    Parâmetros

    No HTML, como atributos em kebab-case (cover-size="64", allow-custom). Por JavaScript, em camelCase (coverSize: 64). Mude qualquer um depois com jukebox.update({ … }) ou trocando o atributo.

    Aparência

    Cores, tamanho e lugar do disco na tela. Tudo muda ao vivo, sem recriar o componente.

    AtributoOpção JSTipoPadrãoDescrição
    accentaccentcor CSS#2d81ffCor de destaque: botão de tocar, régua, volume, progresso e o selo das músicas enviadas.
    surfacesurfacecor CSS#121316Fundo do painel e do botão de liga/desliga.
    inkinkcor CSS#f2f1eeCor do texto e das linhas (as transparências saem dela).
    radiusradiusnúmero (px)0Arredondamento dos cantos. 0 deixa os cantos retos, como no METAPHI.
    positionpositiontextobottom-leftCanto da tela: bottom-left, bottom-right, top-left ou top-right.
    mobile-positionmobilePositiontextobottom-rightCanto em telas estreitas (até breakpoint). No celular, o canto direito fica mais perto do polegar.
    cover-sizecoverSizenúmero (px)56Tamanho da capa no canto. Em telas estreitas ela usa 79% disso.
    offset-xoffsetXnúmero (px)14Distância da borda lateral.
    offset-yoffsetYnúmero (px)20Distância da borda de baixo (ou de cima).
    blurblurnúmero (px)10Desfoque do vidro do painel.
    backdropbackdropbooleanotrueEscurece e desfoca a página atrás do painel aberto.
    breakpointbreakpointnúmero (px)760Largura do componente abaixo da qual o painel vira uma folha na base da tela.
    z-indexzIndexnúmero41Camada do componente na página.
    containedcontainedbooleanofalseFica dentro do elemento target (que precisa de position: relative) em vez de fixo na tela (para demonstrações dentro de um bloco da página).

    Disco e leque

    O vinil no canto e o leque de capas em 3D do painel: giro, inclinação, profundidade e navegação.

    AtributoOpção JSTipoPadrãoDescrição
    rpmrpmnúmero33Rotações por minuto do vinil enquanto toca (33, 45, 78…). Vale para o disco do canto e os do leque.
    peekpeekbooleanotrueO vinil espia para fora da capa com o mouse em cima.
    visiblevisiblenúmero3Capas visíveis de cada lado da capa em foco (1 a 5).
    fanfannúmero (°)6Inclinação de cada capa vizinha.
    turnturnnúmero (°)22Quanto as vizinhas giram para longe.
    depthdepthnúmero0.5Quanto as vizinhas recuam e diminuem.
    spreadspreadnúmero0.58Distância até as primeiras vizinhas, em fração da capa.
    stackstacknúmero0.5Quanto as capas distantes se empilham: 0 dá espaçamento igual, 1 fica no estilo coverflow.
    dimdimnúmero0.45Quanto as capas distantes apagam.
    auto-rotateautoRotatebooleanotrueO leque avança sozinho enquanto nada toca.
    intervalintervalnúmero (s)4Intervalo do avanço automático, em segundos.
    pause-on-hoverpauseOnHoverbooleanotruePausa o avanço com o cursor em cima do painel.
    looploopbooleanotrueA lista dá a volta nas pontas.
    draggabledraggablebooleanotrueArrastar passa as capas, com inércia e encaixe.
    wheelwheelbooleanotrueA roda do mouse (ou o trackpad) passa as capas.

    Playlist

    Um disco que toca várias músicas curtas do YouTube em sequência, como a "METAPHI Playlist" (11 faixas). O próprio player passa de uma faixa à outra, sem precisar de outro toque no celular. Recomendado para site institucional.

    AtributoOpção JSTipoPadrãoDescrição
    show-playlistsshowPlaylistsbooleanotrueMostra os discos-playlist no leque. Desligado, o leque fica só com os discos de um vídeo. Para montar a sua playlist com músicas comuns, veja "Playlist com músicas curtas".
    shuffleshufflebooleanotrueAs faixas da playlist tocam em ordem aleatória (sorteada de novo a cada vez que o disco começa). Desligado, tocam na ordem da lista.

    Reprodução

    Volume, ordem das músicas, o domínio do player do YouTube e quando ele carrega.

    AtributoOpção JSTipoPadrãoDescrição
    volumevolumenúmero (1–100)60Volume ao ligar a música.
    autoplayautoplaybooleanofalseToca no primeiro clique, toque ou tecla em qualquer lugar da página: o gesto que os navegadores exigem para liberar som. O player carrega logo depois da página. Se a pessoa desligar a música, ela não volta sozinha.
    show-progressshowProgressbooleanofalseMostra a linha do tempo da música no painel (posição, duração e arrastar para avançar). Útil para mixes longos em sistemas; em site institucional, fica de fora.
    startstarttextorandomDisco inicial: random (sorteado a cada visita), first, a posição (0, 1…) ou o id do vídeo.
    advanceadvancetextonextAo terminar uma música: next (o próximo disco), random (outro, sorteado) ou repeat (a mesma de novo).
    backgroundbackgroundbooleanofalseMídia própria (discos com src) continua tocando com a página em segundo plano ou a tela bloqueada, com os controles do sistema. Músicas do YouTube não têm essa opção: no celular, o navegador pausa o player quando a página sai da tela.
    skip-errorsskipErrorsbooleanotrueVídeo indisponível pula para o próximo disco (até 3 seguidos; depois, aparece o link "Ouvir no YouTube").
    hosthosttextoautoauto: youtube.com no computador (vale o login do YouTube do navegador e evita a checagem anti-robô) e youtube-nocookie.com no celular. Ou force youtube ou nocookie.
    preparepreparetextoautoQuando o player do YouTube carrega. auto: na primeira interação com a página (computador) ou logo depois do carregamento (celular, para o primeiro toque já tocar). Também: interaction, load, hover (ao chegar perto do disco) e manual.
    langlangtextoautoIdioma dos textos: pt-BR, en ou es. auto segue o lang da página.

    Recursos para sistemasSistemas

    Músicas da própria pessoa e continuar de onde parou. Desligados por padrão: recomendados só em sistemas.

    AtributoOpção JSTipoPadrãoDescrição
    allow-customallowCustombooleanofalseMostra "Adicionar música": a pessoa cola um link do YouTube, o componente confere a duração no próprio player e o vídeo vira um disco.
    show-examplesshowExamplesbooleanotrueMostra o botão "Exemplos" na janela de envio, com links prontos para testar (veja "Exemplos para testar"). Troque a lista com a opção examples ou desligue onde não fizer sentido.
    min-durationminDurationnúmero (min)25Duração mínima da música enviada, em minutos (0 aceita qualquer duração). O padrão pede mixes e sets com mais de 25 minutos.
    max-durationmaxDurationnúmero (min)720Duração máxima aceita, em minutos (padrão: 12 horas).
    max-custommaxCustomnúmero8Quantas músicas enviadas ficam guardadas. Ao enviar mais uma, a mais antiga sai.
    storagestoragetextolocallocal: as músicas enviadas ficam no navegador da pessoa (localStorage). none: o seu sistema guarda (no servidor, pela conta da pessoa) com onTrackAdd/onTrackRemove e devolve em customTracks.
    resumeresumebooleanofalseContinuar de onde parou: guarda o disco, a posição e se a música estava ligada. Ao recarregar, o mesmo disco continua do mesmo ponto no primeiro toque, clique ou tecla.
    save-intervalsaveIntervalnúmero (s)4A cada quantos segundos a posição é guardada enquanto toca (também ao sair da página).
    storage-keystorageKeytextometaphi-jukeboxPrefixo das chaves no localStorage: <chave>:tracks e <chave>:point. Use um por sistema (ou por usuário).

    Só por JavaScript

    Funções e listas não cabem em atributos: passe em createJukebox({ … }) ou jukebox.configure({ … }).

    OpçãoTipoDescrição
    tracksTrack[]As músicas, na ordem do leque (veja "Músicas"). No HTML, vão num <script type="application/json"> dentro do elemento.
    examples(link | { id, title, subtitle })[]Exemplos do botão "Exemplos" da janela de envio. Sem ela, os três exemplos padrão.
    customTracksTrack[]Músicas enviadas que o seu servidor devolve (com storage: "none"). Entram no fim do leque.
    labelsobjetoTroca qualquer texto, ex.: { title: "Rádio", add: "Enviar mix" }.
    targetElement | seletorOnde criar o elemento (só em createJukebox). Padrão: document.body.
    onReady(jukebox) => voidO player do YouTube ficou pronto (ou desistiu: sem rede, bloqueado).
    onStatus(status, jukebox) => voidplaying, paused, waiting (o navegador pediu um toque) ou error.
    onTrackChange(detail, jukebox) => voidTrocou de disco. detail: { index, track, playing, status, volume }.
    onTrackAdd(track) => Promise<Track | void>Antes de guardar uma música enviada: salve no servidor e devolva os dados (ou lance um erro com a mensagem para a pessoa).
    onTrackRemove(id | null) => Promise<void>Antes de remover uma música enviada (null: todas).

    04

    Recursos para sistemas

    Dois recursos para quem volta sempre: a pessoa traz a própria música (mixes e sets com mais de 25 minutos) e a música continua de onde parou depois de recarregar a página. Os dois começam desligados.

    allow-custom

    Músicas próprias

    1. No painel, Adicionar música abre o campo do link (youtube.com, youtu.be, /shorts, /live).
    2. O componente abre o vídeo num player escondido, sem tocar, e lê a duração, o título e o canal. Não precisa de chave de API.
    3. Aceita só acima da duração mínima (min-duration, padrão mais de 25 minutos) e até 12 horas. Vídeo curto ou sem permissão de incorporar recebe uma mensagem clara, antes de salvar.
    4. Vira um disco no fim do leque, com o selo Sua música, e já toca. Ficam as 8 últimas (max-custom): ao enviar mais uma, a mais antiga sai.
    5. O disco enviado tem Remover (confirmação em dois toques); o campo tem Remover todas.

    resume

    Continuar de onde parou

    1. Guarda o disco, a posição na música e se ela estava ligada, a cada 4 segundos (save-interval) e ao sair da página.
    2. Ao recarregar, o mesmo disco volta selecionado e o player carrega logo depois da página. Os navegadores não deixam tocar som sozinho: a música continua no primeiro toque, clique ou tecla, do mesmo ponto.
    3. Se a pessoa desligou a música, ela não volta sozinha. Trocar de disco começa o novo do início.
    4. Disco-playlist volta no mesmo disco, com a ordem sorteada de novo.
    5. O ponto fica no navegador (<storage-key>:point). Em sistemas com login, use uma chave por pessoa.

    Exemplos para testar

    Na janela de envio, o botão Exemplos mostra estes três vídeos longos: tocar num deles já preenche o link e envia. Para trocar a lista, use a opção examples; para tirar o botão, show-examples="false".

    O primeiro tem 29:58, por isso a duração mínima padrão é mais de 25 minutos. Commin-duration="30", ele seria recusado com a mensagem de vídeo curto.

    Músicas guardadas no seu servidor

    Com storage: 'none', o navegador não guarda as músicas enviadas: o seu sistema salva na conta da pessoa (e elas aparecem em qualquer aparelho). onTrackAdd roda antes de guardar: devolva a música salva ou lance um erro com a mensagem para a pessoa. Confira de novo no servidor o id (/^[\w-]{11}$/) e a duração recebida.

    JavaScript
    import { createJukebox } from './metaphi-jukebox.js';
    
    // sistema com login: as músicas enviadas ficam na conta da pessoa, no seu servidor
    const jukebox = createJukebox({
      tracks,                       // as músicas da casa
      allowCustom: true,            // botão "Adicionar música"
      minDuration: 25,              // só mixes e sets com mais de 25 minutos
      maxCustom: 8,                 // ficam as 8 últimas
      resume: true,                 // continuar de onde parou
      storage: 'none',              // o navegador não guarda as músicas: o servidor guarda
      storageKey: `app:${user.id}`, // o ponto de parada, separado por pessoa
      customTracks: await fetch('/api/musicas').then((r) => r.json()),
      // salve e devolva a música (ou lance um erro: a mensagem aparece para a pessoa)
      onTrackAdd: async (track) => {
        const r = await fetch('/api/musicas', { method: 'POST', body: JSON.stringify(track) });
        if (!r.ok) throw new Error('Não deu para salvar agora. Tente de novo.');
        return r.json();
      },
      onTrackRemove: (id) => fetch('/api/musicas', { method: 'DELETE', body: JSON.stringify({ id }) }),
    });

    05

    API JavaScript

    O próprio elemento é a API: document.querySelector('metaphi-jukebox') ou o retorno de createJukebox(). Tocar e trocar de disco precisam acontecer dentro de um clique ou toque, por causa das regras de som dos navegadores.

    Método / propriedadeDescrição
    play(index?)Toca o disco index (posição ou id) ou o atual. Chame dentro de um clique/toque.
    pause()Desliga a música (conta como "a pessoa desligou").
    toggle()Liga ou desliga.
    next() / previous()Próximo / disco anterior, já tocando.
    setVolume(0–100)Volume. 0 desliga.
    seek(segundos)Vai para um ponto da música atual.
    hold() / release()Pausa enquanto outro vídeo ou áudio da página toca e volta depois, sem contar como "a pessoa desligou".
    open() / close()Abre ou fecha o painel de discos.
    prepare()Carrega o player do YouTube agora, sem tocar.
    addTrack(link)Confere e adiciona uma música. Promise { track, removed, duplicate }; erro com a mensagem pronta para mostrar.
    removeTrack(id)Remove uma música enviada. Promise true/false.
    clearCustomTracks()Remove todas as músicas enviadas. Promise com a quantidade.
    clearResume()Esquece o ponto guardado (continuar de onde parou).
    update(opções)Troca opções ao vivo. Aparência, leque e reprodução mudam sem recriar nada.
    destroy()Desmonta tudo (também acontece ao remover o elemento da página).
    stateLeitura: { index, track, playing, status, volume, time, duration, open, held, ready }.
    tracks · options · versionLeitura: as músicas na ordem do leque, as opções atuais e a versão.

    06

    Eventos

    Disparados no elemento, com bubbles e composed: dá para ouvir no próprio elemento ou no document. O painel Ao vivo, no topo, mostra cada um acontecendo.

    EventoDescrição
    jukebox:readyO player do YouTube ficou pronto.
    jukebox:statusdetail.status: playing, paused, waiting ou error.
    jukebox:play / jukebox:pauseO som começou ou parou de verdade (confirmado pelo player).
    jukebox:trackchangeTrocou de disco. detail: { index, track, playing, status, volume }.
    jukebox:open / jukebox:closeO painel abriu ou fechou.
    jukebox:trackaddEntrou uma música enviada. detail: { track, removed }.
    jukebox:trackremoveSaiu uma música enviada. detail.id (null: todas).
    jukebox:updateOpções trocadas. detail.changed: a lista.

    07

    Vídeos na página

    Se a página tem vídeos ou áudios próprios, a música sai da frente enquanto eles tocam. hold() pausa sem contar como "a pessoa desligou"; release() volta, se ela não tiver desligado nesse meio-tempo.

    JavaScript
    const jukebox = document.querySelector('metaphi-jukebox');
    const video = document.querySelector('video');
    
    // o vídeo da página toca: a música pausa; parou: a música volta (se a pessoa não tiver desligado)
    video.addEventListener('play', () => jukebox.hold());
    video.addEventListener('pause', () => jukebox.release());
    video.addEventListener('ended', () => jukebox.release());

    08

    Estilo

    O componente usa Shadow DOM: o CSS do site não quebra o toca-discos, e o dele não vaza. As cores vêm das opções (accent, surface, ink); as fontes, as partes internas e o estado ficam abertos para o site.

    CSS
    /* fontes do site dentro do componente (herdam para o Shadow DOM) */
    metaphi-jukebox {
      --jukebox-font: 'Inter', sans-serif;
      --jukebox-font-mono: 'Geist Mono', monospace;
      --jukebox-font-display: 'Archivo', sans-serif;
    }
    
    /* partes internas */
    metaphi-jukebox::part(panel) { box-shadow: 0 40px 120px -40px #000; }
    
    /* o site reage à música */
    body:has(metaphi-jukebox[data-playing]) .equalizer { animation-play-state: running; }
    • data-playing, data-open, data-ready e data-status ficam no próprio elemento.
    • Cliques dentro de elementos com data-jukebox-keep-open não fecham o painel (como o Customize desta página).
    • Quem prefere menos movimento (prefers-reduced-motion) vê o leque sem animação e o disco parado.

    10

    Perguntas frequentes

    A música pode parar de tocar sozinha?

    Pode, nos discos do YouTube: o vídeo pode sair do ar, ficar privado, ter a incorporação desativada pelo dono, ser bloqueado por direitos autorais ou por país. O componente pula para o próximo disco (até 3 seguidos). O mais seguro é usar músicas sem direitos autorais ("No Copyright") ou mídia própria (src).

    A música continua com a tela bloqueada ou em outra aba?

    Com mídia própria e background, sim, com os controles do sistema na tela de bloqueio. Com o YouTube, não no celular: o navegador pausa o player quando a página sai da tela, e a música volta quando a pessoa retorna.

    Por que a música não começa sozinha ao abrir a página?

    Os navegadores não deixam uma página tocar som sem um gesto da pessoa. O componente toca dentro do próprio clique ou toque. Com autoplay, a música começa no primeiro clique, toque ou tecla em qualquer lugar da página (como nesta página); com "continuar de onde parou", ela volta do mesmo ponto nesse primeiro gesto.

    Funciona no iPhone?

    Sim. No celular o player carrega logo depois da página, para o primeiro toque já tocar. Se o Safari ainda pedir outro gesto, o botão de som pisca (estado waiting) e o próximo toque toca. As playlists passam de uma faixa à outra dentro do player, sem precisar de outro toque.

    Apareceu "Ouvir no YouTube". O que houve?

    O YouTube não tocou: vídeo indisponível, incorporação desativada pelo dono (erros 101 e 150) ou a checagem anti-robô do YouTube. Com skipErrors, o componente tenta o próximo disco antes de mostrar o link.

    Preciso de uma chave da API do YouTube?

    Não. A duração, o título e o canal das músicas enviadas vêm do próprio player incorporado, e o controle é feito por postMessage, sem o script da API.

    Posso colar um link de playlist do YouTube (list=…)?

    Não pelo campo de envio. Para tocar várias faixas em sequência, crie um disco com playlist: ["id1", "id2", …].

    Funciona com Content Security Policy?

    Sim. Libere frame-src https://www.youtube.com https://www.youtube-nocookie.com e img-src https://i.ytimg.com (e, se quiser o canal das músicas enviadas, connect-src https://www.youtube.com). Nenhum script do YouTube é carregado, e os estilos entram por adoptedStyleSheets e CSSOM, sem precisar de unsafe-inline.

    O que fica guardado no aparelho da pessoa?

    Por padrão, nada. Com allowCustom e storage: "local", as músicas enviadas ficam no localStorage (<chave>:tracks). Com resume, o disco, a posição e se a música estava ligada (<chave>:point). O player do YouTube segue as regras de cookies do YouTube quando carrega. No celular, por padrão, ele usa o domínio youtube-nocookie.com.

    Como troco as músicas da playlist?

    Crie um disco com playlist: a lista dos vídeos (ids ou links do YouTube), mais title, subtitle e, de preferência, uma cover própria. Ele toca as músicas em sequência, sorteando a ordem (shuffle). Links de playlist do YouTube (list=…) não servem: liste os vídeos um a um.

    Achei um bug ou tenho uma ideia. Onde aviso?

    Escreva para jukebox@metaphi.tech com o navegador, o aparelho e, se der, o link da página onde aconteceu.

    Como uso em React, Next.js ou Vue?

    Crie com createJukebox() num efeito que roda só no navegador (useEffect, onMounted) e chame .remove() ao desmontar. No Next.js, use o componente só no cliente. A aba "Código" do painel Ao vivo já gera o exemplo em React.

    11

    Licença e créditos

    Uso livre: você pode usar, copiar, modificar e distribuir, inclusive em projetos comerciais, desde que mantenha o aviso de copyright e o texto da licença (o comentário no topo do arquivo, com os créditos). O componente é fornecido como está, sem garantia. O arquivo publicado é minificado e ofuscado; o código-fonte não é distribuído.

    Licença
    Licença MIT MIT
    Autor
    Deivison Arthur
    Bugs e melhorias
    jukebox@metaphi.tech

    O texto completo da licença e os créditos estão no cabeçalho do arquivo (comentário /*! … */), que acompanha todas as cópias: mantê-lo é a condição da licença. O ícone de link no painel de discos leva para esta página.