Problems with currentPlaybackTime and MPMusicPlayerController and iOS 7.1 - ios

Having problems setting currentPlaybackTime with MPMusicPlayerController in iOS 7.1.
I used to be able to simply do the following:
MPMusicPlayerController *iPodController =
[MPMusicPlayerController applicationMusicPlayer];
iPodController.currentPlaybackTime = 30.0;
[iPodController play];
And the music player would seek to 30 seconds in and play.
As of iOS 7.1 this is not the case.
If I do the following:
[iPodController play];
iPodController.currentPlaybackTime = 30.0;
Then it "may" jump 30 secs in or not. Very inconsistent.
This used to work for all previous iOS versions. Is there a way to fix this?

I find that I can't set currentPlaybackTime before playing a given song.
Using your first snippet:
iPodController.currentPlaybackTime = 30.0;
[iPodController play];
setting the currentPlaybackTime property does nothing and I can't seek to the desired playback time. But making the calls the other way around have worked consistently for me with iOS 7.1 so far:
[iPodController play];
iPodController.currentPlaybackTime = 30.0;

Related

MPMusicPlayerController won't seek to given playbackTime

I want MPMusicPlayerController.applicationMusicPlayer() instance to start playing from a specific starting time:
applicationMusicPlayer.setQueueWithStoreIDs([String(track.id)])
applicationMusicPlayer.currentPlaybackTime = 10.0
print(applicationMusicPlayer.currentPlaybackTime) // will print 10.0
But as soon as the player starts playing the item, it will reset its currentPlaybackTime to zero and will start from the beginning:
applicationMusicPlayer.play()
print(applicationMusicPlayer.currentPlaybackTime) // will print 0.0
I thought maybe it's because I set the playback to the player that has just been created and is not ready yet, but neither .prepareToPlay() or .isPreparedToPlay() help me with that situation.
I even tried to wait for a few seconds and only then start the playback from the position that I've set. No success at all, extremely frustrating.
Maybe it is somehow connected to the fact that I'm playing songs from Apple Music directly? I can't switch to AVPlayer 'cause I have to play music from Apple Music.
Would appreciate any thoughts and help!
UPDATE: I found the method beginSeekingBackward at the MPMediaPlayback and it says that if the content is streamed, it won't have any effect:
https://developer.apple.com/documentation/mediaplayer/mpmediaplayback/1616248-beginseekingbackward?language=objc
Seems like only built-in Music app has a control over streaming music playback?
I had just run into this exact problem. I managed to get around it with the follow code.
It creates a background thread that continuously checks the currentPlaybackTime of the player. As soon as currentPlaybackTime is not the time I set it to be I set currentPlaybackTime back to what I wanted.
It feels like a terrible hack but it's working for me so far.
MPMusicPlayerController *player = [MPMusicPlayerController systemMusicPlayer];
player.currentPlaybackTime = _startTime;
[player play];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
dispatch_async(queue, ^{
while(true) {
if (player.currentPlaybackTime != _startTime) {
player.currentPlaybackTime = _startTime;
break;
}
}
});

How to Speed up the audio Playing in MpMoviePlayerController

I am using MPMoviePlayerController in my app to play the video and audios. I want to give an option to user to play the audio/video slower/faster then the normal speed i.e 0.5x (slower then normal ), 1x (normal speed), 2x (double speed then normal.).
I want to know is there any way that i can speed up/down the MPMoviePlayerController streaming so that user can have options to listen/view the audio/video at slower/faster speed.
i found the solution to this problem myself.
When you use MPMoviePlayerController and make its instance then you have a property of MpMoviePlayerController as currentPlaybackRate. It is set to 1.0 by default means normal playing. If you sets its value to 1.5 or 2.0 then it will play the currently playing audio at that speed.
See the following code.
MPMoviePlayerController *moviePlayer = [MPMoviePlayerController alloc]init];
moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
moviePlayer.contentURL = #"http://someduumyUrl.com" ;
moviePlayer.controlStyle = MPMovieControlStyleDefault;
[moviePlayer prepareToPlay];
moviePlayer.currentPlaybackRate = 2.0 // will play the audio at double speed.

MPMoviePlayerController setFullScreen animated bug on iOS 8.0 but not on iOS 8.1

I have and MPMoviePlayerController in my project. I tried to run it on iOS 8.0. When I play the video for the first time, It works fine and I have the progress bar of the video. Then I quit and try to play the video for the second time. It still works except than I don't have the progress bar of the video. I said in the title "setFullScreen:animated" because I also had the error "CGImageCreate : invalid image size 0x0" so I guess It can come frome here.
Also, it appears to work without any problem on iOS 8.1, so I think it's bug corrected by Apple. Maybe someone have heard something about it.
Here is some code when the Controller is created and setted :
_moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:
[NSURL fileURLWithPath:self.model.filePath]];
_moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
_moviePlayer.view.backgroundColor = [UIColor blackColor];
_moviePlayer.view.frame = self.imageButton.frame;
[self.view addSubview:_moviePlayer.view];
[_moviePlayer setFullscreen:YES animated:YES];
[_moviePlayer prepareToPlay];
Any guess ?

UISlider and playing sound in iOS

I'm trying to use a UISlider to play sound in a fashion which emulates how a violin bow would play on a string. At current, I can get sound playing from the slider however the functionality isn't correct.
-(IBAction) slider
{
NSString* path = [[NSBundle mainBundle] pathForResource:#"im_on" ofType:#"mp3" ];
if (song) [song release];
song = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[song play];
}
This is code and there is not much else to it. I have linked this method in IB to a slider which is triggered on the event Value Changed. When set to continuous = YES, when the slider begins to slide, the sound plays. However if it continues to slide the sound will stop until the slider stops where it then play again. When set to continuous = NO, the sound does not play when the value changes but when the touch is lifted. the sound continues to play while the value is hanging after that.
Is there a way to have the sound continue to play until the slider stops/changes direction/touch is released? i.e override all but the first value changed sent event until x condition is met.

iOS AVAsset.duration is zero for HTTP live streaming but works for progressive

I have an iOS app that plays video from a HTTP Live stream "playlist.m3u8" and I have a custom player created using AVPlayer. To handle normal user interactions such as scrubbing i need to get the duration of the video, but for some reason on iOS 4.3 using xcode 4.0 when I call the following code I get a CMTime that when converted to seconds gives a NaN -- I know what it's doing because CMTimeValue = 0 and CMTimeScale = 0 which gives the NaN and the CMTimeFlags = 17 which is even more strange.
Here's the code I uses which isn't complex at all:
AVPlayerItem *pItem = mPlayer.currentItem;
AVAsset* asset = pItem.asset;
CMTime d = asset.duration;
double duration = CMTimeGetSeconds(asset.duration);
I should also mention that I do monitor the status of the loading playlist to make sure it's ready before i start playing/scrubbing:
[mPlayer addObserver:self forKeyPath:#"currentItem.status" options:0 context:VideoPlaybackViewDelegateStatusContext];
Thanks for any help on this issues anyone could provide.
https://developer.apple.com/library/ios/releasenotes/AudioVideo/RN-AVFoundation-Old/#//apple_ref/doc/uid/TP40011199-CH1-SW4
The docs above mention that duration should now be obtained from the AVPlayerItem instance, rather than its corresponding AVAsset. To get the duration from the current player item via key-value observing, I use the following method (originally pulled from NGMoviePlayer which was written for iOS 4.0):
- (void)loadPlayerWithItem:(AVPlayerItem *)playerItem {
self.player = [AVPlayer playerWithPlayerItem:playerItem];
...
// changed this from previous value currentItem.asset.duration
[self.player addObserver:self forKeyPath:#"currentItem.duration"
options:0
context:nil];
...
}
I implemented the above change in my player and the duration is working now! This change in AVFoundation was the root cause of the issue. CMTimeFlags = 17 indicates kCMTimeFlags_Indefinite & kCMTimeFlags_Valid, and the docs specify:
In particular, the duration reported by the URL asset for streaming-based media is typically kCMTimeIndefinite, while the duration of a corresponding AVPlayerItem may be different and may change while it plays.

Resources