Skip to content

Instantly share code, notes, and snippets.

@kkebo
Last active June 21, 2022 17:38
Show Gist options
  • Save kkebo/126192f030d8cbd96b3a68f2c465acd5 to your computer and use it in GitHub Desktop.
Save kkebo/126192f030d8cbd96b3a68f2c465acd5 to your computer and use it in GitHub Desktop.
ShazamKit on Swift Playgrounds 3.4 on iPadOS 15
import Foundation
import AVFoundation
Bundle(path: "/System/Library/Frameworks/ShazamKit.framework")!.load()
class SHSession {
static let rawType = NSClassFromString("SHSession") as! NSObject.Type
let rawValue: NSObject
var delegate: SHSessionDelegate? {
get {
self.rawValue.value(forKey: "delegate") as! SHSessionDelegate?
}
set {
self.rawValue.setValue(newValue, forKey: "delegate")
}
}
var catalog: SHCatalog {
.init(rawValue: self.rawValue.value(forKey: "catalog") as! NSObject)
}
init() {
self.rawValue = Self.rawType.init() as! NSObject
}
convenience init(catalog: SHCatalog) {
self.init()
self.rawValue.perform("initWithCatalog:", with: catalog.rawValue)
}
required init(rawValue: NSObject) {
guard rawValue.isKind(of: Self.rawType) else { fatalError() }
self.rawValue = rawValue
}
func match(_ signature: SHSignature) {
self.rawValue.perform("matchSignature:", with: signature.rawValue)
}
}
extension SHSession: RawRepresentable {}
@dynamicMemberLookup
class SHCatalog {
static let rawType = NSClassFromString("SHCatalog") as! NSObject.Type
let rawValue: NSObject
subscript(dynamicMember member: String) -> TimeInterval {
self.rawValue.value(forKey: member) as! TimeInterval
}
required init(rawValue: NSObject) {
guard rawValue.isKind(of: Self.rawType) else { fatalError() }
self.rawValue = rawValue
}
}
extension SHCatalog: RawRepresentable {}
@dynamicMemberLookup
class SHMatch {
static let rawType = NSClassFromString("SHMatch") as! NSObject.Type
let rawValue: NSObject
subscript(dynamicMember member: String) -> [SHMatchedMediaItem] {
(self.rawValue.value(forKey: member) as! [NSObject])
.map { .init(rawValue: $0) }
}
subscript(dynamicMember member: String) -> SHSignature {
.init(rawValue: self.rawValue.value(forKey: member) as! NSObject)
}
required init(rawValue: NSObject) {
guard rawValue.isKind(of: Self.rawType) else { fatalError() }
self.rawValue = rawValue
}
}
extension SHMatch: RawRepresentable {}
@dynamicMemberLookup
class SHMatchedMediaItem {
static let rawType = NSClassFromString("SHMatchedMediaItem") as! NSObject.Type
let rawValue: NSObject
subscript(dynamicMember member: String) -> TimeInterval {
self.rawValue.value(forKey: member) as! TimeInterval
}
subscript(dynamicMember member: String) -> Float {
self.rawValue.value(forKey: member) as! Float
}
required init(rawValue: NSObject) {
guard rawValue.isKind(of: Self.rawType) else { fatalError() }
self.rawValue = rawValue
}
}
extension SHMatchedMediaItem: RawRepresentable {}
@dynamicMemberLookup
class SHSignature {
static let rawType = NSClassFromString("SHSignature") as! NSObject.Type
let rawValue: NSObject
subscript(dynamicMember member: String) -> Data {
self.rawValue.value(forKey: member) as! Data
}
subscript(dynamicMember member: String) -> TimeInterval {
self.rawValue.value(forKey: member) as! TimeInterval
}
required init(rawValue: NSObject) {
guard rawValue.isKind(of: Self.rawType) else { fatalError() }
self.rawValue = rawValue
}
}
extension SHSignature: RawRepresentable {}
class SHSignatureGenerator {
static let rawType = NSClassFromString("SHSignatureGenerator") as! NSObject.Type
let rawValue: NSObject
var signature: SHSignature {
.init(rawValue: self.rawValue.value(forKey: "signature") as! NSObject)
}
init() {
self.rawValue = Self.rawType.init() as! NSObject
}
required init(rawValue: NSObject) {
guard rawValue.isKind(of: Self.rawType) else { fatalError() }
self.rawValue = rawValue
}
func append(_ buffer: AVAudioPCMBuffer, at time: AVAudioTime?) {
self.rawValue.perform("appendBuffer:atTime:error:", with: buffer, with: time)
}
}
extension SHSignatureGenerator: RawRepresentable {}
@objc protocol SHSessionDelegate: NSObjectProtocol {
@objc optional func session(_ session: NSObject, didFind match: NSObject)
@objc optional func session(_ session: NSObject, didNotFindMatchFor signature: NSObject, error: Error?)
}
final class SessionDelegate: NSObject {}
extension SessionDelegate: SHSessionDelegate {
func session(_ session: NSObject, didFind match: NSObject) {
print("didFindMatch")
}
func session(_ session: NSObject, didNotFindMatchFor signature: NSObject, error: Error?) {
print("didNotFindMatch")
}
}
let delegate = SessionDelegate()
let session = SHSession()
session.delegate = delegate
let generator = SHSignatureGenerator()
// generator.append(buffer, at: nil)
let signature = generator.signature
session.match(signature)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment