【问题标题】:How to get lyrics for Now Playing song in iOS10 (Swift 3)如何在 iOS10 (Swift 3) 中获取 Now Playing 歌曲的歌词
【发布时间】:2017-04-05 06:01:12
【问题描述】:

我想显示当前由 iOS 系统播放器播放的歌曲的歌词。

这是我的自定义播放器:

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

这段代码总是返回 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 保护 (翻录 aac/mp3)。

我在真机上测试:iPhone 6s/iOS 10.3

关于如何获取歌词或为什么 MPMediaItemPropertyAssetURL 返回 nil 的任何建议?

【问题讨论】:

  • 如今,大多数 iTunes 内容要么受 FairPlay DRM 保护,要么受 Apple Music 保护(也受 FairPlay 保护?不知道。)并且此类内容总是返回 nil MPMediaItemPropertyAssetURL。你只应该以“点唱机”的方式使用它,iOS 会为你播放音乐。更复杂的用例是不可能的。
  • 您是否尝试过像下面这样访问? let lyric = nowPlaying?.lyrics let assetUrl = nowPlaying?.assetURL 还要注意
  • @RhythmicFistman 情况并非如此,因为我的内容不是 iTunes Store 内容。但无论如何我已经用以下方法仔细检查了返回false(意味着歌曲上没有DRM):nowPlaying?.hasProtectedAsset
  • @Bluewings 我刚试过,都返回nill

标签: ios swift swift3 avfoundation mpmediaitem


【解决方案1】:

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

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
    }
}

【讨论】:

  • NotificationCenter.default.post(newSongNotification as Notification) 创建一个错误并且 nowPlaying 总是返回 nil。为什么 ? @dandepeched
  • @dandepected 它仍然返回 nil 。我正在使用上面的喜欢。 NowPlayingController.sharedController.getLyrics()
  • 歌词总是零你能帮帮我吗?
【解决方案2】:

我知道这有点老了,但我只花了大约 4 个小时研究如何从 MP3 文件中读取歌词,如果它有歌词。我使用的是 AVAudioPlayer 而不是 MPMusicPlayerController。天哪,这该死的简单……

Swift 5.3 for macOS (我不知道这是否适用于 iOS,但我想它会)

import AVFoundation

func getLyrics(url: URL) -> String? {
    let asset = AVAsset(url: url)
    return asset.lyrics
}

请注意,它返回一个可选项,因此最好检查 nil。希望这可以节省一些人的研究时间。

请参阅 Apple 文档 here

【讨论】:

  • 感谢您的信息。但是,我在我的 iOS 音乐播放器中尝试了很多歌曲,并且每首歌曲的歌词属性都为零。 :-(
  • 我不是为 iOS 开发的,但我觉得奇怪的是,如果歌词嵌入到您的 mp3 文件(或其他媒体类型)中,这对您不起作用。答案链接中的开发人员文档显示此方法适用于所有 iOS 4.0 版本。
  • mp3文件中是否嵌入了歌词。我对为什么它不起作用的唯一猜测是它们没有嵌入。我也觉得很奇怪(也很伤心)。但我很感激这些信息!
  • 这是有道理的。如果他们不在那里,那么回报将为零。要进行测试,请将 mp3 导入 Music 并添加一些歌词,然后将文件 url 更改为指向 Music 存储它的位置,或者将其同步到 iOS 设备并进行测试,或者使用您知道的文件进行测试有歌词。只是一个想法。
  • 正如你所说!我在 Mac 上的“音乐”中为一首歌曲添加了歌词,它们出现在我的 iOS 应用程序中。现在我所要做的就是为我最喜欢的播放列表中的所有 570 首歌曲添加歌词 - 哈哈!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多