In my application, I'm using both iPod Player for playing background music(Music App) and AvAudioPlayer for playing the songs from URL's. I want to put fading effect for the songs while switching between these players. I tried the way by decreasing the volume of one player and increasing the other, but it did not give me the fading effect. Can anyone help me how to achieve this?
Thanks in advance
This is my code
- (IBAction)play:(id)sender
{
timerCount = 0;
playAndPauseTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(playTimer) userInfo:nil repeats:YES];
}
-(void)playTimer
{
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
if(timerCount < 10) {
timerCount++;
float volume = musicPlayer.volume;
if(volume>0) {
volume = musicPlayer.volume-0.02f;
[musicPlayer setVolume:volume];
}
} else {
[playAndPauseTimer invalidate];
[musicPlayer setVolume:initialVolume];
[audioplayer play];
pauseButton.hidden = NO;
startButton.hidden = YES;
}
}
- (IBAction)pause:(id)sender
{
//[self pauseTimer];
timerCount=0;
playAndPauseTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(pauseTimer) userInfo:nil repeats:YES];
}
-(void)pauseTimer
{
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController iPodMusicPlayer];
if(timerCount < 10) {
timerCount++;
float volume = musicPlayer.volume;
if(volume > 0){
volume = musicPlayer.volume-0.02f;
[musicPlayer setVolume:volume];
}
} else {
[playAndPauseTimer invalidate];
[audioplayer pause];
[musicPlayer setVolume:initialVolume];
pauseButton.hidden = YES;
startButton.hidden = NO;
}
}
Related
I was Created AVAudio Player, its playing perfectly,Click the play button song is playing and its shows pause button,click pause button song is paused and its shows play button,but click the play button is playing from starting onwards.i want play resume song. how to control this issue. this is my code , please check once's.
-(void)playAudio
{
// [progreetimer invalidate];
// if([audioPlayer isPlaying]==YES)`enter code here`
if(self.isPlaying)
{
[self.play setBackgroundImage:[UIImage imageNamed:#"audioplayer_play.png"]
forState:UIControlStateNormal];
NSLog(#"Pausing Music");
if (self.progreetimer) {
[self.progreetimer invalidate];
progreetimer =nil;
}
[audioPlayer pause];
self.isPlaying = NO;
}
else {
// Init audio with playback capability
[self.play setBackgroundImage:[UIImage imageNamed:#"audioplayer_pause.png"] forState:UIControlStateNormal];
// NSString *urlstr = #"http://jesusredeems.in/media/Media Advt/mp3_player/Songs/viduthalaiyin geethangal_vol1/93.Ellame Koodum.mp3";
NSString *urlstr =#"http://www.abstractpath.com/files/audiosamples/sample.mp3";
urlstr = [urlstr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlstr];
NSData *data = [NSData dataWithContentsOfURL:url];
audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil];
audioPlayer.volume = 1.9f;
// [audioPlayer prepareToPlay];
SongProgressBar.maximumValue = [audioPlayer duration];
SongProgressBar.value = 0.0;
NSLog(#"Playing music");
//start a timer to update the time label display
self.progreetimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self
selector:#selector(updateTime:) userInfo:nil repeats:YES];
self.progreetimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self
selector:#selector(updateSlider) userInfo:nil repeats:YES];
[progreetimer fire];
audioPlayer.delegate=self;
[audioPlayer play];
self.isPlaying = YES;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.SongProgressBar.minimumValue = 30;
self.SongProgressBar.maximumValue = 30;
[self.SongProgressBar setThumbImage:[UIImage imageNamed:#"thumbslider.png"]
forState:UIControlStateNormal];
// [self.SongProgressBar setThumbImage:[UIImage imageNamed:#"slider_icon.png"]
// forState:UIControlStateHighlighted];
[self.SongProgressBar setMinimumTrackImage:[UIImage imageNamed:#"slider_max.png"]
forState:UIControlStateNormal];
[self.SongProgressBar setMaximumTrackImage:[UIImage imageNamed:#"slider_icon.png"]
forState:UIControlStateNormal];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[audioPlayer pause]; // Or pause
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[audioPlayer play];
}
- (IBAction)songprogressbar:(id)sender {
// Fast skip the music when user scroll the UISlider
[audioPlayer stop];
[audioPlayer setCurrentTime:SongProgressBar.value];
[audioPlayer prepareToPlay];
[audioPlayer play];
}
- (IBAction)backword:(id)sender {
if ([self.audioPlayer isPlaying]) {
NSTimeInterval desiredTime = audioPlayer.currentTime -15.0f;
if (desiredTime < 0) {
audioPlayer.currentTime =0.0f;
} else {
audioPlayer.currentTime = desiredTime;
}
}
}
- (IBAction)play:(id)sender {
[self playAudio];
}
- (void)updateSlider {
// Update the slider about the music time
SongProgressBar.value = audioPlayer.currentTime;
}
- (void)setCurrentAudioTime:(float)value {
[self.audioPlayer setCurrentTime:value];
}
//Stops the timer when the music is finished
- (void)audioPlayerDidFinishPlaying : (AVAudioPlayer *)player successfully : (BOOL)flag {
// Music completed
if (flag) {
[progreetimer invalidate];
NSLog(#"Finished playing the song");
}
}
- (IBAction)forword:(id)sender {
if ([audioPlayer isPlaying]) {
NSTimeInterval desiredTime = audioPlayer.currentTime +15.0f;
if (desiredTime < audioPlayer.duration) {
audioPlayer.currentTime = desiredTime;
}
}
}
- (IBAction)volume:(id)sender {
audioPlayer.volume=volume.value;
}
-(NSString*)timeFormat:(float)value{
float minutes = floor(lroundf(value)/60);
float seconds = lroundf((value) - (minutes * 60));
int roundedSeconds = lroundf(seconds);
int roundedMinutes = lroundf(minutes);
NSString *time = [[NSString alloc]
initWithFormat:#"%d:%02d",
roundedMinutes, roundedSeconds];
return time;
}
- (void)updateTime:(NSTimer *)timer {
self.starttimer.text = [NSString stringWithFormat:#"%#",
[self timeFormat: ceilf(audioPlayer.currentTime)]];
self.endtimer.text = [NSString stringWithFormat:#"-%#", [self timeFormat: (audioPlayer.duration - ceilf(audioPlayer.currentTime))]];
}
You should try this. see else part of method
-(void)playAudio
{
// [progreetimer invalidate];
// if([audioPlayer isPlaying]==YES)`enter code here`
if(self.isPlaying)
{
//Code to pause audioPlayer
[audioPlayer pause];
self.isPlaying = NO;
}
else
{
if(audioPlayer.url != nil && audioPlayer.duration != 0)
{
[audioPlayer play];
}
else
{
//Code to add new audioPlayer
}
}
}
Use the following code
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL error: nil];
[player prepareToPlay];
player.currentTime = 0;
[player play];
I am using AVPlayer to play music via Streaming URLs. Upon playing the first song the CPU is at about 3-4%, but each time a new song gets played the CPU will jump up and seem to get stacked on itself. Why is this happening? This is the code I am using to play music.
- (void)updateTime {
UIImage *pauseButtonImage = [UIImage imageNamed:#"Pause"];
float duration = CMTimeGetSeconds(self.player.currentItem.duration);
float current = CMTimeGetSeconds(self.player.currentTime);
self.durationProgressView.progress = (current/duration);
if (self.durationProgressView.progress == 0)
{
[self.playPauseButton setBackgroundImage:pauseButtonImage forState:UIControlStateNormal];
}
}
-(void)playCurrentArtist:(NSDictionary *)currentArtist
{
NSString *streamString = [currentArtist objectForKey:#"stream_url"];
NSString *urlString = [NSString stringWithFormat:#"%#?client_id=%#", streamString,CLIENT_ID];
NSURL *URLFromString = [NSURL URLWithString:urlString];
self.player = nil;
AVPlayer *playerWithURL = [[AVPlayer alloc]initWithURL:URLFromString];
self.player = playerWithURL;
[self.player play];
self.durationProgressView.hidden = NO;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:[self.player currentItem]];
self.timer = [NSTimer scheduledTimerWithTimeInterval:.05 target:self selector:#selector(updateTime) userInfo:nil repeats:YES];
}
-(void)itemDidFinishPlaying:(NSNotification *) notification {
//if there are no tracks in queue
if (![self.hostQueue count]) {
NSLog(#"nothing in queue upon song finishing");
[[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:[self.player currentItem]];
[self.hostCurrentArtist removeAllObjects];
[self setCurrentArtistFromCurrentArtist:self.hostCurrentArtist];
NSArray *argsCurrentArray = #[self.hostCurrentArtist];
[self.socket emit:kCurrentArtistChange args:argsCurrentArray];
}
else {
[self playNextSongInQueue];
[self setCurrentArtistFromCurrentArtist:self.hostCurrentArtist];
};
}
-(void)playNextSongInQueue
{
if ([self.hostQueue count]) {
[self.audioPlayer stop];
[self.timer invalidate];
[[NSNotificationCenter defaultCenter]removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:[self.player currentItem]];
UIImage *pausedButtonImage = [UIImage imageNamed:#"Pause"];
//Rearange tracks and current songs and emit them to the sever.
NSDictionary *currentTrack = [self.hostQueue objectAtIndex:0];
self.hostCurrentArtist = [currentTrack mutableCopy];
[self.hostQueue removeObjectAtIndex:0];
[self.tableView reloadData];
[self playCurrentArtist:self.hostCurrentArtist];
[self.playPauseButton setBackgroundImage:pausedButtonImage forState:UIControlStateNormal];
self.audioPlayer.delegate = self;
self.durationProgressView.hidden = NO;
self.timer = [NSTimer scheduledTimerWithTimeInterval:.5 target:self selector:#selector(updateTime) userInfo:nil repeats:YES];
NSArray *argsWithQueue = #[self.hostQueue];
NSArray *arrayWithTrack = #[currentTrack];
[self setCurrentArtistFromCurrentArtist:self.hostCurrentArtist];
}
}
I am using the AVAudioPlayer class to play audio. I have implemented a timer slider that progresses as the music is playing.
Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
AudioBool = YES;
}
- (IBAction)play:(id)sender
{
// Code to read the file from resource folder and sets it in the AVAudioPlayer
// Sets the audio timer in 1 sec intervals
sliderTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime) userInfo:nil repeats:YES];
// Sets the slider maximum value
slider.maximumValue = player.duration;
// Sets the valueChanged target
[slider addTarget:self action:#selector(sliderChanged : ) forControlEvents : UIControlEventValueChanged];
// Play the audio
// [player prepareToPlay];
[player play];
if(AudioBool == YES)
{
[player play];
AudioBool = NO;
}
else
{
[player pause];
AudioBool = YES;
}
}
- (void)updateTime
{
// Updates the slider about the music time
slider.value = player.currentTime;
NSString *time = [self timeFormatted:slider.value];
self.timerLabe.text = time;
}
- (NSString *)timeFormatted:(int)totalSeconds
{
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
//int hours = totalSeconds / 3600;
//return [NSString stringWithFormat:#"%02d:%02d:%02d",hours, minutes, seconds];
return [NSString stringWithFormat:#"%02d:%02d", minutes, seconds];
}
- (IBAction)sliderChanged : (UISlider *)sender
{
// skips music with slider changged
[player pause];
[player setCurrentTime:slider.value];
// [player prepareToPlay];
[player play];
}
// Stops the timer when audio finishes
- (void)audioPlayerDidFinishPlaying : (AVAudioPlayer *)player successfully :
(BOOL)flag
{
// Music completed
if (flag)
{
[sliderTimer invalidate];
}
}
2 issues I have:
I can't seem to pause the audio. When I re-tap the play button, it re-starts the audio at the beginning instead of pausing it.
The slider also re-starts at the beginning instead of pausing.
How do I fix these issues?
Thanks
try this solution, you need to make changes in play method basically..shift the slider initialisation in viewDidLoad also play/pause based on isPlaying property (AudioBool property in your code)
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
#property (nonatomic, strong) AVAudioPlayer *audioPlayer;
#property (nonatomic) BOOL isPlaying;
#property (nonatomic, strong) NSTimer *sliderTimer;
#property (weak, nonatomic) IBOutlet UISlider *slider;
#property (weak, nonatomic) IBOutlet UILabel *timerLabel;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:#"10101" ofType:#"mp3"];
NSURL *fileURL = [NSURL fileURLWithPath:filePath];
self.isPlaying = NO;
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
[self.audioPlayer prepareToPlay];
[self.slider addTarget:self action:#selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
self.slider.minimumValue = 0;
self.slider.maximumValue = self.audioPlayer.duration;
}
- (IBAction)play:(id)sender {
if (self.isPlaying)
{
// Music is currently playing
[self.audioPlayer pause];
self.isPlaying = !self.isPlaying;
}
else
{
// Music is currenty paused/stopped
[self.audioPlayer play];
self.isPlaying = !self.isPlaying;
self.sliderTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime) userInfo:nil repeats:YES];
}
}
- (void)sliderChanged:(UISlider *)sender
{
// skips music with slider changged
[self.audioPlayer pause];
[self.audioPlayer setCurrentTime:self.slider.value];
[self.audioPlayer play];
}
- (void)updateTime
{
// Updates the slider about the music time
self.slider.value = self.audioPlayer.currentTime;
NSString *time = [self timeFormatted:self.slider.value];
self.timerLabel.text = time;
}
- (NSString *)timeFormatted:(int)totalSeconds
{
int seconds = totalSeconds % 60;
int minutes = (totalSeconds / 60) % 60;
return [NSString stringWithFormat:#"%02d:%02d", minutes, seconds];
}
// Stops the timer when audio finishes
- (void)audioPlayerDidFinishPlaying : (AVAudioPlayer *)player successfully:(BOOL)flag
{
// Music completed
if (flag)
{
[self.sliderTimer invalidate];
}
}
I'm making a game and would like to use a timer to countdown an event, just like what's seen on Bejeweled. I know that I've to put NSTimer in a NSRunLoop to make it work, since NSTimer is inaccurate. Have tried the following but it still don't work. Please help!
#import ...
NSTimer *_gameTimer;
int secondsLeft;
//some code
//called countdownTimer using [self countdownTimer];
- (void)countdownTimer
{
_gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime:) userInfo:nil repeats:YES];
NSRunLoop *gameRun = [NSRunLoop currentRunLoop];
[gameRun addTimer:_gameTimer forMode:NSDefaultRunLoopMode];
}
- (void)updateTime:(NSTimer *)timer
{
if (secondsLeft>0 && !_gameOver) {
_timerLabel.text = [NSString stringWithFormat:#"Time left: %ds", secondsLeft];
secondsLeft--;
} else if (secondsLeft==0 && !_gameOver) {
// Invalidate timer
[timer invalidate];
[self timerExpire];
}
}
- (void)timerExpire
{
// Gameover
[self gameOver];
[_gameTimer invalidate];
_gameTimer = nil;
}
NSTimer needs to be a local variable so there can only be one instance of the object running through the loop. Here's the code.
- (void)countdownTimer
{
NSTimer *_gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime:) userInfo:nil repeats:YES];
NSRunLoop *gameRun = [NSRunLoop currentRunLoop];
[gameRun addTimer:_gameTimer forMode:NSDefaultRunLoopMode];
if (secondsLeft==0 || _gameOver) {
[_gameTimer invalidate];
_gameTimer = nil;
}
}
- (void)updateTime:(NSTimer *)timer
{
if (secondsLeft>0 && !_gameOver) {
_timerLabel.text = [NSString stringWithFormat:#"Time left: %ds", secondsLeft];
secondsLeft--;
} else if (secondsLeft==0 || _gameOver) {
// Invalidate timer
[timer invalidate];
[self timerExpire];
}
- (void)timerExpire
{
// Gameover
[self gameOver];
}
I want to use an NSTimer (or if you have a better suggestion) to play a sound when the device is unplugged, or unknown. However if the user plugs the device back in, the sound should immediately stop.
Here's my code but it doesn't seem to behave as I am describing it,
- (void)currentBatteryState
{
UIDevice *device = [UIDevice currentDevice];
switch(device.batteryState) {
case UIDeviceBatteryStateUnknown:
currentBatteryStatusLabel.text = #"Unknown";
if ([batteryControlTimer isValid]) {
[batteryControlTimer invalidate];
batteryControlTimer = [NSTimer scheduledTimerWithTimeInterval:2.5 target:self selector:#selector(playSound) userInfo:nil repeats:YES];
} else {
batteryControlTimer = [NSTimer scheduledTimerWithTimeInterval:2.5 target:self selector:#selector(playSound) userInfo:nil repeats:YES];
}
break;
case UIDeviceBatteryStateUnplugged:
currentBatteryStatusLabel.text = #"Unplugged";
if ([batteryControlTimer isValid]) {
[batteryControlTimer invalidate];
batteryControlTimer = [NSTimer scheduledTimerWithTimeInterval:2.5 target:self selector:#selector(playSound) userInfo:nil repeats:YES];
} else {
batteryControlTimer = [NSTimer scheduledTimerWithTimeInterval:2.5 target:self selector:#selector(playSound) userInfo:nil repeats:YES];
}
break;
case UIDeviceBatteryStateCharging:
currentBatteryStatusLabel.text = #"Charging";
[batteryControlTimer invalidate];
break;
case UIDeviceBatteryStateFull:
currentBatteryStatusLabel.text = #"Full";
[batteryControlTimer invalidate];
break;
}
}
- (void) playSound
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"siren_1", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
Thank you
If the condition isn't met, don't play any sound, but don't invalidate the timer. That way it will keep firing at the interval even if the condition isn't met once.
So:
- (void)playSound {
if(conditionIsMet) {
//code to play your sound
}
}
Edit:
If you want to make the interval at which the sound can stop because the condition isn't met, then you just need to make the timer's time interval and the duration of the sound smaller.