Objective C (iPhone) Strange Behaviour with musicPlayer API - iphone

I'm developing a music app for iPhone that uses the built in iPod library. I noticed a strange behaviour that I was able to replicate in Apple's sample code entitled "AddMusic" simply by NSLogging out what was going on.
My question is:
Has anyone else encountered this, or better yet found a solution?
The behaviour is:
With the musicPlayer API, one is able to get notifications on state changes of the iPhone's built in iPod. For example, when a song is played or paused, it can shoot off a notification.
You can also queue up songs to be played by invoking a mediaPicker which accesses the music library.
The problem occurs while the API is switching the song from the currently playing one to the new song, which was cued up.
What I noticed is that, in both Apple's sample code and my code, the player state change notification is fired 5 or 6 times, seemingly at random. A sample NSLog is as follows:
2013-08-27 17:24:14.676 AddMusic[418:60b] Paused
2013-08-27 17:24:14.937 AddMusic[418:60b] Playing
2013-08-27 17:24:14.943 AddMusic[418:60b] Paused
2013-08-27 17:24:14.950 AddMusic[418:60b] Playing
2013-08-27 17:24:15.842 AddMusic[418:60b] Paused
2013-08-27 17:24:15.853 AddMusic[418:60b] Playing
I am using X-Code DP6 and iOS 7 B6, but I don't think this is an NDA issue since these commands are old. Just thought I'd provide this information in case this is a new problem.
Thanks!

Related

Using Ti.Media.VideoPlayer video does not loop on iPhone 4

Having a weird problem with my app.
Trying to play a video in a loop (see the code below). VideoPlayer repeatMode is set to Ti.Media.VIDEO_REPEAT_MODE_ONE.
Works in simulator, works on iPhone 4s, works on iPad Air... does not work on iPhone 4 (all of them running iOS 7.1.1 apart from simulator - 7.1).
Exact symptoms: after one play, video should restart from beginning, but it stops. If controls are available, I can press play to start playing it again, then after reaching the end it stops again.
I could swear that it worked on iPhone 4 before the 7.1 upgrade, but somehow it stopped.
Anyone could replicate this issue? Or have any idea?
Sys info:
Titanium SDK: Tested with 3.2.3.GA; 3.2.2.GA; 3.2.1.GA; 3.2.0.GA
Platform & version: iOS 7.1.1 (11D201)
Device: works on iPhone 4s, iPad Air, simulator; fails on iPhone 4
Host Operating System: OSX 10.9.2
Titanium Studio: 3.2.3.201404181442
Xcode: 5.1.1 (5B1008)
Alloy: 1.3.1
Code for basic Alloy project to replicate:
index.js
var videoPlayer = Titanium.Media.createVideoPlayer({
autoplay : true,
fullscreen : false,
mediaControlStyle : Titanium.Media.VIDEO_CONTROL_DEFAULT,
repeatMode: Ti.Media.VIDEO_REPEAT_MODE_ONE,
scalingMode : Titanium.Media.VIDEO_SCALING_ASPECT_FIT
});
//Video is 12s long so it is easy to notice that it does not loop.
videoPlayer.url = "video/candles.mp4";
$.index.add(videoPlayer);
$.index.open();
index.xml
<Alloy>
<Window class="container">
</Window>
</Alloy>
I would appreciate any suggestions.
I have done some research and played around with the Titanium.Media.VideoPlayer and managed to work around the issue. Below you can find the solution in case anyone else encounter this problem.
First of all, some info on the problem.
I have found some forum boards where developers were having very similar problem with MPMoviePlayerController on iPad 1st gen. Looped video was less or more randomly freezing on loop. So I think there is a problem with the Apple video player on some devices, and not necessary with Titanium implementation.
My first approach was to try replay video on complete event that is fired when video stops playing, instead of using repeatMode.
So far so good. It worked on the first time, yay! But the happiness was rather short. During an hour of test of videoPlayer.play() on event complete, the video sometimes was repeating 10-30 times fine and then suddenly was freezing. What gives? Turns out the video player had some sort of a hiccup.
Normal sequence of events was as follows:
video ends, playbackstate changes to 2,
complete event is fired
I restart video on complete
playbackstate changes to 1, video is playing until the end.
For a mysterious reason once in a while this sequence got additional something happening:
video reaches the end - playbackstate changes to 2,
complete event is fired.
video gets restarted on complete
playbackstate changes to 1, video starts playing
suddenly playbackstate changes to 1, video stops, without firing complete event.
Solution
So, knowing all this, I have set up listeners to listen to playbackstate instead of complete and when I hear playbackstate: 1 then I restart video and tadaaa! Everything works!.
Caveat: not 'everything' unfortunately. I am using custom video controls, so I have lost pause, and stop ability (every time video playback state changes to 'stopped' I restart it forcefully). To make it work I have to remember to remove listener every time I press 'pause/stop' buttons and then reattach it afterwards.
Hope that helps someone.

iPhone: MPMusicPlayerController stops AVAudioPlayer

I'm playing a silent music with AVAudioPlayer when user locks the screen, so that my timers won't stop.
However, when I play an iPod music with [MPMusicPlayerController applicationMusicPlayer], AVAudioPlayer stops,without receiving any call back.
Is there any way so that I can start [MPMusicPlayerController applicationMusicPlayer] playing without stoping AVAudioPlayer playing?
EDIT:
Thanks guys, this is the app I'm working on:
It is an Alarm app, this app allows user to lock screen while app is running,and when it is the time of the alarm, app can play iPod music to wake the user.Local notification can not use iPod music as alert sound, so I have to keep the app running while screen is locked.
If user quit the app, it will use local notification as alarm, whose sound is limited to files in bundle.
I can't use UILocalNotification as timer since when in screen locked status(in UIApplicationStatusInactive), app can't receive local notification generated by the system.
Apple has architected their backgrounding system to really limit things like this from happening. Essentially, there is no way for the you to keep the application running in the background unless it needs to be there. If you explain what you are trying to accomplish, maybe a better solution can be found but as good practice, never use random backgrounding methods to do other things. I am assuming that you might be using the faint music as a way to show something custom on the main screen, this is not a good idea.
Your app will get rejected if you play a silent audio.
Also as per apple's documentation https://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/IPhoneOSClientImp/IPhoneOSClientImp.html#//apple_ref/doc/uid/TP40008194-CH103, notifications cannot have sounds (soundName) which play more than 30 seconds.
So you wont be able to release your app in the store.
I figured it out myself.
It is not calling [MPMusicPlayerController +applicationMusicPlayer] that stops AVAudioPlayer, but calling [MPMusicPlayerController -setShuffleMode:], I don't know why calling this would stop AVAudioPlayer, but it is where the problem lies in.
Thanks everyone, I think I should paste my complete code next time.

Iphone sdk - How to play a sound during a phone call after some elapsed time?

Well I am having two issues that i can't get to work, related to audio and calls.
The first one is to play a sound during a phone call. I don't want to play continuous music or stream anything, it is just a simple and short sound that the user will hear at one time during his call.
I have read some posts claiming that this is possible, and I even have an application that does so, but I can't get it to work. My app identifies the call using CTCallCenter and print the logs but never plays the sound or plays it after the app comes to foreground again. I have the .plist property of required background mode App plays audio.
The second issue, is to play the sound after some elapsed time. NSTimers doesn't work when on background mode, nor NSThread sleep on my background process or NSOperation. So how could I play this sound after say 10 seconds of the call?
Also, this behavior has to work also when the application is already on background mode. With CTCallCenter I am only getting the event when the application is interrupted from use, but I don't see any logs when i send the app to background and then begin/receive a call
.
If anyone could point me to the right direction I'll be really grateful.
I havent done this, but NSLocalNotifcation, schedule a notification to play when you app get the call to move into the background. I would expect this to work. Interested to find out if it does.

iOS 5 Audio Alarms Don't Sound Without kAudioSessionProperty_OverrideCategoryMixWithOthers On

I have an audio app that is having some problems with the way iOS 5 has changed audio behaviors. When my app's audio is playing (AVAudioSessionCategoryPlayback), and a Clock.app alarm or timer is fired from the OS, the UIAlertView notification pops up, but without the audio alert. My application sound ducks fine to get out of the way of the audio alert, but the alarm app's audio alert does not sound.
Naturally, tons of support requests poured in over the iOS 5 change. I have solved this temporarily by setting kAudioSessionProperty_OverrideCategoryMixWithOthers which lets the alarm audio come through, but there are a few very undesirable side-effects when doing this:
Other app's audio can play with/over mine.
The remote control events are not routed to my app, but to iPod.app.
None of the above drawbacks are acceptable for my app's requirements. I have been hacking away at this for some time now but haven't been able to crack it. How can I setup my audio such that:
My app's audio still uses the AVAudioSessionCategoryPlayback category for background audio.
The Clock.app alarms still have their audio alerts make sound
The app still responds to remote control notifications
After writing this question I went to file a bug report on this. I created a small sample project that I thought would replicate the issue, but I could not replicate it! This caused me to dig in deep once again and try to figure out what was up here…
I fired up an iOS alarm, then I placed a break point in audioPlayerBeginInterruption: and traced through my code line by line in the debugger. I noticed that before my code ran (while I was paused in the debugger), the iOS 5 alarm was sounding! Luckily it still sounded even as I was stepping through my app, so I was able to figure out which pieces of code specifically caused it to stop sounding.
Part of my interruptionHandler is to (obviously) stop the internal audio of my app to let the interruption come through. I never thought to inspect this method before, but turns out the problem existed in there. My stop method would call prepareToPlay immediately after stopping to make resuming faster the next time.
[self.player stop];
[self.player prepareToPlay]; // <- iOS 5 alarm sound stopped here.
The docs state the prepareToPlay method
preloads buffers and acquires the audio hardware needed for playback, which minimizes the lag between calling the play method and the start of sound output.
Sounds reasonable, and this worked for lesser iOS versions. My hypothesis is that  must have made a change to the Clock.app alarm system such that the new alarm sounds use the hardware, whereas before it used the software. This is what I think is causing the iOS 5 alarms to be silent in some apps.
Removing the prepareToPlay lines caused the alarm to sound without using kAudioSessionProperty_OverrideCategoryMixWithOthers, thus solving all my issues laid out in this question.
TL;DR
Remove the prepareToPlay calls from your stop sound code logic. It will take a microsecond longer to start later, but will allow interruptions to sound.

background music stops after 3/4 runs in iphone app

I am playing sounds in loop in my app. So it should continue playing through out the app. but sometimes it stops after playing sound for 3/4 times.I don't understand whats happening.
I am using audio-toolbox framework for playing sound. creating audio queue and then playing sounds in loop. I am also playing sound from ipod library using mediaplayer. Same thing happening with song from ipod.
I have set [musicPlayer setRepeatMode: MPMusicRepeatModeOne]; but still it stops after 3/4 times.
How exactly are you playing the sound? Show us the code. Do you use System Sound Services? They are not meant to play longer sounds, quote Audio Toolbox Reference:
You can use System Sound Services to
play short (30 seconds or less)
sounds.
This could be the source of your problem. But until you show us the code we can’t but guess.