I'm trying to create an MPMoviePlayer as paused at appearance.
I've tried doing just a regular pause, as a selector with 0.1s delay, let NSNotificationCenter pause it as soon as the movie started (This did work, but with a slight delay. The movie played for a second before paus).
Is there a way to keep it paused from first appearance?
Thanks in advance
use pause method to do it
[moviePlayer pause];
Sorry for taking y'alls time...
A friend helped me just after I posted the question.
Apparently there is a property called shouldAutoplay that I missed in the documentation.
Just use that.
Related
I am using AVAudioPlayer in my program, but having touble in something
I have 10 sounds, and as I click one to play or then others don't stop, I tried to solve by
[myPlayer stop];
myPlayer = nil;
it works, but takes time, so what should I do to stop when it click 2nd row on tableview for playing another sound?
If any query regarding question, you may ask in comments,
I think You hae added some observer before calling, [myPlayer play];... So you have to remove those observer
I have a view controller that uses AVPlayer. this view controller can load a modal view controler where the user can record audio using AVAudioRecorder.
this is what happens:
if the user plays the composition in the fist controller with [AVPLayer play] the AVAudioRecorder will not record in the modal view controller. there are no errors but the current time returned by AVAudioRecorder is 0.0;
if the user dismisses the modal dialog and reloads it. AVAudioRecorder works fine.
this can be repeated over and over
AVAudioRecorder does not work the first time it is invoked after a [AVPlayer play] call
I have been fighting with this for days and just have reorganized my code related to both AVPlayer and AVAudioRecorder and it's still acting weird.
Any help or pointer is much appreciated
Thanks in advance
Jean-Pierre
I've been having the same problem too, and this is the solution I found.
When recording, write this line code after AVAudioRecord is initialized:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord error:NULL];
Then invoke record method.
How are you setting the AVAudioSession's category, i.e., play or record? Try something like
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
I've been having the same problem. I use AVPlayer to play compositions (previous recordings I've used AVAudioRecord for). However, I found that once I've used AVPlayer I could no longer use AVAudioRecorder. After some searching, I discovered that so long as AVPlayer is instantiated in memory and has been played at least once (which is usually what you do immediately after instantiating it) AVAudioRecorder will not record. However, once AVPlayer is dealloc'd, AVAudioRecorder is then free to record again. It appears that AVPlayer holds on to some kind of connection that AVAudioRecorder needs, and it's greedy...it won't let it go until you pry it from it's cold dead hands.
This is the solution I've found. Some people claim that instantiating AVPlayer takes too much time to keep breaking down and setting back up. However, this is not true. Instantiating AVPlayer is actually quite trivial. So also is instantiating AVPlayerItem. What isn't trivial is loading up AVAsset (or any of it's subclasses). You really only want to do that once. They key is to use this sequence:
Load up AVAsset (for example, if you're loading from a file, use AVURLAsset directly or add it to a AVMutableComposition and use that) and keep a reference to it. Don't let it go until you're done with it. Loading it is what takes all the time.
Once you're ready to play: instantiate AVPlayerItem with your asset, then AVPlayer with the AVPlayerItem and play it. Don't keep a reference to AVPlayerItem, AVPlayer will keep a reference to it and you can't reuse it with another player anyway.
Once it's done playing, immediately destroy AVPlayer...release it, set its var to nil, whatever you need to do. **
Now you can record. AVPlayer doesn't exist, so AVAudioRecorder is free to do its thing.
When you're ready to play again, re-instantiate AVPlayerItem with the asset you've already loaded & AVPlayer. Again, this is trivial. The asset has already been loaded so there shouldn't be a delay.
** Note that destroying AVPlayer may take more than just releasing it and setting its var to nil. Most likely, you've also added a periodic time observer to keep track of the play progress. When you do this, you receive back an opaque object you're supposed to hold on to. If you don't remove this item from the player AND release it/set it to nil, AVPlayer will not dealloc. It appears that Apple creates an intentional retain cycle you must break manually. So before you destroy AVPlayer you need to (example):
[_player removeTimeObserver:_playerObserver];
[_playerObserver release]; //Only if you're not using ARC
_playerObserver = nil;
As a side note, you may also have set up NSNotifications (I use one to determine when the player has completed playing)...don't forget to remove those as well.
If you need use AVPlayer and AVAudioRecorder at the same time do following:
set audio category to "play and record" (as described above or with C-based Audio Session Function)
"record" method must be invoked after invocation of "play" method with some delay. (I set 0.5 sec)
If you don't provide this, playback will start, but recording will not start.
shouldn't it be [AVAudioRecorder record]; instead of play?
I've had the same issue: AVAudioRecorder did not start recording.
My example is a bit different: I have a tabbar based app with several AVAudioPlayers in the different views. For the sake of the example, lets say that the first loaded view has 3 AVAudioPlayers, while the second view has one AVAudioPlayer and one AVAudioRecorder. They are all initiated in the viewDidLoad method.
The recorder was not working in second view. When I hit my record button, the view slightly shaked and the recording did not begin.
Strangely, the simulator worked fine and did not show the same symptoms... (anyone has an idea why?)
After some research and reading this thread I have realized that I have not set the players in the first view to nil, so I guess they were still in the memory preventing the recorder to start. Once I have set them to nil in the viewDidDisappear method, it was working alright again.
here is what helped me:
-(void)viewDidDisappear:(BOOL)animated {
firstPlayer = nil;
secondPlayer = nil;
thirdPlayer = nil;
}
ViewDidUnload did not help because the View, and therefore the variablbes in the class itself were not unloaded when switching views.
Hope this may be useful for others as well.
#Aaron Hayman explanation is accurate but the solution for me was very simple. Just implement the didFinishPlaying method of the player delegate and release the player there.
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
self.playerWord = nil;
}
I have an app with a splash screen. For the splashscreen I've decided to add a m4v movie. I'm using the MPMoviePlayerController to show the movie. Everything is working as expected except for one thing:
I'm trying to make the MPMoviePlayerController loop by subscribing to it's MPMoviePlayerPlaybackDidFinishNotification notification and issuing a [notification.object play] if the data didn't finish loading.
This works partially, it restarts the movie, but there's the fadeout and re-fadein that make it look bad.
Is there any other way to loop the movie?
Or any way to remove the fades?
Try this single line of code:
myPlayer.repeatMode = MPMovieRepeatModeOne;
:)
By complete coincidence I have just written a blog post on this subject - we ran into this problem while we were writing our latest app :)
Assuming that you don't want to follow my shameless plug, here's how we fixed it :
Make sure that the movie starts
and ends on the same frame.
Make the starting frame the Default.png of the app
On startup add Default.png to the window as a UIImageView
Make the movie have a clear background
Play and loop the movie
When the movie ends, it will fade out before it loops round. As Default.png is exactly the same as the start and end frames, the user will never notice :)
When you want to end the movie just remove the Default.png UIImageView and stop the movie - as the background is clear it will just fade out to whatever ui you have in your window.
Sam
I don't think there is any public option to do this. You could try and inspect Erica Sadun's Class Dumps for a method you can override that would handle the fading. Maybe a videoDidFinish method or something.
Have you tried messing around with the backgroundColor property? Apple's MPMoviePlayerController docs say
"The receiver fades to and from the
background color when transitioning to
and from playback...The default color
for this property is black. You can
change this to other colors (including
clear) to provide a more appropriate
transition from your application’s
content to the movie content."
So, you can probably try setting it to [UIColor clearColor] and seeing if that helps.
I want to use AVAudioPlayer to play short sounds... because I have more control than System Sound.
I have several buttons which are hooked up to play several different short sounds.
Each sound file is about 1.5 - 2.0 seconds.
Everything works fine ...except ...I have to wait for the sound to stop before I can press the button and the sound will play again.
Currently the individual AVAudioPlayers are created on viewDidLoad ... and the sounds are called to play when the buttons are pressed
I tried creating the players when the button is pressed... this solves the above problem... but after a while the app crashes... all sound stops working.
Any ideas?
Thanks
Jonathan
If AVAudioPlayer stops playing sounds, it is usually because there are too many player instances created, usually leaked. You should make sure you release some after you are done.
You need to set the currentTime of the player to 0 before playing. Calling [player play] when it is already playing has no effect.
player.currentTime = 0;
[player play];
Creating new ones is fine, but make sure your header declares and does this:
- (void) audioPlayerDidFinishPlaying: (AVAudioPlayer *) player successfully: (BOOL) completed {
[player release];
}
if your app is simple, that will release the memory of anything done that's no longer necessary, as per mahboudz' suggestion.
This might not totally prevent crashing, depending on your sound file sizes, and if you dealloc the scene. You might want to add
if (self.view.superview) { //release }
or something.
This is all memory handling. You may want to brush up on pointers to know how to handle your player objects, literally within any function, and still feel comfortable placing release in dealloc OR the didFinish: delegate function, and know why it doesn't belong in the other one.
The iPhone can be interrupted, stopped, and messed with at any time, so you have to know how to handle the memory and how to deal with it when it happens. I just had a crash of a similar nature, and everything above applied to it. NSXML delegates would be a nightmare without knowing pointers... same for AVAudioPlayer
If you plan to use a lof of short sounds, you might want to think about switching to OpenAL.
It's not a lot more complicated and you will save yourselve some trouble in more complicated audio settings later on.
There's a tutorial and some useful code available here (archived here).
this is MAYBE because you have created the AVAudioPlayers inside the viewDidLoad(). I remember I had the same problem. Just initialize them inside the class but not there. hope it works!
EDIT:
ok i saw the date... 2009...
I'm using SCListener to get the iPhone's volume, but I'd like to put an observer on the volume. So when it changes I can update the volume meter on the screen. But doing something like:
SCListener *listener = [SCListener sharedListener];
[listener addObserver:self
forKeyPath:#"peakPower"
options:NSKeyValueObservingOptionOld
context:NULL];
doesn't do the trick because peakPower isn't a variable. How would I put an observer on the function? Or how would a create a listener I could stop and start to keep track of the peak power in a variable I could put an observer on?
Thanks in advance for the help!
SCListener is not Key Value Observer compliant. AFAIK, you have to poll for the values.
Simply set up a repeating timer, and read the levels each time the timer fires.