如何获取iOS10中正在播放歌曲的歌词(Swift 3)

问题描述:

我想显示iOS系统播放器正在播放的歌曲中的歌词。如何获取iOS10中正在播放歌曲的歌词(Swift 3)

这里是我的自定义播放器:

import UIKit 
import MediaPlayer 
import AVFoundation 

class NowPlayingController: NSObject { 
    var musicPlayer: MPMusicPlayerController { 
     if musicPlayer_Lazy == nil { 
      musicPlayer_Lazy = MPMusicPlayerController.systemMusicPlayer() 

      let center = NotificationCenter.default 
      center.addObserver(self, 
       selector: #selector(self.playingItemDidChange), 
       name: NSNotification.Name.MPMusicPlayerControllerNowPlayingItemDidChange, 
       object: musicPlayer_Lazy) 
      musicPlayer_Lazy!.beginGeneratingPlaybackNotifications() 
     } 

     return musicPlayer_Lazy! 
    } 
    private var musicPlayer_Lazy: MPMusicPlayerController? 

    var nowPlaying: MPMediaItem? 

    //If song changes 
    func playingItemDidChange(notification: NSNotification) { 
     nowPlaying = musicPlayer.nowPlayingItem 
    } 
} 

nowPlaying项目要获得歌词我已经试过2点的方法和他们两个总是回报nil的。

该代码总是返回零:

let lyricsText = nowPlaying?.value(forProperty: MPMediaItemPropertyLyrics) as? NSString as String? 

在下面的代码MPMediaItemPropertyAssetURL总是返回nil,而不是实际的URL:

let songUrl = nowPlaying?.value(forProperty: MPMediaItemPropertyAssetURL) as? NSURL as URL? 
if songUrl != nil { 
    let songAsset = AVURLAsset(url: songUrl!, options: nil) 
    lyricsText = songAsset.lyrics 

所有歌曲的设备(通过iTunes同步),包含歌词(显示在系统播放器中)和非DRM保护 (ripped aac/mp3)。

我在真机上测试这个:iPhone 6S/iOS的10.3

任何建议,我怎么能得到歌词为什么MPMediaItemPropertyAssetURL返回零?

+0

这些天,大多数iTunes内容要么是使用FairPlay DRM或受保护的是苹果音乐(也使用FairPlay进行保护,不知道?)这种类型的内容总是返回一个零MPMediaItemPropertyAssetURL。您只能以“自动点唱机”的方式使用它,iOS会为您播放音乐。更复杂的用例是不可能的。 –

+0

您是否尝试过如下所示的访问? 'let lyric = nowPlaying?.lyrics let assetUrl = nowPlaying?.assetURL' 也请注意, – Bluewings

+0

@RhythmicFistman情况并非如此,因为我的内容不是iTunes Store的内容。但无论如何,我已经使用下面的方法进行了双重检查,该方法返回'false'(意味着歌曲没有DRM):'nowPlaying?.hasProtectedAsset' – dandepeched

我不知道它为什么不起作用,但它看起来像现在相同的代码工作正常。也许它以某种方式连接到我现在用于播放器实例的单例。这是斯威夫特3版本,100%的工作:

import UIKit 
import MediaPlayer 
import AVFoundation 

class NowPlayingController: NSObject { 

    static let sharedController = NowPlayingController() 

    //MARK: Init 
    private override init() { 
     super.init() 

     var musicPlayer_Lazy: MPMusicPlayerController? 

     // System player instance 
     if musicPlayer_Lazy == nil { 
      musicPlayer_Lazy = MPMusicPlayerController.systemMusicPlayer() 
      NotificationCenter.default.addObserver(self, 
               selector: #selector(self.playingItemDidChange), 
               name: NSNotification.Name.MPMusicPlayerControllerNowPlayingItemDidChange, 
               object: musicPlayer_Lazy) 
      musicPlayer_Lazy!.beginGeneratingPlaybackNotifications() 
     } 

     self.musicPlayer = musicPlayer_Lazy! 
    } 

    // MARK: Class properties 
    var musicPlayer: MPMusicPlayerController! 
    var nowPlaying: MPMediaItem? 

    // MARK: Methods 
    func playingItemDidChange(notification: NSNotification) { 
     nowPlaying = musicPlayer.nowPlayingItem 
     NotificationCenter.default.post(newSongNotification as Notification) 
    } 

    func getLyrics() { 
     let songUrl = nowPlaying?.value(forProperty: MPMediaItemPropertyAssetURL) as? URL 
     let songAsset = AVURLAsset(url: songUrl!, options: nil) 
     let lyricsText = songAsset.lyrics 
    } 
}