ฉันจะบันทึกเสียงบน iPhone ด้วย AVAudioRecorder ได้อย่างไร


148

ตอนนี้ที่ iPhone 3.0 sdk เป็นสาธารณะฉันคิดว่าฉันสามารถถามคำถามนี้สำหรับคนที่เคยเล่นกับ 3.0 sdk แล้ว ฉันต้องการบันทึกเสียงในแอปพลิเคชันของฉัน แต่ฉันต้องการใช้ AVAudioRecorder และไม่ใช่วิธีการบันทึกแบบเก่าอย่างที่แสดงใน SpeakHere ไม่มีตัวอย่างใด ๆ ของวิธีการที่ดีที่สุดใน iPhone Dev Center และอ้างอิงถึงคลาส ฉันเป็นมือใหม่ในการพัฒนา iPhone ดังนั้นฉันกำลังมองหาตัวอย่างง่ายๆเพื่อเริ่มต้นใช้งาน ขอบคุณล่วงหน้า.

คำตอบ:


207

จริงๆแล้วไม่มีตัวอย่างเลย นี่คือรหัสการทำงานของฉัน ผู้ใช้กดปุ่มบน navBar เพื่อทำการบันทึก การบันทึกใช้คุณภาพซีดี (ตัวอย่าง 44100 ตัวอย่าง), สเตอริโอ (2 ช่องสัญญาณ) linear pcm ระวัง: หากคุณต้องการใช้รูปแบบที่แตกต่างกันโดยเฉพาะอย่างยิ่งรูปแบบที่เข้ารหัสตรวจสอบให้แน่ใจว่าคุณเข้าใจวิธีการตั้งค่า AVAudioRecorder (อ่านเอกสารประเภทเสียงอย่างระมัดระวัง) ไม่เช่นนั้นคุณจะไม่สามารถเริ่มใช้งานได้อย่างถูกต้อง อีกหนึ่งสิ่ง. ในรหัสฉันไม่แสดงวิธีจัดการข้อมูลการวัดแสง แต่คุณสามารถเข้าใจได้อย่างง่ายดาย ท้ายที่สุดโปรดทราบว่าวิธี AVAudioRecorder deleteRecording เนื่องจากการเขียนนี้ขัดข้องแอปพลิเคชันของคุณ นี่คือเหตุผลที่ฉันลบไฟล์ที่บันทึกผ่าน File Manager เมื่อบันทึกเสร็จแล้วฉันบันทึกเสียงที่บันทึกเป็น NSData ในวัตถุที่แก้ไขในปัจจุบันโดยใช้ KVC

#define DOCUMENTS_FOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]


- (void) startRecording{

UIBarButtonItem *stopButton = [[UIBarButtonItem alloc] initWithTitle:@"Stop" style:UIBarButtonItemStyleBordered  target:self action:@selector(stopRecording)];
self.navigationItem.rightBarButtonItem = stopButton;
[stopButton release];

AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err){
    NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
    return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err){
    NSLog(@"audioSession: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
    return;
}

recordSetting = [[NSMutableDictionary alloc] init];

[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; 
[recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

[recordSetting setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];



// Create a new dated file
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
NSString *caldate = [now description];
recorderFilePath = [[NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, caldate] retain];

NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
err = nil;
recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSetting error:&err];
if(!recorder){
    NSLog(@"recorder: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
    UIAlertView *alert =
    [[UIAlertView alloc] initWithTitle: @"Warning"
                               message: [err localizedDescription]
                              delegate: nil
                     cancelButtonTitle:@"OK"
                     otherButtonTitles:nil];
    [alert show];
    [alert release];
    return;
}

//prepare to record
[recorder setDelegate:self];
[recorder prepareToRecord];
recorder.meteringEnabled = YES;

BOOL audioHWAvailable = audioSession.inputIsAvailable;
if (! audioHWAvailable) {
    UIAlertView *cantRecordAlert =
    [[UIAlertView alloc] initWithTitle: @"Warning"
                               message: @"Audio input hardware not available"
                              delegate: nil
                     cancelButtonTitle:@"OK"
                     otherButtonTitles:nil];
    [cantRecordAlert show];
    [cantRecordAlert release]; 
    return;
}

// start recording
[recorder recordForDuration:(NSTimeInterval) 10];

}

- (void) stopRecording{

[recorder stop];

NSURL *url = [NSURL fileURLWithPath: recorderFilePath];
NSError *err = nil;
NSData *audioData = [NSData dataWithContentsOfFile:[url path] options: 0 error:&err];
if(!audioData)
    NSLog(@"audio data: %@ %d %@", [err domain], [err code], [[err userInfo] description]);
[editedObject setValue:[NSData dataWithContentsOfURL:url] forKey:editedFieldKey];   

//[recorder deleteRecording];


NSFileManager *fm = [NSFileManager defaultManager];

err = nil;
[fm removeItemAtPath:[url path] error:&err];
if(err)
    NSLog(@"File Manager: %@ %d %@", [err domain], [err code], [[err userInfo] description]);



UIBarButtonItem *startButton = [[UIBarButtonItem alloc] initWithTitle:@"Record" style:UIBarButtonItemStyleBordered  target:self action:@selector(startRecording)];
self.navigationItem.rightBarButtonItem = startButton;
[startButton release];

}

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag
{

NSLog (@"audioRecorderDidFinishRecording:successfully:");
// your actions here

}

ฉันคิดว่าฉันใกล้ที่จะทำให้โค้ดของคุณทำงานได้ แต่ฉันกำลังดิ้นรนกับสิ่งที่ได้รับมอบหมาย ฉันค่อนข้างใหม่สำหรับ Objective C และยังไม่ได้รับความคิดที่ถูกต้องในการทำผู้แทนสำหรับสิ่งนี้ ฉันมีตัวแทนของฉันพยายามใช้ NSObject <AVAudioRecorder> แต่ฉันไม่คิดว่าฉันทำถูกต้อง การโพสต์รหัสผู้แทนจะเป็นปัญหาด้วยหรือไม่ ขอบคุณ
Jim Zimmerman

ในที่สุดฉันก็สามารถทำงานได้โดยการเพิ่มสิ่งนี้ลงในชั้นเรียนตัวแทนของฉัน @protocol AVAudioRecorder @optional - (เป็นโมฆะ) audioRecorderBeginInterruption: (AVAudioRecorder *) เครื่องบันทึก; - (เป็นโมฆะ) audioRecorderDidFinishRecording: (AVAudioRecorder *) เครื่องบันทึกสำเร็จ: (BOOL) ตั้งค่าสถานะ; - (เป็นโมฆะ) audioRecorderEncodeErrorDidOccur: (AVAudioRecorder *) ข้อผิดพลาดของตัวบันทึก: (NSError *) ข้อผิดพลาด; - (เป็นโมฆะ) audioRecorderEndInterruption: (AVAudioRecorder *) เครื่องบันทึก; ดูเหมือนว่าจะได้ผล แต่ฉันไม่รู้ว่านี่เป็นวิธีปฏิบัติที่ดีที่สุดหรือไม่ ตอนนี้ฉันต้องเก็บมันไว้ในแหล่งข้อมูลในเครื่องและเล่นกลับไปที่อื่น
จิม Zimmerman

นั่นไม่ถูกต้องจิม ในส่วนหัวของตัวควบคุมเครื่องบันทึกคุณจะทำอะไรเช่น ... #import <AVFoundation / AVFoundation.h> @interface RecorderViewController: UIViewController <AVAudioRecorderDelegate> {
dizy

8
บางคำถาม: editedObject & editedFieldKey ใน stopRecording ไม่ได้กำหนด คุณช่วยให้แสงให้ฉันได้ไหม
Raptor

1
@ เพียงคนเดียวพวกเขาจะทำหน้าที่เหมือนกัน ฉันปรับรหัสดั้งเดิมที่ฉันไม่ได้ใช้วันที่ปัจจุบันดังนั้นฉันจึงมีคำสั่งในการบันทึกเช่นรหัสDate = [วันที่ NSDateWithTimeIntervalSinceNow: lastEvent] ในรหัสของฉันอยู่แล้ว ฉันเพิ่งเปลี่ยนเป็นสิ่งที่คุณเห็นในโค้ดขนาดสั้น แต่เนื่องจากขี้เกียจฉันไม่ได้เขียนคำแถลงใหม่ ;-)
Massimo Cafaro

85

แม้ว่านี่เป็นคำถามที่ตอบแล้ว (และชนิดเก่า) ฉันได้ตัดสินใจโพสต์รหัสการทำงานเต็มรูปแบบของฉันสำหรับคนอื่น ๆ ที่พบว่ามันยากที่จะหางานที่ดี (นอกกรอบ) การเล่นและการบันทึกตัวอย่าง - รวมถึงการเข้ารหัส pcm เล่นผ่านลำโพง เขียนไปที่ไฟล์นี่คือ:

AudioPlayerViewController.h:

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

@interface AudioPlayerViewController : UIViewController {
AVAudioPlayer *audioPlayer;
AVAudioRecorder *audioRecorder;
int recordEncoding;
enum
{
    ENC_AAC = 1,
    ENC_ALAC = 2,
    ENC_IMA4 = 3,
    ENC_ILBC = 4,
    ENC_ULAW = 5,
    ENC_PCM = 6,
} encodingTypes;
}

-(IBAction) startRecording;
-(IBAction) stopRecording;
-(IBAction) playRecording;
-(IBAction) stopPlaying;

@end

AudioPlayerViewController.m:

#import "AudioPlayerViewController.h"

@implementation AudioPlayerViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    recordEncoding = ENC_AAC;
}

-(IBAction) startRecording
{
NSLog(@"startRecording");
[audioRecorder release];
audioRecorder = nil;

// Init audio with record capability
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryRecord error:nil];

NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] initWithCapacity:10];
if(recordEncoding == ENC_PCM)
{
    [recordSettings setObject:[NSNumber numberWithInt: kAudioFormatLinearPCM] forKey: AVFormatIDKey];
    [recordSettings setObject:[NSNumber numberWithFloat:44100.0] forKey: AVSampleRateKey];
    [recordSettings setObject:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
    [recordSettings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recordSettings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [recordSettings setObject:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];   
}
else
{
    NSNumber *formatObject;

    switch (recordEncoding) {
        case (ENC_AAC): 
            formatObject = [NSNumber numberWithInt: kAudioFormatMPEG4AAC];
            break;
        case (ENC_ALAC):
            formatObject = [NSNumber numberWithInt: kAudioFormatAppleLossless];
            break;
        case (ENC_IMA4):
            formatObject = [NSNumber numberWithInt: kAudioFormatAppleIMA4];
            break;
        case (ENC_ILBC):
            formatObject = [NSNumber numberWithInt: kAudioFormatiLBC];
            break;
        case (ENC_ULAW):
            formatObject = [NSNumber numberWithInt: kAudioFormatULaw];
            break;
        default:
            formatObject = [NSNumber numberWithInt: kAudioFormatAppleIMA4];
    }

    [recordSettings setObject:formatObject forKey: AVFormatIDKey];
    [recordSettings setObject:[NSNumber numberWithFloat:44100.0] forKey: AVSampleRateKey];
    [recordSettings setObject:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
    [recordSettings setObject:[NSNumber numberWithInt:12800] forKey:AVEncoderBitRateKey];
    [recordSettings setObject:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recordSettings setObject:[NSNumber numberWithInt: AVAudioQualityHigh] forKey: AVEncoderAudioQualityKey];
}

NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", [[NSBundle mainBundle] resourcePath]]];


NSError *error = nil;
audioRecorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recordSettings error:&error];

if ([audioRecorder prepareToRecord] == YES){
    [audioRecorder record];
}else {
    int errorCode = CFSwapInt32HostToBig ([error code]); 
    NSLog(@"Error: %@ [%4.4s])" , [error localizedDescription], (char*)&errorCode); 

}
NSLog(@"recording");
}

-(IBAction) stopRecording
{
NSLog(@"stopRecording");
[audioRecorder stop];
NSLog(@"stopped");
}

-(IBAction) playRecording
{
NSLog(@"playRecording");
// Init audio with playback capability
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];

NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = 0;
[audioPlayer play];
NSLog(@"playing");
}

-(IBAction) stopPlaying
{
NSLog(@"stopPlaying");
[audioPlayer stop];
NSLog(@"stopped");
}

- (void)dealloc
{
[audioPlayer release];
[audioRecorder release];
[super dealloc];
}

@end

หวังว่านี่จะช่วยพวกคุณบางคนได้


สวัสดีเมื่อฉันสร้างและเรียกใช้รหัสที่สองที่ ShayBC ใช้บน iphone simulator ฉันไม่ได้ผลลัพธ์ใด ๆ เลย แต่ในคอนโซลมันแสดงว่ามันใช้งานได้ เครื่องจำลอง Iphone ใช้ลำโพงและไมโครโฟนของแล็ปท็อปของฉันหรือไม่และฉันต้องสร้างแอปบนอุปกรณ์หรือไม่

1
@Bataly the iphone simulator จะเล่นไฟล์เสียงของคุณ (mp3 / caf ... ) และสามารถบันทึกผ่านแล็ปท็อปของคุณได้ลองดูการตั้งค่าระบบของเสือดาวหากมีปัญหา แต่วิธีที่ดีที่สุดในการทดสอบแอปของคุณคือการรันมันบน iDevice จริงและเป็นความคิดที่ดีสำหรับรหัสทั้งหมดที่คุณเขียนเนื่องจากมีแอพจำนวนมากที่ถูกปฏิเสธจากแอพสโตร์เนื่องจากความผิดพลาดเนื่องจากไม่เคยทดสอบกับ iDevice จริงมีคุณสมบัติเพิ่มเติมที่ไม่รองรับการจำลอง (บลูทู ธ , กล้อง, มัลติทัชที่เหมาะสม, accelerometer, IAP, GPS, มันจะมีประสิทธิภาพที่ดีกว่า iDevice ที่สุด ... )
Shaybc

[บันทึกการตั้งค่า setObject: formatObject forKey: AVFormatIDKey]; บรรทัดนี้จะไม่ให้ฉันใช้ AVFormatIDKey เป็นกุญแจ สิ่งที่ช่วยให้? ถ้าฉันตั้งค่าเป็นค่าอื่นมันใช้งานได้ ...
jspooner

4
การค้นพบล่าสุดสำหรับ kAudioFormatMPEG4AAC เราไม่สามารถตั้งค่า AVEncoderBitRateKey เป็น 12800 แสดงความคิดเห็นปิดบรรทัดและมันจะทำงาน จะพยายามค้นหาว่าอัตราบิตที่ถูกต้องสำหรับ AAC ควรเป็นเท่าไหร่
joe kirk

11
ฉันไม่คิดว่าคุณสามารถเขียนถึงบันเดิลได้ดังนั้นฉันจึงเขียนเอกสารเช่นนี้: NSArray * path = NSSearchPathForDirectoriesInDomains (NSDocumentDirectory, NSUserDomainMask, YES); NSString * basePath = เส้นทาง [0]; NSURL * url = [NSURL fileURLWithPath: [NSString stringWithFormat: @ "% @ / recordTest.caf", basePath]];
marxy

14

ฉันอัพโหลดตัวอย่างโครงการแล้ว คุณสามารถดู

เครื่องบันทึกเสียง


ในกรณีที่คุณไม่พบสิ่งที่ดาวน์โหลด: ไปที่ 'ดาวน์โหลด' ที่มุมขวาบนจากนั้นไปที่ 'ดาวน์โหลด
แพคเก

@Phlibbo: หาอะไรไม่ได้ตอนนี้เหรอ?
user523234

@ user523234: นี่คือ URL การดาวน์โหลด - github.com/AvinashP/VoiceRecorder/downloads#download_128004
rajt

2
รหัสตัวอย่างไม่ได้รวบรวมตามที่ระบุไว้ในปัญหา Github เมื่อ 6 เดือนที่ผ่านมา
Dewayne

ฉันได้แก้ไขรหัสและเช็คอินเป็น github มันควรจะใช้งานได้แล้ว
Avinash

11

มันมีประโยชน์จริงๆ ปัญหาเดียวที่ฉันมีคือขนาดของไฟล์เสียงที่สร้างขึ้นหลังจากการบันทึก ฉันต้องการลดขนาดไฟล์ดังนั้นฉันจึงทำการเปลี่ยนแปลงการตั้งค่า

NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue :[NSNumber numberWithInt:kAudioFormatAppleIMA4] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:16000.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt: 1] forKey:AVNumberOfChannelsKey];

ขนาดไฟล์ลดลงจาก 360kb เหลือเพียง 25kb (การบันทึก 2 วินาที)


คุณสามารถโพสต์ส่วนที่เหลือของรหัสของคุณเช่นกัน? เพราะฉันคิดว่าฉันไม่มีทอง ฉันพยายามเปลี่ยนการตั้งค่าจำนวนมาก แต่ผมไม่สามารถที่จะลดขนาดไฟล์ ..
Swapnil Luktuke

1
ฉันอัพโหลดตัวอย่างโครงการแล้ว คุณสามารถดู github.com/AvinashP/VoiceRecorder
Avinash

8

ฉันพยายามทำให้รหัสนี้ทำงานในช่วง 2 ชั่วโมงที่ผ่านมาและถึงแม้ว่ามันจะไม่แสดงข้อผิดพลาดในตัวจำลอง แต่ก็มีอยู่หนึ่งตัวในอุปกรณ์

อย่างน้อยในกรณีของฉันที่ข้อผิดพลาดมาจากไดเรกทอรีที่ใช้ (บันเดิล):

NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", [[NSBundle mainBundle] resourcePath]]];

มันไม่สามารถเขียนได้หรืออะไรเช่นนี้ ... ไม่มีข้อผิดพลาดยกเว้นข้อเท็จจริงที่ว่าการเตรียมการบันทึกล้มเหลว ...

ฉันจึงแทนที่ด้วย:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *recDir = [paths objectAtIndex:0];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/recordTest.caf", recDir]]

ตอนนี้ใช้งานได้เหมือนเครื่องราง

หวังว่านี่จะช่วยผู้อื่น


1
คุณไม่ได้รับอนุญาตให้เขียนลงในโฟลเดอร์ทรัพยากร
saurabh

6

ขอบคุณมากที่@Massimo CafaroและShaybc ฉันสามารถบรรลุภารกิจด้านล่างได้

ใน iOS 8:

บันทึกเสียง & บันทึก

เล่นการบันทึกที่บันทึกไว้

1. เพิ่ม "AVFoundation.framework" ในโครงการของคุณ

ในไฟล์. h

2. เพิ่มคำชี้แจงการนำเข้า 'AVFoundation / AVFoundation.h' ด้านล่าง

3.Define "AVAudioRecorderDelegate"

4. สร้างเลย์เอาต์ที่มีปุ่มบันทึกเล่นและการกระทำของพวกเขา

5. กำหนดบันทึกและเครื่องเล่น ฯลฯ

นี่คือตัวอย่างรหัสที่สมบูรณ์ซึ่งอาจช่วยคุณได้

ViewController.h

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

@interface ViewController : UIViewController <AVAudioRecorderDelegate>

@property(nonatomic,strong) AVAudioRecorder *recorder;
@property(nonatomic,strong) NSMutableDictionary *recorderSettings;
@property(nonatomic,strong) NSString *recorderFilePath;
@property(nonatomic,strong) AVAudioPlayer *audioPlayer;
@property(nonatomic,strong) NSString *audioFileName;

- (IBAction)startRecording:(id)sender;
- (IBAction)stopRecording:(id)sender;

- (IBAction)startPlaying:(id)sender;
- (IBAction)stopPlaying:(id)sender;

@end

จากนั้นทำงานในสิ่งต่อไปนี้

ViewController.m

#import "ViewController.h"

#define DOCUMENTS_FOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]

@interface ViewController ()
@end

@implementation ViewController

@synthesize recorder,recorderSettings,recorderFilePath;
@synthesize audioPlayer,audioFileName;


#pragma mark - View Controller Life cycle methods
- (void)viewDidLoad
{
    [super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}


#pragma mark - Audio Recording
- (IBAction)startRecording:(id)sender
{
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    NSError *err = nil;
    [audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
    if(err)
    {
        NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
        return;
    }
    [audioSession setActive:YES error:&err];
    err = nil;
    if(err)
    {
        NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
        return;
    }
    
    recorderSettings = [[NSMutableDictionary alloc] init];
    [recorderSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
    [recorderSettings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
    [recorderSettings setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
    [recorderSettings setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
    [recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
    [recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
    
    // Create a new audio file
    audioFileName = @"recordingTestFile";
    recorderFilePath = [NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, audioFileName] ;
    
    NSURL *url = [NSURL fileURLWithPath:recorderFilePath];
    err = nil;
    recorder = [[ AVAudioRecorder alloc] initWithURL:url settings:recorderSettings error:&err];
    if(!recorder){
        NSLog(@"recorder: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
        UIAlertView *alert =
        [[UIAlertView alloc] initWithTitle: @"Warning" message: [err localizedDescription] delegate: nil
                         cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        return;
    }
    
    //prepare to record
    [recorder setDelegate:self];
    [recorder prepareToRecord];
    recorder.meteringEnabled = YES;
    
    BOOL audioHWAvailable = audioSession.inputIsAvailable;
    if (! audioHWAvailable) {
        UIAlertView *cantRecordAlert =
        [[UIAlertView alloc] initWithTitle: @"Warning"message: @"Audio input hardware not available"
                                  delegate: nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [cantRecordAlert show];
        return;
    }
    
    // start recording
    [recorder recordForDuration:(NSTimeInterval) 60];//Maximum recording time : 60 seconds default
    NSLog(@"Recroding Started");
}

- (IBAction)stopRecording:(id)sender
{
    [recorder stop];
    NSLog(@"Recording Stopped");
}

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *) aRecorder successfully:(BOOL)flag
{
    NSLog (@"audioRecorderDidFinishRecording:successfully:");
}


#pragma mark - Audio Playing
- (IBAction)startPlaying:(id)sender
{
    NSLog(@"playRecording");
    
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
    
     NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@.caf", DOCUMENTS_FOLDER, audioFileName]];
    NSError *error;
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
    audioPlayer.numberOfLoops = 0;
    [audioPlayer play];
    NSLog(@"playing");
}
- (IBAction)stopPlaying:(id)sender
{
    [audioPlayer stop];
    NSLog(@"stopped");
}

@end

ป้อนคำอธิบายรูปภาพที่นี่


2
This is from Multimedia programming guide...

- (IBAction) recordOrStop: (id) sender {
if (recording) {
    [soundRecorder stop];
    recording = NO;
    self.soundRecorder = nil;
    [recordOrStopButton setTitle: @"Record" forState:
     UIControlStateNormal];
    [recordOrStopButton setTitle: @"Record" forState:
     UIControlStateHighlighted];
    [[AVAudioSession sharedInstance] setActive: NO error:nil];
} 
else {
    [[AVAudioSession sharedInstance]
     setCategory: AVAudioSessionCategoryRecord
     error: nil];
    NSDictionary *recordSettings =
    [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithFloat: 44100.0], AVSampleRateKey,
     [NSNumber numberWithInt: kAudioFormatAppleLossless], AVFormatIDKey,
     [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
     [NSNumber numberWithInt: AVAudioQualityMax],
     AVEncoderAudioQualityKey,
     nil];
    AVAudioRecorder *newRecorder =
    [[AVAudioRecorder alloc] initWithURL: soundFileURL
                                settings: recordSettings
                                   error: nil];
    [recordSettings release];
    self.soundRecorder = newRecorder;
    [newRecorder release];
    soundRecorder.delegate = self;
    [soundRecorder prepareToRecord];
    [soundRecorder record];
    [recordOrStopButton setTitle: @"Stop" forState: UIControlStateNormal];
    [recordOrStopButton setTitle: @"Stop" forState: UIControlStateHighlighted];
    recording = YES;
}
}

2

ในลิงค์ต่อไปนี้คุณสามารถค้นหาข้อมูลที่เป็นประโยชน์เกี่ยวกับการบันทึกด้วย AVAudioRecording ในลิงค์นี้ในส่วนแรก "การใช้เสียง" มีสมอชื่อ "การบันทึกด้วย AVAudioRecorder Class" ที่นำคุณไปสู่ตัวอย่าง

AudioVideo Conceptual MultimediaPG


2

ตกลงดังนั้นคำตอบที่ฉันได้ช่วยฉันไปในทิศทางที่ถูกต้องและฉันรู้สึกขอบคุณมาก มันช่วยให้ฉันทราบวิธีการบันทึกบน iPhone จริง ๆ แต่ฉันคิดว่าฉันจะรวมรหัสที่เป็นประโยชน์บางอย่างที่ฉันได้รับจากห้องสมุดอ้างอิงของ iPhone:

AudioandVideoTechnologies

ฉันใช้รหัสนี้และเพิ่มลงในตัวอย่าง avTouch อย่างง่ายดาย ด้วยตัวอย่างโค้ดด้านบนและตัวอย่างจากไลบรารีอ้างอิงฉันสามารถทำให้สิ่งนี้ทำงานได้ดี


2

สำหรับรูปแบบ wav ด้านล่างการตั้งค่าเสียง

NSDictionary *audioSetting = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithFloat:44100.0],AVSampleRateKey,
                              [NSNumber numberWithInt:2],AVNumberOfChannelsKey,
                              [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
                              [NSNumber numberWithInt:kAudioFormatLinearPCM],AVFormatIDKey,
                              [NSNumber numberWithBool:NO], AVLinearPCMIsFloatKey, 
                              [NSNumber numberWithBool:0], AVLinearPCMIsBigEndianKey,
                              [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved,
                              [NSData data], AVChannelLayoutKey, nil];

ref: http://objective-audio.jp/2010/09/avassetreaderavassetwriter.html


ขอบคุณครับนี่คือรหัส ur ใน Swift: let recordSettings:[String:AnyObject] = [ AVFormatIDKey:Int(kAudioFormatLinearPCM), AVLinearPCMIsFloatKey:false, AVLinearPCMIsBigEndianKey:0, AVLinearPCMIsNonInterleaved:false, AVSampleRateKey:44100.0, AVNumberOfChannelsKey:2, AVEncoderBitRateKey:12800, AVLinearPCMBitDepthKey:16, AVEncoderAudioQualityKey:AVAudioQuality.Max.rawValue]
Husam

0

เริ่มต้น

NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);

NSError *error = nil;
NSString *filename = [NSString stringWithFormat:@"%@.caf",FILENAME];
NSString *path = [[NSHomeDirectory() stringByAppendingPathComponent:@"Documents"] stringByAppendingPathComponent:filename];
NSURL *soundFileURL = [NSURL fileURLWithPath:path];


NSDictionary *recordSettings = [NSDictionary dictionaryWithObjectsAndKeys:
                                [NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
                                [NSNumber numberWithInt:AVAudioQualityMedium],AVEncoderAudioQualityKey,
                                [NSNumber numberWithInt:AVAudioQualityMedium], AVSampleRateConverterAudioQualityKey,
                                [NSNumber numberWithInt: 1], AVNumberOfChannelsKey,
                                [NSNumber numberWithFloat:22050.0],AVSampleRateKey,
                                nil];

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


if (!error && [audioRecorder prepareToRecord])
{
    [audioRecorder record];
}

หยุด

[audioRecorder stop];
[audioRecorder release];
audioRecorder = nil;

การตั้งค่าคุณภาพเสียงที่เหมาะสมที่สุดที่ฉันพบ
comonitos

0
-(void)viewDidLoad {
 // Setup audio session
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

    // Define the recorder setting
    NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];

    [recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
    [recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
    [recordSetting setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];

    // Initiate and prepare the recorder
    recorder = [[AVAudioRecorder alloc] initWithURL:outputFileURL settings:recordSetting error:NULL];
    recorder.delegate = self;
    recorder.meteringEnabled = YES;
    [recorder prepareToRecord];

}    

- (IBAction)btnRecordDidClicked:(UIButton *)sender {
        if (player1.playing) {
            [player1 stop];
        }

        if (!recorder.recording) {
            AVAudioSession *session = [AVAudioSession sharedInstance];
            [session setActive:YES error:nil];

            // Start recording
            [recorder record];
            [_recordTapped setTitle:@"Pause" forState:UIControlStateNormal];

        } else {

            // Pause recording
            [recorder pause];
            [_recordTapped setTitle:@"Record" forState:UIControlStateNormal];
        }

        [_stopTapped setEnabled:YES];
        [_playTapped setEnabled:NO];

    }

    - (IBAction)btnPlayDidClicked:(UIButton *)sender {
        if (!recorder.recording){
            player1 = [[AVAudioPlayer alloc] initWithContentsOfURL:recorder.url error:nil];
            [player1 setDelegate:self];
            [player1 play];
        }
    }

    - (IBAction)btnStopDidClicked:(UIButton *)sender {
        [recorder stop];
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setActive:NO error:nil];
    }

    - (void) audioRecorderDidFinishRecording:(AVAudioRecorder *)avrecorder successfully:(BOOL)flag{
        [_recordTapped setTitle:@"play" forState:UIControlStateNormal];

        [_stopTapped setEnabled:NO];
        [_playTapped setEnabled:YES];

    }

-1

ตามคำตอบข้างต้นฉันได้ทำการเปลี่ยนแปลงบางอย่างและได้ผลลัพธ์ที่ถูกต้อง

ขั้นตอนที่ 1:ภายใต้ "inf.plist" เพิ่มสิทธิ์การใช้งานไมโครโฟน ==>

  <key>NSMicrophoneUsageDescription</key>
  <string>${PRODUCT_NAME} Microphone Usage</string>

ขั้นตอนที่ 2:

  1. บันทึกไฟล์เสียงบันทึกลงใน Local Document Directory

  2. เล่น / หยุดการบันทึก

  3. รับไฟล์เสียง Duration ของ Saved

นี่คือซอร์สโค้ด โปรดดูครั้งเดียวและใช้มัน

ViewController.h

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

@interface ViewController : UIViewController{
AVAudioPlayer *audioPlayer;
AVAudioRecorder *audioRecorder;
}

-(IBAction) startRecording;
-(IBAction) stopRecording;
-(IBAction) playRecording;
-(IBAction) stopPlaying;

@end

ViewController.m

#import "ViewController.h"
@interface ViewController () <AVAudioRecorderDelegate, AVAudioPlayerDelegate>

@end

@implementation ViewController

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

-(IBAction) startRecording{
// Setup audio session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err)
{
    NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
    return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err)
{
    NSLog(@"audioSession: %@ %ld %@", [err domain], (long)[err code], [[err userInfo] description]);
    return;
}
AVAudioSessionRecordPermission permissionStatus = [audioSession recordPermission];
switch (permissionStatus) {
    case AVAudioSessionRecordPermissionUndetermined:{
        [[AVAudioSession sharedInstance] requestRecordPermission:^(BOOL granted) {
            // CALL YOUR METHOD HERE - as this assumes being called only once from user interacting with permission alert!
            if (granted) {
                // Microphone enabled code
                NSLog(@"Mic permission granted.  Call method for granted stuff.");
                [self startRecordingAudioSound];
            }
            else {
                // Microphone disabled code
                NSLog(@"Mic permission indeterminate. Call method for indeterminate stuff.");
                //        UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
            }
        }];
        break;
    }
    case AVAudioSessionRecordPermissionDenied:
        // direct to settings...
        NSLog(@"Mic permission denied. Call method for denied stuff.");

        break;
    case AVAudioSessionRecordPermissionGranted:
        // mic access ok...
        NSLog(@"Mic permission granted.  Call method for granted stuff.");
        [self startRecordingAudioSound];
        break;
    default:
        // this should not happen.. maybe throw an exception.
        break;
}
}

#pragma mark - Audio Recording
- (BOOL)startRecordingAudioSound{
NSError *error = nil;
NSMutableDictionary *recorderSettings = [[NSMutableDictionary alloc] init];
[recorderSettings setValue :[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey];
[recorderSettings setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recorderSettings setValue:[NSNumber numberWithInt: 2] forKey:AVNumberOfChannelsKey];
[recorderSettings setValue :[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recorderSettings setValue :[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];

// Create a new audio file
NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentPath_ = [searchPaths objectAtIndex: 0];
NSString *pathToSave = [documentPath_ stringByAppendingPathComponent:[self dateString]];
NSLog(@"the path is %@",pathToSave);

// File URL
NSURL *url = [NSURL fileURLWithPath:pathToSave];//FILEPATH];

//Save recording path to preferences
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setURL:url forKey:@"Test1"];
[prefs synchronize];

audioRecorder = [[AVAudioRecorder alloc] initWithURL:url settings:recorderSettings error:&error];
if (!audioRecorder)
{
    NSLog(@"Error establishing recorder: %@", error.localizedFailureReason);
    return NO;
}

// Initialize degate, metering, etc.
audioRecorder.delegate = self;
audioRecorder.meteringEnabled = YES;
//self.title = @"0:00";

if (![audioRecorder prepareToRecord])
{
    NSLog(@"Error: Prepare to record failed");
    //[self say:@"Error while preparing recording"];
    return NO;
}

if (![audioRecorder record])
{
    NSLog(@"Error: Record failed");
    //  [self say:@"Error while attempting to record audio"];
    return NO;
}
NSLog(@"Recroding Started");
return YES;
}

#pragma mark - AVAudioRecorderDelegate
- (void) audioRecorderDidFinishRecording:(AVAudioRecorder *)avrecorder successfully:(BOOL)flag{
NSLog (@"audioRecorderDidFinishRecording:successfully:");
}

#pragma mark - AVAudioPlayerDelegate
- (void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
NSLog (@"audioPlayerDidFinishPlaying:successfully:");
}

- (NSString *) dateString {
// return a formatted string for a file name
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"ddMMMYY_hhmmssa";
return [[formatter stringFromDate:[NSDate date]]stringByAppendingString:@".aif"];
}

-(IBAction) stopRecording{
NSLog(@"stopRecording");
[audioRecorder stop];
NSLog(@"stopped");
}

-(IBAction) playRecording{
//Load recording path from preferences
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSURL *temporaryRecFile = [prefs URLForKey:@"Test1"];

//Get Duration of Audio File
AVURLAsset* audioAsset = [AVURLAsset URLAssetWithURL:temporaryRecFile options:nil];
CMTime audioDuration = audioAsset.duration;
float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
NSLog(@"Duration Of Audio: %f", audioDurationSeconds);

audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:temporaryRecFile error:nil];
audioPlayer.delegate = self;
[audioPlayer setNumberOfLoops:0];
audioPlayer.volume = 1;
[audioPlayer prepareToPlay];
[audioPlayer play];
NSLog(@"playing");
}

-(IBAction) stopPlaying{
NSLog(@"stopPlaying");
[audioPlayer stop];
NSLog(@"stopped");
 }

 @end

-[NSUserDefaults synchronize]อย่าใช้ จากเอกสารของ Apple "วิธีนี้ไม่จำเป็นและไม่ควรใช้"
Ashley Mills
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.