I want to play a specified duration within a sound file on IOS. I found a method in AVAudioPlayer that seeks to the begining of the playing (playAtTime:) but i cannot find a direct way to specify an end time before the end of the sound file.
Is there is a way to achieve this?
If you don't need much precision and you want to stick with AVAudioPlayer, this is one option:
- (void)playAtTime:(NSTimeInterval)time withDuration:(NSTimeInterval)duration {
NSTimeInterval shortStartDelay = 0.01;
NSTimeInterval now = player.deviceCurrentTime;
[self.audioPlayer playAtTime:now + shortStartDelay];
self.stopTimer = [NSTimer scheduledTimerWithTimeInterval:shortStartDelay + duration
target:self
selector:#selector(stopPlaying:)
userInfo:nil
repeats:NO];
}
- (void)stopPlaying:(NSTimer *)theTimer {
[self.audioPlayer pause];
}
Bear in mind that stopTimer will fire on the thread's run loop, so there will be some variability in how long the audio plays, depending on what else the app is doing at the time. If you need a higher level of precision, consider using AVPlayer instead of AVAudioPlayer. AVPlayer plays AVPlayerItem objects, which let you specify a forwardPlaybackEndTime.
Related
Using an AVPlayer I would like to play a mov file for exactly 1 second then pause it.
Currently I'm playing the mov then setting a timer to pause it after 1 second as below. Unfortunately, this does not appear to be exactly accurate and the mov is sometimes playing for slightly shorter or longer than 1 second. Is there a more accurate way of doing this please?
[self.player4 play];
[self performSelector:#selector(pausePlayer4:) withObject:nil afterDelay:1.0];
- (void)pausePlayer4:(NSTimer *)timer
{
[self.player4 pause];
}
Even if you can get an event to fire precisely enough, media playback on iOS devices happens in an entirely different process (a daemon) and there's always latency when doing IPC.
Depending on your needs it might be best to build an AVMutableComposition that plays exactly one second of content from your AVURLAsset, and then assign the composition to your player.
The best way wold be to add a boundary observer to trigger after a second
NSValue *endBoundary = [NSValue valueWithCMTime:CMTimeMakeWithSeconds(1.0, 300)];
[self.player4 addBoundaryTimeObserverForTimes:#[endBoundary]
queue:NULL
usingBlock:^{
[self.player4 stop];
}];
[self.player4 play];
I am trying to implement AVPlayer for play audio file from URL. It is working fine. But sometimes AVPlayer stops/pauses playing and do not resume again. If I click on play button then it works fine. (it should play without user interface). (I do not want use : [player addObserver:self forKeyPath:#"rate" options:0 context:nil];) I also take help from this URL : AVPlayer stops playing and doesn't resume again. But this code has some errors. For temporary I am using this code and looks fine from my side. But I am not sure whether it is fine or not in all cases.So I want to know what should I do which handles all cases. Thanks in advance......
My code :
-(void)updateTime:(NSTimer *)timer {
// temporary code for play audio again, when player pause/stop automatically
if (player.rate==0) {
[player play];
}
currentTime = CMTimeGetSeconds(playerItem.currentTime);
duration = CMTimeGetSeconds(playerItem.duration);
[self.audioSliderBar setValue:(currentTime/duration)];
float minutes = floor(currentTime/60);
seconds =currentTime - (minutes * 60);
float duration_minutes = floor(duration/60);
duration_seconds =
duration - (duration_minutes * 60);
NSString *timeInfoString = [[NSString alloc]
initWithFormat:#"%0.0f:%0.0f",
minutes, seconds ];
self.audioCurrentTimeLabel.text = timeInfoString;
}
In Xcode, I have set my buttons to play a music clip which will last 40 seconds. My question is how do I link up a UIProgressView to the music playing? For example, if the song is half way through, the progress bar will display that.
If you have the following defined in your class:
AVAudioPlayer *audioPlayer;
UIProgressView *progressView;
NSTimer *audioTimer;
Running it off a timer seems to work:
- (void)audioProgressUpdate
{
if (audioPlayer != nil && audioPlayer.duration > 0.0)
[progressView setProgress:(audioPlayer.currentTime / audioPlayer.duration)];
}
When you start the clip start the timer (this runs it every tenth of a second):
[audioPlayer play];
audioTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(audioProgressUpdate) userInfo:nil repeats:YES];
And when you stop the clip, stop the timer:
[audioTimer invalidate];
[audioPlayer stop];
I am using the AVPlayer to play a live stream from the Internet, and need to show than the player is buffering :
I am using an NStimer :
timer = [NSTimer scheduledTimerWithTimeInterval:(1.0/2.0) target:self selector:#selector(buffering) userInfo:nil repeats:YES];
-(void)buffering {
if(radiosound.rate == 1.0)
[activityIndicator stopAnimating];
else
[activityIndicator startAnimating];
}
For sure rate property is not working properly to show !
Is it an other statement to know if the AVPlayer is buffering ?
You need to look at setting up key-value observers for the loaded times, and use that to figure out if you are waiting for data at the current play point.
Observers are setup using addObserver:self forKeyPath: options: context: method on AVPlayerItem and then in the observeValueForKeyPath: ofObject: change: context: callback you can figure out what times have been loaded compared with where in the item the player is playing.
You won't see the rate variable drop to zero when buffering, as this is the desired playback rate, not the actual rate being achieved.
Use the NSURLConnection class in conjunction with the NSURLConnectionDataDelegate protocol.
I want to play any file for 6 seconds. Also suppose the audio is bigger then 6 sec the application will play only for 6 sec.and if it is less then 6 sec then play continuously. So is there any inbuilt option from any framework?
A Simple Way To Play MP3 Audio Files
Assuming you use an AVAudioPlayer, send a -stop message after 6 seconds:
NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:6
target:thePlayer selector:#selector(stop)
userInfo:nil repeats:NO];
(Remember to invalidate the timer if the player stops early.)
If you are using AVAudioPlayer you can make use of an NSTimer as mentioned by #Kenny. Just to add to add to that answer.
NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:6
target:thePlayer selector:#selector(stopPlayer)
userInfo:nil repeats:NO];
- (void)stopPlayer
{
[audioPlayer stop];
}
In case the duration of your audio file is less than 6 seconds or your desired limit you should continue to play right? so you must set the numberOfLoops for the audio player instance to continue playback. Here is the reference