简体   繁体   English

Swift 中的 Apple Music 和 AVAudioEngine

[英]Apple Music & AVAudioEngine in Swift

How can we access songs in the Apple Music library with AVAudioPlayerNode / AVAudioEngine for playback and processing?我们如何使用AVAudioPlayerNode / AVAudioEngine访问 Apple Music 库中的歌曲进行播放和处理?

I have asked this question in Apple forum .我在苹果论坛上问过这个问题。

"Apple Music" may refer to: “苹果音乐”可以指:

  • the music streaming service音乐流媒体服务
  • its iOS client (known as "Music")它的 iOS 客户端(称为“音乐”)
  • its macOS client, which doubles as a local media management and playback app (formerly known as iTunes, known as "Music" as of macOS Catalina).它的 macOS 客户端,兼作本地媒体管理和播放应用程序(以前称为 iTunes,在 macOS Catalina 中称为“音乐”)。

Due to DRM restrictions it is not possible to play tracks from the Apple Music catalogue downloaded onto your device from the Apple Music macOS or iOS clients.由于 DRM 限制,无法播放从 Apple Music macOS 或 iOS 客户端下载到您设备上的 Apple Music 目录中的曲目。 However you can play audio files you own and which you've synced onto your device using the macOS Music app or the Finder app , as follows:但是,您可以使用 macOS 音乐应用程序或 Finder 应用程序播放您拥有的以及已同步到设备上的音频文件,如下所示:

  1. Add the NSAppleMusicUsageDescription key to your Info.plist file, and its corresponding valueNSAppleMusicUsageDescription键添加到您的 Info.plist 文件中,及其对应的值
  2. Setup your AVAudioSession and AVAudioEngine设置您的AVAudioSessionAVAudioEngine
  3. Find the URL of the media item you want to play (you can use MPMediaPickerController like in the example below or you can make your own MPMediaQuery )找到你想播放的媒体项目的 URL(你可以像下面的例子一样使用MPMediaPickerController或者你可以制作自己的MPMediaQuery
  4. Create an AVAudioFile from that URL从该 URL 创建一个AVAudioFile
  5. Create an AVAudioPlayerNode set to play that AVAudioFile创建一个AVAudioPlayerNode集来播放该AVAudioFile
  6. Connect the player node to the engine's output node将播放器节点连接到引擎的输出节点
import UIKit
import AVFoundation
import MediaPlayer

class ViewController: UIViewController {

    let engine = AVAudioEngine()

    override func viewDidLoad() {
        super.viewDidLoad()

        let mediaPicker = MPMediaPickerController(mediaTypes: .music)
        mediaPicker.allowsPickingMultipleItems = false
        mediaPicker.showsItemsWithProtectedAssets = false // These items usually cannot be played back
        mediaPicker.showsCloudItems = false // MPMediaItems stored in the cloud don't have an assetURL
        mediaPicker.delegate = self
        mediaPicker.prompt = "Pick a track"
        present(mediaPicker, animated: true, completion: nil)
    }

    func startEngine(playFileAt: URL) {
        do {
            try AVAudioSession.sharedInstance().setCategory(.playback)

            let avAudioFile = try AVAudioFile(forReading: playFileAt)
            let player = AVAudioPlayerNode()

            engine.attach(player)
            engine.connect(player, to: engine.mainMixerNode, format: avAudioFile.processingFormat)

            try engine.start()
            player.scheduleFile(avAudioFile, at: nil, completionHandler: nil)
            player.play()
        } catch {
            assertionFailure(String(describing: error))
        }
    }
}

extension ViewController: MPMediaPickerControllerDelegate {
    func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
        guard let item = mediaItemCollection.items.first else {
            print("no item")
            return
        }
        print("picking \(item.title!)")
        guard let url = item.assetURL else {
            return print("no url")
        }

        dismiss(animated: true) { [weak self] in
            self?.startEngine(playFileAt: url)
        }
    }

    func mediaPickerDidCancel(_ mediaPicker: MPMediaPickerController) {
        dismiss(animated: true, completion: nil)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM