Запуск диктофона в другом представлении? - PullRequest
0 голосов
/ 02 апреля 2011

Здравствуйте, хорошо, верно, у меня есть представление, называемое RecordViewController, в котором есть функция диктофона, поэтому, как только пользователь нажимает «запись», он записывает свой голос, я также создал кнопку «назад».Но после нажатия этой кнопки назад запись голоса также прекращается.Я хочу, чтобы, как только пользователь вернулся, он все еще записывал свой голос.Вот код, который я использовал:

.h

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreAudio/CoreAudioTypes.h>


@interface RecordViewController : UIViewController <AVAudioRecorderDelegate> {
  IBOutlet UIButton * btnStart;
  IBOutlet UIButton * btnPlay;
  IBOutlet UIActivityIndicatorView * actSpinner;
  BOOL toggle;

  NSURL * recordedTmpFile;
  AVAudioRecorder * recorder;
  NSError * error;
  NSTimer *theTimer;
  IBOutlet UILabel *seconds;
  int mainInt;
  NSString *timeRemainingString;     
}

@property (nonatomic,retain)IBOutlet UIActivityIndicatorView * actSpinner;
@property (nonatomic,retain)IBOutlet UIButton * btnStart;
@property (nonatomic,retain)IBOutlet UIButton * btnPlay;

- (IBAction) start_button_pressed;
- (IBAction) play_button_pressed;
- (IBAction)goBack:(id)sender;
- (void)countUp;

@end

.m

 #import "RecordViewController.h"


 @implementation RecordViewController
 @synthesize actSpinner, btnStart, btnPlay;

 - (void)countUp {
     mainInt += 1;
     seconds.text = [NSString stringWithFormat:@"%02d", mainInt];
 }

 - (IBAction)goBack:(id)sender; {
     [self dismissModalViewControllerAnimated:YES];
 }

 - (void)viewDidLoad {
     [super viewDidLoad];

     //Start the toggle in true mode.
     toggle = YES;
     btnPlay.hidden = YES;

     //Instanciate an instance of the AVAudioSession object.
     AVAudioSession * audioSession = [AVAudioSession sharedInstance];
     //Setup the audioSession for playback and record. 
     //We could just use record and then switch it to playback leter, but
     //since we are going to do both lets set it up once.
     [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord
 error: &error];
     //Activate the session
     [audioSession setActive:YES error: &error];

 }

- (IBAction)start_button_pressed {
  if(toggle) {
    toggle = NO;
    [actSpinner startAnimating];
    [btnStart setImage:[UIImage imageNamed:@"stoprecording.png"]
 forState:UIControlStateNormal];
    mainInt = 0;
    theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(countUp) userInfo:nil repeats:YES];

    btnPlay.enabled = toggle;
    btnPlay.hidden = !toggle;

    //Begin the recording session.
    //Error handling removed.  Please add to your own code.

    //Setup the dictionary object with all the recording settings that this 
    //Recording sessoin will use
    //Its not clear to me which of these are required and which are the bare minimum.
    //This is a good resource: http://www.totodotnet.net/tag/avaudiorecorder/
    NSMutableDictionary* recordSetting = [[NSMutableDictionary alloc] init];
    [recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
    [recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; 
    [recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];

    //Now that we have our settings we are going to instanciate an instance of our recorder instance.
    //Generate a temp file for use by the recording.
    //This sample was one I found online and seems to be a good choice for making a tmp file that
    //will not overwrite an existing one.
    NSString *fileName = [NSString stringWithFormat:@"%.0f.caf", [NSDate timeIntervalSinceReferenceDate] * 1000.0];
    NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
    recordedTmpFile = [NSURL fileURLWithPath:path];
    NSLog(@"Using File called: %@",recordedTmpFile);
    //Setup the recorder to use this file and record to it.
    recorder = [[AVAudioRecorder alloc] initWithURL:recordedTmpFile settings:recordSetting error:&error];
    //Use the recorder to start the recording.
    //Im not sure why we set the delegate to self yet.  
    //Found this in antother example, but Im fuzzy on this still.
    [recorder setDelegate:self];
    //We call this to start the recording process and initialize 
    //the subsstems so that when we actually say "record" it starts right away.
    [recorder prepareToRecord];
    //Start the actual Recording
    [recorder record];
    //There is an optional method for doing the recording for a limited time see 
    //[recorder recordForDuration:(NSTimeInterval) 10]     
  } else {
    toggle = YES;
    [actSpinner stopAnimating];
    [btnStart setImage:[UIImage imageNamed:@"recordrecord.png"] forState:UIControlStateNormal];
    btnPlay.enabled = toggle;
    btnPlay.hidden = !toggle;
    [theTimer invalidate];

    NSLog(@"Using File called: %@",recordedTmpFile);
    //Stop the recorder.
    [recorder stop];
  }
}

- (IBAction)play_button_pressed{

  //The play button was pressed... 
  //Setup the AVAudioPlayer to play the file that we just recorded.
  AVAudioPlayer * avPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:recordedTmpFile error:&error];
  [avPlayer prepareToPlay];
  [avPlayer play];
}

- (void)viewDidUnload {
  // Release any retained subviews of the main view.
  // e.g. self.myOutlet = nil;
  //Clean up the temp file.
  NSFileManager * fm = [NSFileManager defaultManager];
  [fm removeItemAtPath:[recordedTmpFile path] error:&error];
  //Call the dealloc on the remaining objects.
  [recorder dealloc];
  recorder = nil;
  recordedTmpFile = nil;
}

@end

1 Ответ

1 голос
/ 03 апреля 2011

Поскольку вы сейчас структурировали свой код, код записи звука полностью зависит от наличия пользовательского интерфейса.Как только ваш контроллер представления освобождается, аудио-рекордер также разрушается.

Вы должны отделить код записи аудио от кода пользовательского интерфейса.Создайте отдельный класс, который содержит все свойства и функции, связанные с записью.Затем создайте экземпляр этого класса вне вашего контроллера представления (например, в вашем делегате приложения) и только передайте этот объект вашему контроллеру представления.Важно то, что объект записи полностью не зависит от наличия или отсутствия контроллера вида.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...