objective c iphone musicplayer crashing - objective-c

I am creating a non appstore jailbreak tweak and I came across a problem that causes my app to crash.
I am using musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
the music player has complete functionality, play/pause, next, previous. it displays the title of the song, the artist, the artwork and everything.
the problem seems to be the loading and unloading of the musicplayer.
for example, if i am running the app, and i close the iphone's Music app, it will cause my app to crash. also if i load the app without the Music app running in the background it will crash.
as long as the music app is running in the background my app will not crash.
can anyone help me with this?
is something to be set to nil? or how do i go about releasing them?
should they be synthesize/property?

I was having this problem also for my tweak, and I couldn't figure out a way to fix it. I ended up using the AVPlayer Method, It seems to work well for me. Granted I only need to play one song, so if you need to play a playlist of some sorts you are out of luck.
I used it like the following in the mediapickerclass:
NSURL *url = [[mediaItemCollection.items objectAtIndex: 0] valueForProperty:MPMediaItemPropertyAssetURL]
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:url];
AVPlayer *player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
[player play];
If you need you need to reference it from somewhere else you can just write the url to a .plist

Related

MPMoviePlayerController Background playing

Okay guys i have a problem. I'm stream MPMoviePlayerController and i want it to play audio in background and i've somewhat achieved this.
This is what i do in my -didFinishLaunchingWithOptions:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
Now whenever the application calls -applicationWillResignActive:
i do a post notification to continue the playback. And this works but it's an ugly fix. As there is a second delay between the sound stopping and the notification being called. So the playback stops for a second and then continues again by calling the notification which just says [viewPlayer play];
And many other have achieved smooth background playback. Like spotify or other apps whenever you enter background mode there is no sound lag/clipping in sound. This is really annoying to listen to whenever i press the home button or lock the phone.
Yes i did set the background mode for playback.
I have also tried -applicationDidEnterBackground: but this notification is even slower. It comes after -applicationWillResignActive:
I have no idea how to fix this, and or how others achieved it. I have looked through almost all other similar questions. None have my problem.
Thanks in advance.
I've recently used a framework to stream YouTube video inline in a UIView. This framework has a category on MPMoviePlayerController which works pretty well. You notice a change in the music when going to background but it is still acceptable.
The category can be found here:
MPMoviePlayerController+BackgroundPlayback.h
MPMoviePlayerController+BackgroundPlayback.m

playing a youtube movie from url in objective C

I have a tableview which contains youtube urls.
http://www.youtube.com/v/M67PNWvKdg0&autoplay=1
I am trying to play the video file with the following piece of code. I also imported the media framework.
Video *video = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSURL *urlString=[NSURL URLWithString:video.url];
//NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
//pathForResource:#"Video1" ofType:#"mp4"]];
MPMoviePlayerViewController *playercontroller = [[MPMoviePlayerViewController alloc]
initWithContentURL:urlString];
[self presentMoviePlayerViewControllerAnimated:playercontroller];
playercontroller.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[playercontroller.moviePlayer play];
playercontroller = nil;
What it does for now is it pops up a movie player but then immediately goes back to my tableview. Does anybody knows what the problem is?
Thanks in advance
Are you working on iOS 6? I found difficulty in playing Youtube videos through MPMoviePlayerController, so I found out this to be very useful.
This has MPMoviePlayerController only...
And this would work well for Versions < iOS 6 too.
You can't play youtube videos via Media Player. You have only two solutions: open the link via external app (just open it and iOS will run Safari or YouTube.app if installed) or you can implement your own view with UIWebView and open the link inside WebView.
May be this link would help you, and one more thing is the video plays only on device cant test on a simulator.
There's another way but you have to be a little adventurous.
You can use a third party rtsp framework of which there are a few.
Then you need to link to the m.youtube.com, this is the rtsp version of youtube that Android and other phones will get you to.
If you try to open this link in safari on the iphone the page redirects to the h264 links.
You can open the url in an uitableview and change the user-agent tag. Or simply copy the links you want into a table.
Are all youtube videos automatically converted to h264 now, at one time I remember they were a subset of the rtsp pages.
If you have an Android device you can access this page in a webview quite easily.
here check this link out.
http://streammore-tv.tumblr.com/post/34794206547/welcome

NSUserNotification with custom soundName

Did anyone manage to make a NSUserNotification soundName to work with a custom sound?
I tried with aif and caf format 44100KHz 16bit 2 second of duration. The notification is displayed at the proper time, with the right title and text, but the default sound gets played instead of my custom sound.
The sound files are correctly copied in the application bundle.
If I try this the sounds work ok:
NSSound* sound = [NSSound soundNamed:#"morse.aif"];
[sound play];
But when I use the same sound in my notification, the default notification sound gets played:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Insert code here to initialize your application
NSUserNotification* notification = [[NSUserNotification alloc]init];
notification.title = #"Titolo";
notification.deliveryDate = [NSDate dateWithTimeIntervalSinceNow:10];
notification.soundName = #"morse.aif";
[[NSUserNotificationCenter defaultUserNotificationCenter]scheduleNotification:notification];
}
I tried with and without extension, but with no success.
notification.soundName = #"morse.aif";
notification.soundName = #"morse2.caf";
notification.soundName = #"morse";
none of these work.
My application is not signed and not sandboxed, but I don't think that's necessary for user notifications, and apart from the sound problem the notifications work great.
It seems to me like this issue is case-sensitivity. Using notification.soundName = #"Morse"; works perfectly for me. As you can see in the NSSound documentation for soundNamed The search folders for sounds are, in order:
~/Library/Sounds
/Library/Sounds
/Network/Library/Sounds
/System/Library/Sounds
If you look in the last one, which is probably where you're trying to pull from since they're the sounds in System Preferences, you can see their names
So keep the case of the file, and omit the extension and it should work as expected.
If you have multiple versions of your App binary notification center may be searching the wrong binary for your sound files.
If you make sure to delete any old copies of the binary it should fix the issue.
From the Apple Dev Forums: https://devforums.apple.com/message/708511
This can happen if you have multiple version of your app binary floating around. NotificationCenter only fines one of them. If it is the one without the sound then it will not work.

AVQueuePlayer playing items simultaneously rather than in sequence

I am trying to put together a simple app to play a pre-roll video followed by some content video.
Currently, I'm trying to use the AVQueuePlayer class to get this done. Unfortunately, it seems to want to play the videos properly in sequence.
For example, the pre-roll plays by itself for a few seconds, then (prior to the pre-roll being complete) it starts to try and play the content video. For a few seconds, the player seems to be at war with itself and switches back and forth between the two videos (neither playing very well at all). Finally, when the pre-roll is finished, the content video then plays the rest of the way normally.
I've looked through the documentation for the AVQueuePlayer and I don't see anything obvious that I'm missing.
My code is pretty basic:
AVPlayerItem *preRollItem = [AVPlayerItem playerItemWithURL: preRollUrl];
AVPlayerItem *contentItem = [AVPlayerItem playerItemWithURL: contentUrl];
self.player = [AVQueuePlayer queuePlayerWithItems:[NSArray arrayWithObjects:preRollItem, contentItem, nil]];
[self.player play];
What is the trick to getting the videos to play in sequence.
Make sure you are actually testing on the device. From my experience the iOS5 simulator has big problems with AVQueuePlayer and does bizarre things.
I found the iOS4.3 simulator is doing a much better job when it comes to testing AVFoundation.

How do you know when a user chooses to play a video through AirPlay?

I have a custom video player set up with custom controls, and I utilize MPVolumeView to provide an airplay button. When a user chooses to use AirPlay, they interact with that Apple UI and there is no event (that I can find) that says "hey, the video is now playing over AirPlay".
The problem is that, if I close the player and reopen it, it loads the movie (load state changes to MPMovieLoadStatePlayable), I play it, and I immediately get a playback did finish notification with reason being MPMovieFinishReasonPlaybackEnded, and the video continues to try to play through AirPlay. I'm certain the movie stops and is deallocated whenever I close the player.
If anyone has any advice on how to handle this, knows some events to listen for, or has any ideas about this whatsoever, please let me know. Thanks!
The answer here turns out to be that, at least up to 4.3, there is no way to get an answer to this through code.
The problem in this case is how you dispose of the MPMoviePlayerController when you're finished with it. Even if the video plays through, before you finally release it, you have to call pause and then stop. Like this:
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] init];
// use the player. then when done with it:
[mp pause];
[mp stop];
[mp release];
If you don't do this then the next time you create a MPMoviePlayerController, certain properties are somehow ghosted in the framework. Playing a video progressively caused audio from the previous mp to play while the new mp did its initial buffering. Also, if the previous video was playing over airplay, the next video would get a notification that the video finished right after it starts and some other weirdness.
Long story short, dispose of your video players with the above sequence to avoid issues with later movie players.