I'm working on code that looks at the user's videos and passes them along to AVPlayer by way of an AVPlayerItem which takes a URL.
To get all the videos on an iOS device, you can do:
let videoNumber = MPMediaType.anyVideo.rawValue
let predicate = MPMediaPropertyPredicate.init(value: videoNumber, forProperty: MPMediaItemPropertyMediaType)
let query = MPMediaQuery.init()
query.addFilterPredicate(predicate)
if let items = query.items
{
mediaCollection = MPMediaItemCollection(items: items)
// -1 would indicate an error condition
print("number of items in collection is \(mediaCollection?.count ?? -1)")
}
When you select the MPMediaItem you want to use from the items array, there should be an assetURL to go with it.
Trouble is, on my device, all of my assetURL properties are NULL. Coincidentally, while hasProtectedAsset for each of these items is false, isCloudItem for each of these items is true.
How can I come up with a valid assetURL that I can pass along to any media player? It feels somewhat bogus that developers can't get proper references & access to media in a user's iPod library.
Related
I try to get file list from the Music Library (iPod Music Library), but I can't do it, my list is always empty. I sure that I have tracks in Music Library, I check it in other app - and it works. But as I remember that application sent me a request to access the Music Library. Perhaps I also need to create such a request? Help me solve the problem. I use this code to get file list:
func fetchFileList() {
let mediaItems = MPMediaQuery.songs().items
let mediaCollection = MPMediaItemCollection(items: mediaItems ?? [])
print("mediaCollectionItems: \(mediaCollection.items)") //It's always empty
//Then I'd like to get url of the track
//let item = mediaCollection.items[0]
//let pathURL = item.value(forProperty: MPMediaItemPropertyAssetURL) as? URL
//print("pathURL: \(pathURL)")
}
If you want to access the Music Library, you have to add NSAppleMusicUsageDescription key to your Info.plist with a description about what you want to do with the music.
Se apple documentation for more info: MediaPlayer Documentation
I understand how to enumerate images and video in the photo library using PHPhotoLibrary, but videos added through iTunes as "home videos", and visible only through the new TV app under the Home Video section, don't appear in that enumeration.
Is there another way of querying for them?
Well, it looks like the only other thing you can try to use are the Media Player API's.
https://developer.apple.com/documentation/mediaplayer/mpmediaquery
A query that specifies a set of media items from the device's media
library by way of a filter and a grouping type.
That might work, since I assume that your synced movies are part of the media library and not part of the photo library.
First you need to add the NSAppleMusicUsageDescription to your Info.plist. Then we can use MPMediaQuery and filter out the home video items.
let predicate: MPMediaPropertyPredicate = MPMediaPropertyPredicate(value: MPMediaType.homeVideo.rawValue, forProperty: MPMediaItemPropertyMediaType)
let query: MPMediaQuery = MPMediaQuery.init()
query.addFilterPredicate(predicate)
let items = query.items
for item : MPMediaItem in items!
{
// Here is your home video
}
See the MPMediaTypeHomeVideo item: https://developer.apple.com/documentation/mediaplayer/mpmediatype/mpmediatypehomevideo
Now items should contain all your home videos.
EDIT: I tested it, and it works for me on iOS 12, however title seems to be empty. You can access the video file itself using the assetURL property.
Here's an updated method.
import MediaPlayer
func video() {
MPMediaLibrary.requestAuthorization() { status in
if status == .authorized {
let predicate: MPMediaPropertyPredicate = MPMediaPropertyPredicate(value: MPMediaType.homeVideo.rawValue, forProperty: MPMediaItemPropertyMediaType)
let query: MPMediaQuery = MPMediaQuery.init()
query.addFilterPredicate(predicate)
if let items = query.items {
for item in items {
// Here is your home video
print(item.title ?? "title?")
}
}
}
}
}
you'll need to add this key to your info.plist
Privacy - Media Library Usage Description
So I'm building some playlist and song retrieval into my app at the moment, and I'm really confused by some of the results I'm getting back from the API. It seems to be returning songs that no longer exist on Spotify or have been long removed from a playlist.
Retrieving a list of Playlists from a user is working fine, but just in case this problem is arising from the way I draw that playlist's tracks, here is the code I use to get them:
SPTPlaylistSnapshot.playlistWithURI(uri, accessToken: session.accessToken) { (error, playlistSnapshotOb) -> Void in
if let playlistSnapshot = playlistSnapshotOb as? SPTPlaylistSnapshot {
let itemz = playlistSnapshot.firstTrackPage.items //tracksForPlayback()
for item in itemz{
let track = item as! SPTPlaylistTrack
let splice = "\(track.uri)"
let trackURI = splice.stringByReplacingOccurrencesOfString("spotify:track:", withString: "")
var displayArtist = String()
let artistz = track.artists
if artistz.count > 1{
for i in 0...(artistz.count - 1){
let itz = artistz[i] as! SPTPartialArtist
if i > 0 {
displayArtist += ", \(itz.name)"
}else{
displayArtist += "\(itz.name)"
}
}
self.tracks.append(track.name)
self.ArtistObjects.append(displayArtist)
self.uriS.append(trackURI)
}else{
let singularArtist = artistz[0] as! SPTPartialArtist
displayArtist = singularArtist.name
self.tracks.append(track.name)
self.ArtistObjects.append(displayArtist)
self.uriS.append(trackURI)
}
Additionally, below is a screenshot of the desktop Spotify app showing the real content of the playlist I am pulling:
Spotify per Desktop
You'll see that the songs "Big Bank Dank" and "Light Day Remix" are not actually on this playlist, but for some reason, on my app below, when I pull this playlist, it has these songs listed:
Spotify In My App
(Apparently I can't post an actual image because of my rep - apologies)
Any idea why it's doing this?
The tracks are probably just not available any longer for some unspecified reason. This is quite common. By default, the Spotify client does not show unavailable tracks in playlists, but in settings there is a toggle you can flip so that they are shown as greyed out instead.
I don't know about iOS SDK, but there should be either an attribute telling you the available markets for the tracks or if it is playable or not, depending on the country of the user being logged in.
This is how it works in the Web API, which should be similar.
https://developer.spotify.com/web-api/track-relinking-guide/
I want to make a simple media player in Swift. I want to make a table with all Albums on the iphone and after selecting the album i want to play the songs of it. But i can not get the album titles (and artwork).
I tried:
var query = MPMediaQuery.albumsQuery()
let mediaCollection = MPMediaItemCollection(items: query.items)
println(mediaCollection.items)
let player = MPMusicPlayerController.systemMusicPlayer()
player.setQueueWithItemCollection(mediaCollection)
player.play()
MPMediaItem has valueForProperty() function. The properties which you need are MPMediaItemPropertyAlbumTitle and MPMediaItemPropertyArtwork.
I am looking for a swift coding playing sound out of the player list and not sounds added as resource to your project.
I mainly found the usage of
NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("sound_name", ofType: "wav"))
println(alertSound)
but for this you need to have the sound file in your bundle. But I couldn't find any example
selecting audio files bought thru itunes and play them.
Any idea how to do this? Can I access my music layer playlist files and using them in my app?
Thanks for any code lines.
rpw
These music files are represented by MPMediaItem instances. To fetch them, you could use an MPMediaQuery, as follows:
let mediaItems = MPMediaQuery.songsQuery().items
At this point, you have all songs included in Music App Library, so you can play them with a MPMusicPlayerController after setting a playlist queue:
let mediaCollection = MPMediaItemCollection(items: mediaItems)
let player = MPMusicPlayerController.iPodMusicPlayer()
player.setQueueWithItemCollection(mediaCollection)
player.play()
You might need to filter songs by genre, artist, album and so on. In that case, you should apply a predicate to the query before fetching the media items:
var query = MPMediaQuery.songsQuery()
let predicateByGenre = MPMediaPropertyPredicate(value: "Rock", forProperty: MPMediaItemPropertyGenre)
query.filterPredicates = NSSet(object: predicateByGenre)
let mediaCollection = MPMediaItemCollection(items: query.items)
let player = MPMusicPlayerController.iPodMusicPlayer()
player.setQueueWithItemCollection(mediaCollection)
player.play()
Cheers!