播放暂停的AVAudioRecorder文件

Fel*_*oft 6 xcode objective-c avaudioplayer avaudiorecorder

在我的程序中,我希望用户能够:

  • 记录他的声音,
  • 暂停录制过程,
  • 听他录制的内容
  • 然后继续录制.

我已经设法达到了可以用AVAudioRecorder和AVAudioPlayer录制和播放录音的程度.但每当我尝试录制,暂停录制然后播放时,播放部分都会失败并且没有错误.

我可以猜测它没有播放的原因是因为音频文件尚未保存并仍在内存中.

有没有办法播放暂停的录音?如果有,请告诉我如何

我正在使用xcode 4.3.2

小智 10

如果要播放录音,则必须先停止录制才能将文件加载到AVAudioPlayer实例中.

如果你想能够播放一些录音,那么在听完录音后再添加更多录音,或者在录音中间录音.那么你就会遇到麻烦.

您必须创建一个新的音频文件,然后将它们组合在一起.

这是我的解决方案:

// Generate a composition of the two audio assets that will be combined into
// a single track
AVMutableComposition* composition = [AVMutableComposition composition];
AVMutableCompositionTrack* audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                 preferredTrackID:kCMPersistentTrackID_Invalid];

// grab the two audio assets as AVURLAssets according to the file paths
AVURLAsset* masterAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:self.masterFile] options:nil];
AVURLAsset* activeAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:self.newRecording] options:nil];

NSError* error = nil;

// grab the portion of interest from the master asset
[audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, masterAsset.duration)
                    ofTrack:[[masterAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
                     atTime:kCMTimeZero
                      error:&error];
if (error)
{
    // report the error
    return;
}

// append the entirety of the active recording
[audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, activeAsset.duration)
                    ofTrack:[[activeAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0]
                     atTime:masterAsset.duration
                      error:&error];

if (error)
{
    // report the error
    return;
}

// now export the two files
// create the export session
// no need for a retain here, the session will be retained by the
// completion handler since it is referenced there

AVAssetExportSession* exportSession = [AVAssetExportSession
                                       exportSessionWithAsset:composition
                                       presetName:AVAssetExportPresetAppleM4A];
if (nil == exportSession)
{
    // report the error
    return;
}


NSString* combined = @"combined file path";// create a new file for the combined file

// configure export session  output with all our parameters
exportSession.outputURL = [NSURL fileURLWithPath:combined]; // output path
exportSession.outputFileType = AVFileTypeAppleM4A; // output file type

[exportSession exportAsynchronouslyWithCompletionHandler:^{

    // export status changed, check to see if it's done, errored, waiting, etc
    switch (exportSession.status)
    {
        case AVAssetExportSessionStatusFailed:
            break;
        case AVAssetExportSessionStatusCompleted:
            break;
        case AVAssetExportSessionStatusWaiting:
            break;
        default:
            break;
    }
    NSError* error = nil;

    // your code for dealing with the now combined file
}];
Run Code Online (Sandbox Code Playgroud)

我不能完全赞同这项工作,但它是从其他几个人的输入拼凑而成的:

AVAudioRecorder/AVAudioPlayer - 将录音附加到文件

(目前我找不到其他链接)


Rin*_*ain 1

记录音频视图控制器.h

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

   @interface record_audio_testViewController : UIViewController <AVAudioRecorderDelegate> {

IBOutlet UIButton * btnStart;
IBOutlet UIButton * btnPlay;
IBOutlet UIActivityIndicatorView * actSpinner;
BOOL toggle;

//Variables setup for access in the class:
NSURL * recordedTmpFile;
AVAudioRecorder * recorder;
NSError * error;

 }

 @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;
 @end
Run Code Online (Sandbox Code Playgroud)

RecordAudioViewController.m

  @synthesize actSpinner, btnStart, btnPlay;
   - (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 setTitle:@"Stop Recording" forState: UIControlStateNormal ];  
    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.
    //I know this is a mess of collapsed things into 1 call.  I can break it out if need be.
    recordedTmpFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent: [NSString stringWithFormat: @"%.0f.%@", [NSDate timeIntervalSinceReferenceDate] * 1000.0, @"caf"]]];
    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 setTitle:@"Start Recording" forState:UIControlStateNormal ];
    btnPlay.enabled = toggle;
    btnPlay.hidden = !toggle;

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

  - (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];

// Release any cached data, images, etc that aren't in use.
  }

  -(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;
  }


  - (void)dealloc {
[super dealloc];
  }

 @end
Run Code Online (Sandbox Code Playgroud)

记录音频视图控制器.xib

拿2个按钮。1 用于开始录音,另一个用于播放录音


归档时间:

查看次数:

2943 次

最近记录:

7 年,9 月 前