saving slider position from AVAudioPlayer to NSUserDefault for loading later

Discussion in 'iOS Programming' started by gbenna, Apr 16, 2012.

  1. gbenna macrumors member

    Joined:
    Jul 27, 2011
    #1
    I am making a little app that uses AVAudioPlayer to play an m4a or car audiobook. I am trying to save the current time the player is at when the viewer leaves the view so when they return they can pick up where they left off. I have created a slider that tracks the progress of the audio from beginning to end and can be moved back and forth by the viewer. I have made it so that when the viewer leaves the view the position of the slider is saved in the NSUserDefaults. I have checked and this is saved as a plist in the users preferences. I have been able to call up the plist file but I am not sure where to load it. I have updated my code since my first post. I someone could help me figure out where to load the save float value I would really appreciate it.

    Here is my code.


    Code:
    - (void)viewDidLoad
    
    {
        AVAudioSession *session = [AVAudioSession sharedInstance];
        [session setCategory:AVAudioSessionCategoryPlayback error:nil];
        [session setActive:YES error:nil];
    
        [super viewDidLoad];
        self.title = myTitle;  
        
    NSString *pictureString = [[NSBundle mainBundle] bundlePath];
        NSString *imageString =[pictureString stringByAppendingPathComponent:picture];
        [self.button setBackgroundImage:[UIImage imageWithContentsOfFile:imageString] forState:UIControlStateNormal];
        
         NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:self.myAudio ofType:nil]];
          theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
       theAudio.delegate =self;
        theAudio.volume = 1.0; 
        theAudio.numberOfLoops = 0;
        
        
        // Set the valueChanged target
        
        [aSlider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];    
        
        
    
    	// Do any additional setup after loading the view, typically from a nib.
    }
    
    - (IBAction)slide {
        theAudio.currentTime = aSlider.value;
    }
    
    -(void)updateTime:(NSTimer *)timer {
        aSlider.value = theAudio.currentTime;
    }
    
    -(IBAction)buttonPressed:(id)sender  {
    
    //This is where I get the value that was saved.
        [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];  
        NSString *time = [NSString stringWithFormat:@"%f",[[ NSUserDefaults standardUserDefaults]floatForKey:@"playbackKey"]];
        float place =[time floatValue];
        NSLog(@"%f",place);
    
    //I tried to load it into here but no go.
        aSlider.maximumValue = [theAudio duration];
        
       if ([theAudio isPlaying]){
            [theAudio pause]; 
            
                   [button setTitle:@"Play" forState:UIControlStateNormal];}
        
        else
        {[theAudio play];
    //I also tried here by putting [theAudio playAtTime:place]  but didn't work
            [button setTitle:@"Pause" forState:UIControlStateNormal];}
        
        
        
        
    }
    
    - (void)updateSlider {
        aSlider.value = theAudio.currentTime;
    }
    
    - (IBAction)sliderChanged:(UISlider *)sender {
         [theAudio stop];
         [theAudio setCurrentTime:aSlider.value];
       [theAudio prepareToPlay];
        [theAudio play];
    }
    
    - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
    { if (flag) {
      [sliderTimer invalidate];
    }
    
    }
    
    -(void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear: animated];	
        [theAudio stop];	
        NSString *time = [NSString stringWithFormat:@"%f",aSlider.value];   
        [[ NSUserDefaults standardUserDefaults]setObject:time forKey:@"playbackKey"];
        
    }


    I have tried loading the saved file in various places but with no luck.
     
  2. cMacSW macrumors regular

    Joined:
    Mar 20, 2006
    #2
    So when you set the slider value like this:

    aSlider.value = place;

    Does Nothing?
     
  3. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #3
    When you save stuff to NSUserDefaults you don't need to load them via the saved file. You can just access them again using the methods of the NSUserDefaults class. Be sure to review the Preferences and Settings Programming Guide.
     
  4. gbenna thread starter macrumors member

    Joined:
    Jul 27, 2011
    #4
    saving slider position from AVAudioPlayer to NSUserDefault for loading later

    So I finally got this working. I change to save the audio players current time to the NSUserDefaults both as pause and exit the view. Then I load it in view did load to aSlider.value = place; and theAudio.currentTime = place; and then have theAudio playAtTime:currentPlaybackTime. I also had the file saved to the NSUserDefaults named from the plist loaded from a tableview which pushes this view on the screen. That way the viewer can listen to various books at the same time and still never loose their place. I'm only having a small problem.

    When I pause the audio and it saved to the NSUserDefault and then I start it up again, it seems to have jumped ahead a slight bit. Is it possible to have theAudio playAtTime:currentPlaybackTime minus or back a few seconds to make up for this? Or should I save it minus a few seconds. I have put

    Code:
    [theAudio playAtTime:currentPlaybackTime-10];
    but that didn't help.

    Any suggestions?
     
  5. mountebank macrumors newbie

    Joined:
    Apr 19, 2012
    #5
    You're saving the slider's value, but if you compare the slider's value to the player's current time at the point where you're saving the value to the defaults, are they the same?

    Perhaps the slider 'quantizes' it's value to the nearest pixel - so depending on how wide the slider is, you might not get the same value. Also, the slider holds its value until the timer fires, so it will only be accurate at the precise moment that you update it.
     

Share This Page