https://d226lax1qjow5r.cloudfront.net/blog/blogposts/detecting-music-with-shazamkit/shazamkit_musicdetection_1200x600.png

Detección de música con ShazamKit

Tiempo de lectura: 10 minutos

En este tutorial, utilizarás ShazamKit para detectar música en reproducción y enviarla como mensaje a un chat con el Vonage Client SDK para iOS. ShazamKit está disponible en iOS 15 y superior, que en el momento de escribir este artículo está en fase beta.

Requisitos previos

  • Una cuenta de desarrollador de Apple y un dispositivo de prueba con iOS 15.

  • Xcode 13.

  • Cocoapods para instalar el Vonage Client SDK para iOS.

  • Nuestra interfaz de línea de comandos, que puede instalar con npm install @vonage/cli -g.

  • El plugin Vonage CLI Conversations, puedes instalarlo con vonage plugins:install @vonage/cli-plugin-conversations

Vonage API Account

To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.

El proyecto Starter

Este tutorial se basa en el tutorial "Creación de una aplicación de chat" del portal para desarrolladores de Vonage. Este tutorial comenzará clonando el proyecto terminado de GitHub, pero si no estás familiarizado con el uso de Vonage Client SDK para iOS para crear una aplicación de chat, puedes comenzar con el tutorial. Si sigues el tutorial, puedes saltar a la sección de habilitación de ShazamKit.

Configurar una aplicación de Vonage

Ahora debes crear una aplicación de Vonage. Una aplicación contiene la información de seguridad y configuración que necesitas para conectarte a Vonage. Crea un directorio para tu proyecto usando mkdir vonage-tutorial en tu terminal, luego cambia al nuevo directorio con cd vonage-tutorial. Crea una aplicación de Vonage utilizando el siguiente comando:

vonage apps:create "ShazamKit" --rtc-event-url=https://example.com/

Se crea un archivo llamado vonage_app.json en el directorio de tu proyecto y contiene el nuevo ID de aplicación de Vonage y la clave privada. También se crea un archivo de clave privada llamado shazamkit.key también se crea.

A continuación, cree usuarios para su aplicación. Puede hacerlo ejecutando:

vonage apps:users:create Alice vonage apps:users:create Bob

Crea una conversación:

vonage apps:conversations:create "shazam"

Añade a tus usuarios a la conversación, sustituyendo CONVERSATION_ID y USER_ID por los valores anteriores:

# Alice's User ID vonage apps:conversations:members:add CONVERSATION_ID USER_ID # Bob's User ID vonage apps:conversations:members:add CONVERSATION_ID USER_ID

El Client SDK utiliza JWT para la autenticación. El JWT identifica el nombre de usuario, el ID de la aplicación asociada y los permisos concedidos al usuario. Se firma utilizando su clave privada para demostrar que se trata de un token válido. Puedes crear un JWT para tus usuarios ejecutando el siguiente comando sustituyendo APP_ID por el ID de su aplicación:

vonage jwt --app_id=APP_ID --subject=Alice --key_file=./shazamkit.key --acl='{ "paths": { "/*/users/**": {}, "/*/conversations/**": {}, "/*/sessions/**": {}, "/*/devices/**": {}, "/*/image/**": {}, "/*/media/**": {}, "/*/push/**": {}, "/*/knocking/**": {}, "/*/legs/**": {} } }'
vonage jwt --app_id=APP_ID --subject=Bob --key_file=./shazamkit.key --acl='{ "paths": { "/*/users/**": {}, "/*/conversations/**": {}, "/*/sessions/**": {}, "/*/devices/**": {}, "/*/image/**": {}, "/*/media/**": {}, "/*/push/**": {}, "/*/knocking/**": {}, "/*/legs/**": {} } }'

Clonar el proyecto iOS

Para obtener una copia local del proyecto iOS, abra su terminal e introduzca git clone git@github.com:nexmo-community/clientsdk-app-to-app-chat-swift.git. Cambie de directorio a la carpeta clientsdk-app-to-app-chat-swift utilizando cd clientsdk-app-to-app-chat-swift. A continuación, instale las dependencias del proyecto ejecutando pod install. Una vez completado, puede abrir el proyecto Xcode mediante la ejecución de abrir AppToAppChat.xcworkspace.

Autenticación del Client SDK

En la parte inferior del ViewController.swift hay una estructura User struct con una propiedad estática para nuestros usuarios Alice y Bob. Reemplace CONVERSATION_ID, ALICE_JWT y BOB_JWT con los valores que generaste antes en la terminal.

struct User {
    let name: String
    let jwt: String
    let chatPartnerName: String
    let conversationId = "CONVERSATION_ID"
    
    static let Alice = User(name: "Alice",
                            jwt:"ALICE_JWT",
                            chatPartnerName: "Bob")
    static let Bob = User(name: "Bob",
                          jwt:"BOB_JWT",
                          chatPartnerName: "Alice")
}

Activar Shazam

Una vez abierto el proyecto, asegúrate de que tienes un identificador de paquete único y activa la firma automática.

Bundle identifier section of Xcode

A continuación, visite la sección sección de identificadores de su Account en el portal para desarrolladores de Apple. Busque su identificador de paquete y, en la sección Servicios de la aplicación activa ShazamKit.

App Services on the developer portal

Detectar música

Permisos de micrófono

Para detectar la música que se está reproduciendo, tendrá que acceder al micrófono del dispositivo, lo que requiere su permiso. Su proyecto contiene un archivo Info.plist que contiene los metadatos de la aplicación; encontrarás el archivo dentro del grupo AppToAppChat.

Se requiere una nueva entrada en el archivo Info.plist archivo:

  1. Pase el ratón por encima de la última entrada de la lista y haga clic en el pequeño botón + que aparece.

  2. En la lista desplegable, seleccione Privacy - Microphone Usage Description y añada To detect music with Shazam como valor.

Su Info.plist debería tener este aspecto:

Info.plist after adding microphone permissions

A continuación, abra su archivo AppDelegate.swift e importe AVFoundation:

import UIKit
import AVFoundation

A continuación, llame a requestRecordPermission: dentro de application:didFinishLaunchingWithOptions::

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    if AVAudioSession.sharedInstance().recordPermission != .granted {
        AVAudioSession.sharedInstance().requestRecordPermission { (isGranted) in
            print("Microphone permissions \(isGranted)")
        }
    }
    return true
}

Crear un búfer de audio

La aplicación utilizará el micrófono para detectar continuamente música de fondo, por lo que tendrás que crear un búfer de audio desde el micrófono para pasarlo a ShazamKit. Abre el archivo ChatViewController.swift importar AVFoundation, ShazamKit y añade estas propiedades a la clase:

import UIKit
import ShazamKit
import NexmoClient
import AVFoundation

class ChatViewController: UIViewController {
    
    let session = SHSession()
    let audioEngine = AVAudioEngine()
    var lastMatchID: String = ""

    ... 
}

A continuación añade una nueva función a la clase llamada startAnalysingAudio:

func startAnalysingAudio() {
    let inputNode = audioEngine.inputNode
    let bus = 0
    inputNode.installTap(onBus: bus, bufferSize: 2048, format: inputNode.inputFormat(forBus: bus)) { (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in
        self.session.matchStreamingBuffer(buffer, at: time)
    }
    
    audioEngine.prepare()
    try! audioEngine.start()
}

Esta función utiliza AVAudioEngine para acceder a la entrada del micrófono. AVAudioEngine es un framework robusto que te permite manipular audio conectando/cadenando objetos nodo. Sólo te interesa la salida bus 0del inputNode para esta aplicación. La función installTap te permite observar la salida y te da acceso a una función AVAudioNodeTapBlockque es un typealias para AVAudioPCMBuffer y AVAudioTime . Tanto el búfer como el tiempo se pasan a la función matchStreamingBuffer en la función SHSessionque trata de comparar la música que suena con el catálogo de Shazam.

Para terminar el proceso, hay que añadir una función llamada stopAnalysingAudio que dejará de observar la entrada de forma segura:

func stopAnalysingAudio() {
    let inputNode = audioEngine.inputNode
    let bus = 0
    inputNode.removeTap(onBus: bus)
    self.audioEngine.stop()
}

Establece el delegado de la sesión en esta clase, llama a startAnalysingAudio al final de la función viewDidLoad y stopAnalysingAudio en la logout función

override func viewDidLoad() {
    super.viewDidLoad()
    
    session.delegate = self
    
    ...
    
    getConversation()
    startAnalysingAudio()
}

@objc func logout() {
    client.logout()
    stopAnalysingAudio()
    dismiss(animated: true, completion: nil)
}

EnSHSessionDelegate

Ahora que la aplicación está pasando un búfer a lo largo de ShazamKit que necesita para poner en práctica la SHSessionDelegate para recibir actualizaciones. Crear una extensión en la parte inferior del archivo:

extension ChatViewController: SHSessionDelegate {
    func session(_ session: SHSession, didFind match: SHMatch) {
        if let matchedItem = match.mediaItems.first,
           let title = matchedItem.title,
           let artist = matchedItem.artist,
           let matchId = matchedItem.shazamID, matchId != lastMatchID {
            lastMatchID = matchId
            DispatchQueue.main.async {
                self.send(message: "I am currently listening to: \(title) by \(artist) - Via ShazamKit")
            }
        }
    }
    
    func session(_ session: SHSession, didNotFindMatchFor signature: SHSignature, error: Error?) {
        if error != nil {
            print(error as Any)
        }
    }
}

La función didNotFindMatchFor es llamada cuando ShazamKit no encuentra ninguna coincidencia o se produce un error. De lo contrario, la función didFind se llamará cuando se haya encontrado una coincidencia.

Las coincidencias se devuelven como una matriz con distintos niveles de confianza, pero se tomará el primer resultado. Además, la función compara el ID de la coincidencia con la última coincidencia para garantizar que cuando envíes un mensaje al chat, sólo ocurra una vez por coincidencia.

Pruébalo

Construye y ejecuta (CMD + R) el proyecto en tu dispositivo iOS y también en el simulador. Inicia sesión con un usuario diferente en cada dispositivo. Si pones música de fondo, el dispositivo iOS físico pasará el buffer de audio a ShazamKit. Si una canción coincide con el catálogo de Shazam, se enviará un mensaje al chat.

Chat showing a song being matched

¿Y ahora qué?

Puede encontrar el proyecto completo en GitHub. Puedes hacer mucho más con el Client SDK. Más información sobre el Client SDK en developer.nexmo.com y ShazamKit en developer.apple.com

Compartir:

https://a.storyblok.com/f/270183/400x400/19c02db2d3/abdul-ajetunmobi.png
Abdul AjetunmobiVonage Antiguo miembro del equipo

Abdul es desarrollador de Vonage. Ha trabajado en productos de consumo como ingeniero de iOS. En su tiempo libre, le gusta andar en bicicleta, escuchar música y asesorar a aquellos que están comenzando su viaje en la tecnología.