今天,我创建了一个小应用程序来尝试在 iOS 15 中的 ShazamKit 音乐检测能力。按照 Youtube 上的教程进行操作,并且我拥有 Apple 开发者会员资格,并为此应用程序标识符启用了 ShazamKit 服务。
简而言之,我想用 ShazamKit 从应用程序内的音频文件中检测歌曲元数据。
问题是,尽管我已经成功生成了签名,但委托方法didFind
并didNotFindMatchFor
没有触发。didNotFindMatchFor
如果至少没有找到匹配项,我认为它应该在委托方法中给我一个错误,但事实并非如此。
这是一个相当新的功能,我找不到太多相关的东西。感谢任何帮助。
更多信息:我确实找到了一些使用 audioEngine 的东西,但是使用麦克风的输出,如果用户用耳机听音乐,那将是不可能的。就我而言,我想使用文件本身,因为我的生产应用程序是一个音乐播放器,它在沙盒中存储了很多音频文件。
import ShazamKit
import UIKit
class ViewController: UIViewController {
lazy var recoButton: UIButton = {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 120, height: 60))
button.layer.cornerRadius = 8
button.backgroundColor = .brown
button.setTitle("Recognize", for: .normal)
button.addTarget(self, action: #selector(recognizeSong), for: .touchUpInside)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(recoButton)
recoButton.center = view.center
}
@objc func recognizeSong(_ sender: UIButton) {
print("reco button tapped")
// ShazamKit is available from iOS 15
if #available(iOS 15, *) {
// session
let session = SHSession()
// delegate
session.delegate = self
do {
// get track
guard let url = Bundle.main.url(forResource: "Baby One More Time", withExtension: "mp3") else {
print("url is NULLLL")
return }
// create audio file
let file = try AVAudioFile(forReading: url)
let frameCapacity = AVAudioFrameCount(file.length / 26)
// Audio -> Buffer
guard let buffer = AVAudioPCMBuffer(pcmFormat: file.processingFormat, frameCapacity: frameCapacity) else {
print("Failed to create a buffer")
return }
// Read file into buffer
try file.read(into: buffer)
// SignatureGenerator
let generator = SHSignatureGenerator()
try generator.append(buffer, at: nil)
// create signature
let signature = generator.signature()
// try to match
session.match(signature)
} catch {
print(error)
}
} else {
// unavailable alert
}
}
}
extension ViewController: SHSessionDelegate {
func session(_ session: SHSession, didFind match: SHMatch) {
print("Match found!")
// get results
let items = match.mediaItems
items.forEach { item in
print(item.title ?? "title")
print(item.artist ?? "artist")
print(item.artworkURL?.absoluteURL ?? "artwork url")
}
}
func session(_ session: SHSession, didNotFindMatchFor signature: SHSignature, error: Error?) {
if let error = error {
print(error)
}
}
}