Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get all the songs from music library ios swift 3 xcode 8.2.1

Tags:

ios

swift3

i wanna get all the songs from music library and show in my table view and then select multiple songs in table view and play in AVAudioPlayer. but i am unable to get songs from music library and show in my table view.i visit many links but did not work for me, please help me. here is my code

@IBAction func selectMusicFromGallery(_ sender: Any) 
{
    mediaPicker = MPMediaPickerController(mediaTypes: .music)
    mediaPicker.allowsPickingMultipleItems = false
    mediaPicker.delegate = self
   // mediaPicker.prompt = "Select Songs"
    self.present(mediaPicker, animated: true, completion: nil)
}

func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) 
{
    let mediaItems = MPMediaQuery.songs().items
    let mediaCollection = MPMediaItemCollection(items: mediaItems!)
    let player = MPMusicPlayerController.systemMusicPlayer()
    player.setQueue(with: mediaCollection)
    player.play()
}
like image 542
Irfan Saeed Avatar asked Apr 13 '17 06:04

Irfan Saeed


1 Answers

You can use this SongQuery.swift class

// // SongQuery.swift //

import Foundation
import MediaPlayer

struct SongInfo {

    var albumTitle: String
    var artistName: String
    var songTitle:  String

    var songId   :  NSNumber
}

struct AlbumInfo {

    var albumTitle: String
    var songs: [SongInfo]
}

class SongQuery {

    func get(songCategory: String) -> [AlbumInfo] {

        var albums: [AlbumInfo] = []
         let albumsQuery: MPMediaQuery
        if songCategory == "Artist" {
            albumsQuery = MPMediaQuery.artists()

        } else if songCategory == "Album" {
            albumsQuery = MPMediaQuery.albums()

        } else {
            albumsQuery = MPMediaQuery.albums()
        }


       // let albumsQuery: MPMediaQuery = MPMediaQuery.albums()
        let albumItems: [MPMediaItemCollection] = albumsQuery.collections! as [MPMediaItemCollection]
      //  var album: MPMediaItemCollection

        for album in albumItems {

            let albumItems: [MPMediaItem] = album.items as [MPMediaItem]
           // var song: MPMediaItem

            var songs: [SongInfo] = []

            var albumTitle: String = ""

            for song in albumItems {
                if songCategory == "Artist" {
                    albumTitle = song.value( forProperty: MPMediaItemPropertyArtist ) as! String

                } else if songCategory == "Album" {
                    albumTitle = song.value( forProperty: MPMediaItemPropertyAlbumTitle ) as! String


                } else {
                    albumTitle = song.value( forProperty: MPMediaItemPropertyAlbumTitle ) as! String
                }

                let songInfo: SongInfo = SongInfo(
                    albumTitle: song.value( forProperty: MPMediaItemPropertyAlbumTitle ) as! String,
                    artistName: song.value( forProperty: MPMediaItemPropertyArtist ) as! String,
                    songTitle:  song.value( forProperty: MPMediaItemPropertyTitle ) as! String,
                    songId:     song.value( forProperty: MPMediaItemPropertyPersistentID ) as! NSNumber
                )
                songs.append( songInfo )
            }

            let albumInfo: AlbumInfo = AlbumInfo(

                albumTitle: albumTitle,
                songs: songs
            )

            albums.append( albumInfo )
        }

        return albums

    }

    func getItem( songId: NSNumber ) -> MPMediaItem {

        let property: MPMediaPropertyPredicate = MPMediaPropertyPredicate( value: songId, forProperty: MPMediaItemPropertyPersistentID )

        let query: MPMediaQuery = MPMediaQuery()
        query.addFilterPredicate( property )

        var items: [MPMediaItem] = query.items! as [MPMediaItem]

        return items[items.count - 1]

    }

}

And For your View Controller Code Show songs in table view controller

import UIKit
import MediaPlayer
import AVFoundation

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet var tableView : UITableView?
    let myTableView: UITableView = UITableView( frame: CGRect.zero, style: .grouped )

    var albums: [AlbumInfo] = []
    var songQuery: SongQuery = SongQuery()
    var audio: AVAudioPlayer?

    override func viewDidLoad() {

        super.viewDidLoad()
        self.title = "Songs"
        MPMediaLibrary.requestAuthorization { (status) in
            if status == .authorized {
                self.albums = self.songQuery.get(songCategory: "")
                DispatchQueue.main.async {
                    self.tableView?.rowHeight = UITableViewAutomaticDimension;
                    self.tableView?.estimatedRowHeight = 60.0;
                    self.tableView?.reloadData()
                }
            } else {
                self.displayMediaLibraryError()
            }
        }

    }

    func displayMediaLibraryError() {

        var error: String
        switch MPMediaLibrary.authorizationStatus() {
        case .restricted:
            error = "Media library access restricted by corporate or parental settings"
        case .denied:
            error = "Media library access denied by user"
        default:
            error = "Unknown error"
        }

        let controller = UIAlertController(title: "Error", message: error, preferredStyle: .alert)
        controller.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
        controller.addAction(UIAlertAction(title: "Open Settings", style: .default, handler: { (action) in
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!, options: [:], completionHandler: nil)
            } else {
                // Fallback on earlier versions
            }
        }))
        present(controller, animated: true, completion: nil)
    }

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return albums.count
    }

    func tableView( _ tableView: UITableView, numberOfRowsInSection section: Int ) -> Int  {

        return albums[section].songs.count
    }

    func tableView( _ tableView: UITableView, cellForRowAt indexPath:IndexPath ) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(
            withIdentifier: "MusicPlayerCell",
            for: indexPath) as! MusicPlayerCell
        cell.labelMusicTitle?.text = albums[indexPath.section].songs[indexPath.row].songTitle
        cell.labelMusicDescription?.text = albums[indexPath.section].songs[indexPath.row].artistName
        let songId: NSNumber = albums[indexPath.section].songs[indexPath.row].songId
        let item: MPMediaItem = songQuery.getItem( songId: songId )

        if  let imageSound: MPMediaItemArtwork = item.value( forProperty: MPMediaItemPropertyArtwork ) as? MPMediaItemArtwork {
            cell.imageMusic?.image = imageSound.image(at: CGSize(width: cell.imageMusic.frame.size.width, height: cell.imageMusic.frame.size.height))
        }
        return cell;
    }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {

        return albums[section].albumTitle
    }
   func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let songId: NSNumber = albums[indexPath.section].songs[indexPath.row].songId
    let item: MPMediaItem = songQuery.getItem( songId: songId )
    let url: NSURL = item.value( forProperty: MPMediaItemPropertyAssetURL ) as! NSURL
    do {
        audio = try AVAudioPlayer(contentsOf: url as URL)
        guard let player = audio else { return }

        player.prepareToPlay()
        player.play()
    } catch let error {
        print(error.localizedDescription)
    }

    self.title = albums[indexPath.section].songs[indexPath.row].songTitle
  }
}

**

Don't Forgot add frameworks MediaPlayer.framework, MediaToolbox.framework, AudioToolbox.framework

**

like image 82
Yogendra Girase Avatar answered Nov 09 '22 19:11

Yogendra Girase