AVAudioPlayer won't play existing file a second time

寵の児 提交于 2019-12-12 03:06:36

问题


I have searched a lot trying to figure this out - the code to me seems ok but the functionality doesn't reflect this.

I have a View that is presented (its an Audio Recorder view). You can press record and it records to a file just fine (data exists in the file). I can then play the file back via the play button (the AVAudioPlayer is pointing to that file).

However when I close/dismiss that view and come back to it - the file will not play when Play is tapped even though it should be exactly the same code as the file location has not changed.

UPDATE:

Seems that [audioPlayer play] returns no. I have also looked into the data. It seems that when the view appears again and loads that data it doesnt load it correctly (NSdata in Nslog displays mainly 0's) - even though the file exists and has data in it (i can see and hear it after transferring to my mac).

This leads me to suspect that either I am loading the data wrong or avaudioplayer wont read the data for some reason...

Please take a look at the code below:

(NSString *) removeCharsFrom: (NSString *) remover {

    remover = [remover stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    remover = [remover stringByReplacingOccurrencesOfString:@" " withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"\\" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@":" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@";" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"(" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@")" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"£" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"$" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"&" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"'" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"{" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"}" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"[" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"]" withString:@"_"];
    remover = [remover stringByReplacingOccurrencesOfString:@"""" withString:@"_"];

    return remover;
}


- (NSString *) audioPathForResource: (NSString *) audio {

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *saveDirectory = [paths objectAtIndex:0];
    NSString *newFolder = [saveDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"/%@/Audio",catName]];

    if (![[NSFileManager defaultManager] fileExistsAtPath:newFolder]) {
        [[NSFileManager defaultManager] createDirectoryAtPath:newFolder withIntermediateDirectories:YES attributes:nil error:nil];
    }

    NSString *saveFileName = [NSString stringWithFormat:@"%@.caf",audio];
    NSString *newFilePath = [newFolder stringByAppendingPathComponent:saveFileName];


    return [newFilePath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 

}


- (IBAction)cancelTapped:(id)sender {

    [self dismissModalViewControllerAnimated:YES];

}

- (IBAction)saveTapped:(id)sender {


    [self.parentViewController performSelector:@selector(changeAddAudioIcon)];

    [self dismissModalViewControllerAnimated:YES];

}


- (IBAction)trashTapped:(id)sender {

    UIAlertView *alert =
    [[UIAlertView alloc] initWithTitle: @"Delete"
                               message: @"Would you like to delete the audio file? Warning: This cannot be undone."
                              delegate: self
                     cancelButtonTitle: @"Cancel"
                     otherButtonTitles: @"Delete", nil];
    [alert show];
    [alert release];

}

- (IBAction)pauseTapped:(id)sender {

    pauseBtn.enabled = NO;
    playBtn.enabled = YES;
    recordBtn.enabled = YES;
    trashBtn.enabled = YES;

    if (audioRecorder.recording)
    {
        [audioRecorder stop];
    } else if (audioPlayer.playing) {
        [audioPlayer stop];
    }


}

- (IBAction)recordTapped:(id)sender {

    if (!audioRecorder.recording)
    {
        playBtn.enabled = NO;
        pauseBtn.enabled = YES;
        trashBtn.enabled = NO;
        [audioRecorder record];
    }
}

- (IBAction)playTapped:(id)sender {


        pauseBtn.enabled = YES;
        recordBtn.enabled = NO;
        trashBtn.enabled = YES;

        NSError *error;

        NSLog(@"%@",filepathstring);


        NSURL *soundFileURL = [NSURL fileURLWithPath:filepathstring];

            audioPlayer = [[AVAudioPlayer alloc] 
                           initWithContentsOfURL:soundFileURL                                   
                           error:&error];


        audioPlayer.delegate = self;

        if (error)
            NSLog(@"Error: %@", 
                  [error localizedDescription]);
        else
            [audioPlayer play];


}



- (void)alertView: (UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {


    switch (buttonIndex) {
        case 0:

            return;
            break; 
        case 1:
        {   
            NSError *error = nil;
            [[NSFileManager defaultManager] removeItemAtPath:filepathstring error:&error];
            trashBtn.enabled = NO;
        }

            break;

        default:
            break;
    }

}

-(void)audioPlayerDidFinishPlaying:
(AVAudioPlayer *)player successfully:(BOOL)flag
{
    recordBtn.enabled = YES;
    pauseBtn.enabled = NO;
    playBtn.enabled = YES;

    if(player != audioPlayer) {
        [player release];
    }

}
-(void)audioPlayerDecodeErrorDidOccur:
(AVAudioPlayer *)player 
                                error:(NSError *)error
{
    NSLog(@"Decode Error occurred");
}
-(void)audioRecorderDidFinishRecording:
(AVAudioRecorder *)recorder 
                          successfully:(BOOL)flag
{

    NSLog(@"Recording success:%@",flag ? @"YES" : @"NO");

    trashBtn.enabled = YES;
    pauseBtn.enabled = NO;
    playBtn.enabled = YES;

}
-(void)audioRecorderEncodeErrorDidOccur:
(AVAudioRecorder *)recorder 
                                  error:(NSError *)error
{
    NSLog(@"Encode Error occurred");
}




#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.





}

- (void) viewWillAppear:(BOOL)animated {



    catName = [NSString stringWithFormat:@"%@",[self removeCharsFrom:catName]];
    testName = [NSString stringWithFormat:@"%@",[self removeCharsFrom:testName]];
    filepathstring = [[self audioPathForResource:testName] retain];
    NSLog(@"At start = %@",filepathstring);

    if ([[NSFileManager defaultManager] fileExistsAtPath:filepathstring]) {
        playBtn.enabled = YES;
        trashBtn.enabled = YES;
        recordBtn.enabled = YES;
    }
    else
    {
        playBtn.enabled = NO;
        trashBtn.enabled = NO;
    }

    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];


    NSURL *soundFileURL = [NSURL fileURLWithPath:filepathstring];

    NSDictionary *recordSettings = [NSDictionary 
                                    dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithInt:AVAudioQualityMin],
                                    AVEncoderAudioQualityKey,
                                    [NSNumber numberWithInt:16], 
                                    AVEncoderBitRateKey,
                                    [NSNumber numberWithInt: 2], 
                                    AVNumberOfChannelsKey,
                                    [NSNumber numberWithFloat:44100.0], 
                                    AVSampleRateKey,
                                    nil];

    NSError *error = nil;

    audioRecorder = [[AVAudioRecorder alloc]
                     initWithURL:soundFileURL
                     settings:recordSettings
                     error:&error];

    audioRecorder.delegate = self;

    if (error)
    {
        NSLog(@"error: %@", [error localizedDescription]);

    } else {
        [audioRecorder prepareToRecord];
    }

}

- (void)viewDidUnload
{
    [self setCancelBtn:nil];
    [self setSaveBtn:nil];
    [self setTimeLabel:nil];
    [self setDescriptionLabel:nil];
    [self setToolsBar:nil];
    [self setTrashBtn:nil];
    [self setPauseBtn:nil];
    [self setRecordBtn:nil];
    [self setPlayBtn:nil];
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
        return YES;
    } else {
        return UIInterfaceOrientationIsPortrait(interfaceOrientation);
    }
}

- (void)dealloc {
    [cancelBtn release];
    [saveBtn release];
    [timeLabel release];
    [descriptionLabel release];
    [toolsBar release];
    [trashBtn release];
    [pauseBtn release];
    [recordBtn release];
    [playBtn release];
    [audioPlayer release];
    [audioRecorder release];
    [super dealloc];
}

回答1:


Here is the answer:

NSData *data = [NSData dataWithContentsOfMappedFile:[NSString stringWithFormat:@"%@",filepathstring]];


  AVAudioPlayer *ap = [[AVAudioPlayer alloc] 
                   initWithData:data error:&error];

Seems that it just wouldnt work with filepathstring but within an NSString it worked fine. Obvious now!



来源:https://stackoverflow.com/questions/8898767/avaudioplayer-wont-play-existing-file-a-second-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!