Fiz um site de canto com 100 MILHÕES de músicas gastando $10
Recentemente eu decidi que iria começar a aprender canto, e então fui correndo ver quais apps existiam para isso. Me deparei com vários aplicativos, alguns mais simples, outros mais completos. Mas um que se destacou foi o Yousician — ele era simples, permitia ver as notas vocais de cada música e detectava qual nota eu estava fazendo para mostrar se eu acertei ou errei o tom.
Problema
Mas então começaram a surgir dois problemas: o primeiro foi o preço. Por mais que o Yousician não seja tão caro, eu não queria adicionar mais uma assinatura à minha já imensa lista.
O segundo problema — e o que realmente pesou — foi que, apesar do Yousician ter uma biblioteca enorme, ele está longe de ter todas as músicas do mundo. Várias vezes eu queria aprender a cantar alguma música e ela simplesmente não existia lá!
Logo pensei: “Por que não criar um site de canto como o Yousician, porém grátis e com todas as músicas do mundo?”.
Eu sei, isso soa como um sonho impossível logo de cara, porque eu teria que enfrentar dois grandes problemas:
O primeiro seria direitos autorais, já que eu não poderia simplesmente reproduzir músicas no meu site para a pessoa cantar junto (uma feature que o Yousician tem). É justamente por causa disso que o Yousician é pago — para conseguir bancar os custos e ainda pagar pelos direitos autorais das músicas disponíveis lá.
O segundo problema era: plataformas como o YouTube Music têm mais de 100 milhões de músicas. Como eu iria escutar cada uma delas e adicionar as notas manualmente?
Se você é dev, provavelmente já pensou em uma solução para isso — e é exatamente isso que eu vou descrever nos próximos parágrafos deste artigo!
Direitos autorais
Depois de pesquisar bastante sobre como funcionam os direitos autorais de músicas, descobri algo simples e óbvio:
Eu não posso reproduzir uma música no meu site, mas o YouTube pode reproduzir uma música do YouTube Music.
E essa foi a solução para o problema dos direitos autorais: eu simplesmente não reproduzo a música, apenas o YouTube faz isso. Eu uso a API oficial de embed do YouTube para saber em que momento o vídeo está e sincronizar a timeline das notas.
Só com essa solução eu já economizei milhares de dólares em licenciamento que teria que pagar se hospedasse as músicas diretamente.
Adicionando 100 milhões de músicas ao banco de dados
Eu sei, é pra isso que você clicou nesse artigo: como eu tecnicamente adicionei “todas as músicas do mundo” ao banco de dados?
A resposta é simples: eu não adicionei.
Calma, isso não é clickbait.
A solução foi básica: o site tem um banco de dados com algumas músicas, mas quando o usuário pesquisa por alguma faixa, eu não faço essa busca no meu banco de dados, e sim no YouTube Music (usando a API oficial).
Quando o YouTube Music retorna os resultados, eu apenas verifico quais dessas músicas já existem na minha base e envio essa informação para o frontend. Caso o usuário selecione uma música que ainda não existe, eu crio essa música no banco de dados.
Legal, né? Mas ainda tinha um problema: o YouTube Music não fornece as notas vocais das músicas.
Então, como eu iria obter essa informação quando o usuário clicasse em uma track nova?
A solução também foi simples (mas não fácil — demorei uma semana pra resolver kkk).
Eu comprei uma VPS, onde deixei rodando um worker. Quando o usuário clicava em uma música que não existia na base, ela era adicionada a uma fila, o que imediatamente acionava o worker.
Esse worker executava um script em Python que encontrava as notas vocais da música (usando o CREPE). Assim, minha infra inicial era algo como:

Isso parecia funcionar inicialmente, mas teve um problema: como eu usava um modelo de IA robusto para detectar as notas (e o meu worker ainda fazia mais coisas, como importar as capas das músicas para o meu S3), e tudo rodava apenas na CPU, o processo demorava cerca de 30 minutos por música.
Além disso, eu não podia processar muitas músicas ao mesmo tempo, senão tudo ficava ainda mais lento. E como eu queria que o site fosse fluido (onde o usuário só se preocupa em cantar), esse tempo era inaceitável — o ideal seria no máximo 5 minutos.
Então precisei pensar em uma solução mais inteligente: em vez de usar uma VPS com um único worker, decidi usar uma SQS (Simple Queue Service da AWS).
Quando ela recebia uma nova mensagem, chamava uma função Lambda que processava a música.
Isso resolvia o problema de paralelismo: agora várias músicas poderiam ser processadas ao mesmo tempo, de forma barata e independente (cada música rodando em uma instância separada da Lambda).
Minha nova infra ficou parecida com isso:

Mas, como nada é fácil na vida de quem faz side projects, surgiu outro problema: timeout.
Eu recebia esse erro com frequência, porque uma Lambda só pode rodar por no máximo 15 minutos, e meu processo ainda era muito lento. Foi aí que encontrei uma segunda solução.
Depois de muita pesquisa, encontrei o serviço chamado RunPod.
A ideia é simples: você pode rodar uma função Python (como uma Lambda da AWS), mas em uma máquina com GPU — o que deixaria o processo de detecção das notas muito mais rápido.
E o melhor: você paga apenas pelos segundos de execução da função.
Parecia perfeito, mas quem já tentou rodar IA em GPU sabe que isso é caro. Então eu precisei dividir minha infraestrutura em partes menores, pois algumas etapas (como importar capas, letras e metadados) não precisavam rodar em GPU.
Assim, minha arquitetura final ficou assim:

Eu tenho uma fila no SQS. Ao receber uma nova mensagem, ela chama uma Lambda, que importa todas as informações da música que não precisam de IA (letra, metadados, imagens etc.).
Quando essa Lambda termina, ela chama a função do RunPod (que já implementa uma fila interna para processar as funções)
Essa função detecta as notas vocais da música, salva os resultados no banco de dados e encerra o processo.
Com isso, eu consegui uma infra super eficiente, que processa centenas de músicas simultaneamente, pagando apenas centavos de dólar por música e ****com essa nova infra, consegui reduzir o tempo de processamento para algo entre 2 e 3 minutos por música.
Conclusão
Resumindo, encontrei uma forma super barata e inteligente de importar todas essas músicas:
Quando o usuário pesquisa, o site lista músicas do YouTube Music. Quando o usuário selecionar uma música, se a música já existir na base, ele mostra as informações imediatamente. Caso contrário, ela é adicionada a uma fila, que aciona workers responsáveis por importar os dados e detectar as notas vocais.
Esse artigo não tem a intenção de divulgar o meu site — é só para compartilhar uma solução que me queimou a cabeça por semanas 😅.
Mas eu realmente acredito que vale a pena você acessar o site (notefinder.com.br) e criar uma conta só pra ver como esse projeto resultou em um sistema simples, útil para o usuário e, de quebra, barato de manter!
Fonte: https://notefinder.com.br