My audio won't play unless its finished playing even if I stop it then play it.So if you play the sound and play it again before the sound clip reaches the end, won't play again. How can I make it play and start from the beginning even if its still playing.
-(void)playSound{
[avplayer stop];
[avPlayer play];
}
As per the documents -
The stop method does not reset the value of the currentTime property to 0. In other words, if you call stop during playback and then call play, playback resumes at the point where it left off.
Set the currentTime property to 0.0 before playing again.
-(void)playSound{
[avplayer stop];
avplayer.currentTime = 0.0;
[avPlayer play];
}
Related
Sorry for the weird title but AVAudioPlayer acts a bit weird when it comes to playing a sound again, right before the sound that it's playing ends.
I can play an mp3 file when the player is not playing, when the player finished playing and when the player is playing.
I cannot play an mp3 when the song that is currently playing is about to end. This is my code, I documented the important bits.
-(void) play:(int)p{
if([players[p] isPlaying]){
NSLog(#"is playing");
[players[p] setCurrentTime:0.025f]; //when it's playing, set it to the start of the
//file so it starts playing again. Usually works
if(![players[p] isPlaying]){
NSLog(#"is not playing"); //although I just told the player to play again
//it sometimes returns that it in fact does NOT play
//so it's playing in the first if condition but
//not playing in the second if condition
[players[p] prepareToPlay];
[players[p] play]; //from here I try to resurrect the player numerous times
//but everything fails, I have to call the function again to make it work
[players[p] setCurrentTime:0.025f];
if([players[p] isPlaying]){
NSLog(#"playing"); //never gets called; although I tell it to play so many times
//it just won't do
}else {
NSLog(#"NOTplaying");
[players[p] play];
}
} else {
NSLog(#"is still playing");
}
} else {
NSLog(#"not playing at all");
[players[p] play]; } //if not playing, play. Always works
}
I think this might have something to do with how the AVAudioPlayer releases the file or that it's playing but is not playing anyumore in the millisecond after that. (playing during the first if condition but stopped right after that).
The window in which this occurs can easily be reproduced with with a 5sec audio file. Just wait till it's about to end and then click "play" and the method gets executed but nothing's playing. The method works in every other case (not playing and playing but not going to finish playing).
I'm using the AVPlayer method:
- (void)seekToTime:(CMTime)time
toleranceBefore:(CMTime)toleranceBefore
toleranceAfter:(CMTime)toleranceAfter
completionHandler:(void (^)(BOOL finished))completionHandler
for scrubbing a video. toleranceBefore and toleranceAfter are both 0.
However, when the user scrubs to within about 5 seconds of the end, on certain videos, finished is always equal to NO.
The player will then be in an inconsistent state where pause and play methods do nothing. The video is frozen at the time passed to seekToTime.
This happens consistently on some videos, and not at all on others.
I have a simple if/else but I don't know what to put in the else to get the player to play again:
[_avPlayer seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC)
toleranceBefore:toleranceBefore
toleranceAfter:toleranceAfter
completionHandler:^(BOOL finished) {
if(finished){
}
else {
// How to get the player to play again??
}
}];
Like I said above, I've tried putting _avPlayer play in there but it doesn't play.
I load a video into my Sprite Kit SKVideoNode, but how do I stop and restart the playback or go to a specific time in the video? All I see are play and pause methods.
// AVPlayer
NSURL *fileURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"HowToPlay" ofType:#"mp4"]];
_avPlayer = [AVPlayer playerWithURL:fileURL];
// SKVideoNode
_videoNode = [SKVideoNode videoNodeWithAVPlayer:_avPlayer];
[_videoNode play];
This turned out to work for me.
Restart:
[_videoNode removeFromParent];
_videoNode = [SKVideoNode videoNodeWithVideoFileNamed:#"video.mp4"];
_videoNode.position = ...
_videoNode.size = ...
[self addChild:_videoNode];
[_videoNode play];
Pause:
[_videoNode pause];
_videoNode.paused = YES;
Play:
[_videoNode play];
_videoNode.paused = NO;
All you can do with a SKVideoNode is documented here. play and pause are the only supported playback methods.
There is no stop because its equivalent to pause in this context - what should "stop" do, render a black texture? If the SKVideoNode should be removed on "stop" then just send it the removeFromParent message, that'll "stop" it.
Rewind is unnecessary because you can simply run the play method again or create a new SKVideoNode.
I assume jumping to a specific timeframe isn't supported because this can't be instant, so again there's the problem of what the node should display in the time until the video playback position was moved to the specified timestamp?
If you keep a reference to the AVPlayer object used to initialize the video node then you can control playback with its methods
I have a simple app that records video at 120fps, saves it to the documents directory, and then uses an instance of AVPlayer to play it back.
If I set the playback rate to 1.0 (for the AVPlayer instance), the playback is a bit choppy (probably more along the lines of 60fps). However, if I interrupt the playback by pressing the "play" button (which then sets the playback rate to 1.0 again!), it plays back very smoothly.
For instance, this is what occurs when the user presses the play button (and yes, I observe the 'status' property of AVPlayer before allowing the user to play the video):
- (IBAction)playButtonPressed:(id)sender
{
[self.videoPlayer seekToTime:kCMTimeZero];
[self.videoPlayer setRate:1];
self.videoPlayer.volume = 1;
}
And this is my simple player-setup code:
- (void)setUpAVPlayer
{
self.videoURL = [[NSURL alloc] initFileURLWithPath:self.videoURL.path];
self.videoPlayer = [AVPlayer playerWithURL:self.videoURL];
[self.previewLayer setPlayer:self.videoPlayer];
// observe player status
[self.videoPlayer addObserver:self
forKeyPath:#"status"
options:0
context:nil];
}
There really is nothing unusual about what I'm doing. It plays back video fine. It's only the case where the video was recorded at 120fps that there is a playback issue.
(Also, this is running on my iPhone5s since it is the only device that supports 120fps.)
I'm using AVAudioPlayer to play a mp3 file. instead of playing whole mp3, I want to specify play time range, like from 2 seconds to 5 seconds. how to specify the play time range?
You can either add an observer to playback and stop it when currentTime will become the time you want or you can cut your mp3 file to specified time and play it. There are various ways for doing this thing.
You might be able to do it using AVPlayer, AVPlayerItem and AVAsset. The AVPlayerItem is able to seek in an audio file.
I haven't tested it, but it might look something like this.
AVAsset *asset = [AVAsset assetWithURL:URL_TO_YOUR_MP3];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
/* start playback at 2 seconds */
[playerItem seekToTime:CMTimeMake(2.0, 1.0) completionHandler:^(BOOL finished) {
/* Instantiate player */
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
/* Start playback */
[player play];
/* Pause player in 3 seconds */
[player performSelector:#selector(pause) withObject:nil afterDelay:3.0];
}];