保存音频文件并在视图之间导航

Posted

技术标签:

【中文标题】保存音频文件并在视图之间导航【英文标题】:Saving audio files and navigating between views 【发布时间】:2012-05-20 16:01:13 【问题描述】:

我在保存录制的音频文件并在视图之间导航后播放它们时遇到问题。

我一直在使用http://www.techotopia.com/index.php/Recording_Audio_on_an_iPhone_with_AVAudioRecorder_%28ios_4%29的教程

我已经添加了一行来保存音频文件,所以我的prepareForAudioRecording 看起来像下面的代码。该方法在viewDidLoad中调用。

-(void) prepareForAudioRecording

    btnPlay.enabled = NO;
    btnStop.enabled = NO;

    NSArray *dirPaths;
    NSString *docsDir;

    dirPaths = NSSearchPathForDirectoriesInDomains(
                                                   NSDocumentDirectory, NSUserDomainMask, YES);
    docsDir = [dirPaths objectAtIndex:0];
    NSString *soundFilePath = [docsDir
                               stringByAppendingPathComponent:@"page1.caf"];

    //this line added to save the audio file
    [audioPlayer.data writeToFile:soundFilePath atomically:YES];


    NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];

    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];

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

     else 
        [audioRecorder prepareToRecord];
    

正如我所说,我可以录制音频,然后在同一个视图控制器中播放音频,但是当我离开视图并返回它时,我无法播放录音。

首先播放和停止按钮被禁用,我认为这应该只在第一次加载视图时发生 - 但即使我启用它们并按下播放按钮,也没有音频。

下面是我的播放、停止和录制按钮的其他方法。

- (IBAction)playAudio:(id)sender 
    if (!audioRecorder.recording)
    
        btnStop.enabled = YES;
        btnRecord.enabled = NO;

        //if (audioPlayer)
            //[audioPlayer release];
        NSError *error;

        audioPlayer = [[AVAudioPlayer alloc] 
                       initWithContentsOfURL:audioRecorder.url                                    
                       error:&error];

        audioPlayer.delegate = self;

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


-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag

    btnRecord.enabled = YES;
    btnStop.enabled = NO;

-(void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error

    NSLog(@"Decode Error occurred");

-(void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag


-(void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error

    NSLog(@"Encode Error occurred");



- (IBAction)recordAudio:(id)sender 
    if (!audioRecorder.recording)
    
        btnPlay.enabled = NO;
        btnStop.enabled = YES;
        [audioRecorder record];
    


- (IBAction)stopAudio:(id)sender 
    btnStop.enabled = NO;
    btnPlay.enabled = YES;
    btnRecord.enabled = YES;

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

我知道那里有很多代码可以查看,但如果我遗漏了什么,请告诉我。非常感谢您对此提供任何帮助,谢谢。

编辑 1:好的,我做了更多调查并打开了保存我的音频文件的文件夹。音频记录良好,文件大小约为 400KB。当我推送到下一个视图控制器时,文件大小保持在 400KB。但是只要我按下我的后退按钮(不是导航栏中预编程的),文件大小就会变成 4KB;一个空文件。我的后退按钮的代码很简单:

- (IBAction)backPressed:(id)sender 
    [self.navigationController popViewControllerAnimated:YES];

请帮忙!

编辑 2:导航栏中的后退按钮也会发生这种情况。

【问题讨论】:

【参考方案1】:

您正在分配audioPlayeraudioRecorder.url。如果audioRecorder 发生了什么事,那么url 可能是无效的。

尝试这样设置audioPlayer

- (IBAction)playAudio:(id)sender 
    if (!audioRecorder.recording)
    
        btnStop.enabled = YES;
        btnRecord.enabled = NO;

        NSArray *dirPaths;
        NSString *docsDir;

        dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        docsDir = [dirPaths objectAtIndex:0];
        NSString *soundFilePath = [docsDir stringByAppendingPathComponent:@"page1.caf"];

        NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];

        NSError *error;

        audioPlayer = [[AVAudioPlayer alloc] nitWithContentsOfURL:soundFileUR                                    
                                                            error:&error];

        audioPlayer.delegate = self;

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

【讨论】:

您的意思是在我的playAudio 方法中替换audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioRecorder.url error:&error]; 还是将上述代码添加到我的prepareForAudioRecording 方法中? 它似乎与上面的新代码展示了相同的行为。它记录并播放视图控制器中的音频,但是当我从另一个控制器返回视图控制器时,播放按钮被禁用。我有点困惑为什么我已经在我的prepareForAudioRecording 方法中设置了文件路径,为什么还要再次声明它? 至于重新声明文件路径 - 只是为了代码安全。如果在您离开视图控制器时播放按钮被禁用,请检查是否再次调用 viewDidLoad(从而禁用播放按钮)。 刚刚在那里检查过,viewDidLoad 只是第一次被调用。在视图控制器之间导航时不会再次调用它。感谢您到目前为止 rokjarc 的帮助。

以上是关于保存音频文件并在视图之间导航的主要内容,如果未能解决你的问题,请参考以下文章

在使用 AVAudioRecorder 在为导航栏设置动画的同时录制音频时发生中断时,我们如何停止并保存录制?

如何在 SwiftUI 中使用 .fileimporter 保存音频文件并检索文件并在 SwiftUI 列表中显示它们的文件名?

如何更改录制音频的音高并在后台保存?

使用 AVAudioPlayer 播放音频

如何保存录制的音频iOS?

如何录制/保存 iPhone 应用程序中正在播放的音频?