How to get Spotify iOS currently playing track - swift

I'm using SPTAudioStreamingController.sharedInstance().metadata.currentTrack?.uri to get the currently playing track, but sometimes it returns the next song on the playlist, instead of what is playing right now.
Edit: I think it may have to do with the playlist it is playing from, since whenever I skip a track, it deletes from the playlist. Is there a way to play from the top song in the playlist every time a skip occurs?
Or even better: Is there a way to refresh a playlist?

You can use a delegate method and locally keep track of what track is playing:
func audioStreaming(_ audioStreaming: SPTAudioStreamingController!, didStartPlayingTrack trackUri: String!) {
self.currentURI = trackURI
}
Whenever a track starts playing, the delegate method will fire and you can locally store the current URI. Just make sure to also utilize the other delegate methods like didStopPlayingTrack in order to ensure you have all the correct information.

Related

AVAudioPlayerNode - Get Player State?

In an iOS-project I am using the AVAudioPlayerNode in conjunction with the AVAudioEngine and an AVAudioUnitTimePitch. Everything works peachy. However, I was wondering if there is a way to figure out what the current player's state (e.g. isPlaying, isPaused) or at least the playback position is.
While AVAudioPlayer at least allows you to get the currentTime-parameter, I could not yet figure out how to get that information with AVAudioPlayerNode. I tried playing around with the nodeTimeForPlayerTime and playerTimeForNodeTime methods described in the swift documentation but I couldn't make any progress.
Any help would be highly appreciated.
Since the AVAudioPlayerNode is designed as an audio stream, it doesn't necessarily keep track of the time within a particular file. However, the AVAudioPlayerNode does keep a running time of how long its been playing all audio. This timer doesn't reset with each file, in order to change it, you must explicitly tell it where you want to start counting from.
So to find the current time the player has been playing you must do the following:
player.lastRenderTime.sampleTime / file.fileFormat.sampleRate
Now in order to get the timer to reset after each file, you must explicitly reset the players current time. To do this use the player.playAtTime: function.
If you would like an example, check one out here: https://github.com/danielmj/AEAudioPlayer

Prevent MPMusicPlayerController from playing next song in que

I am creating an app that has a playlist and uses the MediaPlayer library. When a song ends I don't want the next song to start. I tried to use the MPMusicPlayerControllerNowPlayingItemDidChangeNotification to pause the music player when the song changes, but the song starts to play before I get the chance to stop it. I also tried to use KVO to track the changes to musicPlayer.currentPlaybackTime, but I only receive messages when i manually change the playback time. I can't find any information about this problem anywhere.
In my app I have shuffle and repeat off, and create a queue with only one song in it, then send that to the music player. When the song finishes, there aren't any other songs in the queue, so it stops playing.
That being said, the latest iOS update has stopped reporting the correct playback state when the song finishes and is reporting it as paused when it used to be stopped. Not sure if that's a side-effect of the above method or not.
Are you calling:
player.beginGeneratingPlaybackNotifications()
before adding the observers?

Is there a way to get information about the previous iPod song?

I'm trying to store the playhead time of a song (MPMediaItem) before the next song begins to play. How would you do that?
Is there something like MPMusicPlayerControllerNowPlayingItemDidChangeNotification which fires before the song changes?
Simple: When the song changes, set a variable foo somewhere to the current time, and set another variable bar to the new song's current playback time (usually gonna be 0.0.) When the song changes again, subtract the value of foo from the current time, then add the value of bar; the result is the final offset of the song that was just being played.
You'll also have to handle fast forward, rewind, stop, and pause, but you can do that by monitoring the playback state and querying the song's current playback time to keep yourself in sync as needed.
I do'nt think, there is such notification(Notify before song change) exist today.
I just find only two notification which can be listen for songs change state.
MPMusicPlayerControllerNowPlayingItemDidChangeNotification,
MPMusicPlayerControllerPlaybackStateDidChangeNotification,
Apple Documentation:
http://developer.apple.com/library/ios/#documentation/mediaplayer/reference/MPMusicPlayerController_ClassReference/Reference/Reference.html
I think there is no notification before media item is changed. The best way seems to use a timer to constantly copying the value from media player to a variable to store NSTimeInterval, until media item is changed or media player state is changed.

How do you send messages between two instances of a custom UITableViewCell?

I have a UITableView populated with a bunch of music players that I've made using a custom UITableViewCell. (as shown in the screenshot linked here: screenshot).
The problem with the way I have it coded is that since each cell is completely independent, there's no way for one tableviewcell to check if any other the other cells have audio playing. This means that when I run my app, I am able to play more than one audio file at the same time.
Ultimately, how would I go about putting some sort of check in place so that when the user hits the play button, the app first checks to see if any other cell is playing audio, and, if so, stops them before playing its own audio file?
Please let me know if you would like me to post my project.
Thank you!
For starters I can't think of any good reason the cells themselves should be responsible for playing the audio. They should be responsible for telling some other object (like whatever controller is responsible for the UITableView) to play the audio. That controller would obviously then know to stop whatever it was already playing before playing something else.
In general, it's not a great idea to be putting that much logic into a 'view.'
It would probably be easiest to use notifications (NSNotification and NSNotificationCenter).
Use a common notification name for starting and stopping.
MusicPlayerWillPlay
MusicPlayerWillStop
When you create each player, register for both notifications. Then when playerA is going to play, it posts a MusicPlayerWillPlay notification. playerB, playerC and playerD, will get this notification, and if they are playing, will stop.
One caveat is that each player is unaware of the others, so you have to register with a nil object, which means playerA will get it's own notification. So in your notification method, you'll probably want to do something like
{
//...
if (sender == self)
return;
//...
}

MPMovie player how to get the amount of time played?

I was trying to go through the iPhone's sample code for mediaplayer.
I want to be able to capture the amount of time the media player has played the video. The duration at which the media player has stopped. Is there a method or property that will tell me the duration of play of the media??
Unfortunately the current API for MPMoviePlayerController allows basically no control. You can tell it to play and stop... otherwise where's a delegate method so you can be notified when the movie finishes playing and that's it, there's no additional controls. (a real bummer)
However, while we cant discuss the new 3.2 SDK yet, I'll give you a tip and say go look at the documentation of MPMoviePlayer in 3.2 and I think you'll be happy.
http://developer.apple.com/iphone/prerelease/library/documentation/MediaPlayer/Reference/MPMoviePlayerController_Class/MPMoviePlayerController/MPMoviePlayerController.html
moviePlayer.currentPlaybackTime
It's not possible to do KVO on it but you could do like me and create an scheduledTimer which updates every second to check what the current playbacktime is and update your graphics accordingly :)
Yes, You can use the property "duration" defined by MPMediaPlayerController. Plese try it out and check the output. U can refer the here duration property