Search code examples
iosiphoneswiftavplayeritem

Issue with getting information from a music track


I am trying to get some information from a music track, everything works fine but some music has no title , artist and cover artwork , and in this case I have to provide a default value for example Unknown.

I am filling table view with track's information like this :

//MARK: - Get Data From Track :
func getDataFromTrack(file:URL)  {

    //Get data from track
    urlAsset = AVURLAsset(url: file)
    for format in urlAsset.availableMetadataFormats {

        for metadata in urlAsset.metadata(forFormat: format) {

            //Track Name :
            if metadata.commonKey == "title" {
                if let title = metadata.stringValue {
                    appDefaults.setTrack(Name: title)
                } else {
                    appDefaults.setTrack(Name: "Unknown")
                }
            }



                //Track Artist:
            if metadata.commonKey == "artist" {
                    if let artist = metadata.stringValue {
                        appDefaults.setArtist(Name: artist)
                    } else {
                        appDefaults.setArtist(Name: "Unknown")
                    }
                }


            //Track Cover:
            if metadata.commonKey == "artwork" {
                if let data = metadata.dataValue {
                    let image = UIImage(data: data)
                    appDefaults.setCover(Image: image!)
                }  else {
                    appDefaults.setCover(Image: #imageLiteral(resourceName: "Defualt cover"))
                }
            }


            appDefaults.setTrack(duration: Float(CMTimeGetSeconds(urlAsset.duration)))
        }
    }
}

In table view :

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


... setup cell 

 let fileName = player.MP3DirectoryFiles[indexPath.row-2] as! NSString
            let absoluteFileName = String(describing: fileName.lastPathComponent)
            let removeSpaceString = absoluteFileName.replacingOccurrences(of: "%20", with: " ")


            //Get MP3 Infromations
            let documentsURL = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!,isDirectory: true )
            let urlToMyPath = documentsURL.appendingPathComponent(removeSpaceString)!

            player.getDataFromTrack(file: urlToMyPath)

}

If there is no data from track cell fill its data for example title with other tracks information !

I tried to get nil value like this , but did not help me :

if metadata.commonKey == "artist" {
                    if let artist = metadata.stringValue {
                        appDefaults.setArtist(Name: artist)
                    } else {
                        appDefaults.setArtist(Name: "Unknown")
                    }
                }

Solution

  • Try setting your default values first, and then updating them if and when the corresponding tags are found for the asset:

    //MARK: - Get Data From Track :
    func getDataFromTrack(file:URL)  {
        // Set defaults
        appDefaults.setTrack(Name: "Unknown")
        appDefaults.setArtist(Name: "Unknown")
        appDefaults.setCover(Image: #imageLiteral(resourceName: "Defualt cover"))
        appDefaults.setTrack(duration: Float(CMTimeGetSeconds(urlAsset.duration)))
    
        //Get data from track
        urlAsset = AVURLAsset(url: file)
        for format in urlAsset.availableMetadataFormats {
            for metadata in urlAsset.metadata(forFormat: format) {
    
                //Track Name :
                if metadata.commonKey == "title" {
                    if let title = metadata.stringValue, !title.isEmpty {
                        appDefaults.setTrack(Name: title)
                    }
                }
    
                //Track Artist:
                if metadata.commonKey == "artist" {
                    if let artist = metadata.stringValue, !artist.isEmpty {
                        appDefaults.setArtist(Name: artist)
                    }
                }
    
                //Track Cover:
                if metadata.commonKey == "artwork" {
                    if let data = metadata.dataValue {
                        let image = UIImage(data: data)
                        appDefaults.setCover(Image: image!)
                    }
                }
            }
        }
    }
    

    The code where you try to set the default value will never be called if the asset does not contain the appropriate key. Also, setting the track duration inside the for loops will cause it to be unnecessarily executed multiple times.