如何用AVAudioRecorder在iPhone上录制音频?

如何用AVAudioRecorder在iPhone上录制音频?

既然iPhone3.0SDK已经公开,我想我可以问那些已经在玩3.0SDK的人这个问题了。我想在我的应用程序中记录音频,但我想使用AVAudioRecorder,而不是像SpeakHere示例那样使用更老的记录方式。在iPhoneDevCenter中,没有任何示例说明如何最好地做到这一点,而且只引用了类。我是iPhone开发的新手,所以我正在寻找一个简单的示例来让我开始。提前谢谢。


胡说叔叔
浏览 288回答 3
3回答

慕标5832272

虽然这是一个已回答的问题(有点旧),但我决定将我的完整工作代码发布给其他发现很难找到良好工作(开箱即用)播放和录制示例的人-包括编码、pcm、通过扬声器播放、写在这里的文件:AudioPlayerViewController.h:#import&nbsp;<UIKit/UIKit.h>#import&nbsp;<AVFoundation/AVFoundation.h>@interface&nbsp;AudioPlayerViewController&nbsp;:&nbsp;UIViewController&nbsp;{AVAudioPlayer&nbsp;*audioPlayer;AVAudioRecorder&nbsp;*audioRecorder;int&nbsp;recordEncoding;enum{ &nbsp;&nbsp;&nbsp;&nbsp;ENC_AAC&nbsp;=&nbsp;1, &nbsp;&nbsp;&nbsp;&nbsp;ENC_ALAC&nbsp;=&nbsp;2, &nbsp;&nbsp;&nbsp;&nbsp;ENC_IMA4&nbsp;=&nbsp;3, &nbsp;&nbsp;&nbsp;&nbsp;ENC_ILBC&nbsp;=&nbsp;4, &nbsp;&nbsp;&nbsp;&nbsp;ENC_ULAW&nbsp;=&nbsp;5, &nbsp;&nbsp;&nbsp;&nbsp;ENC_PCM&nbsp;=&nbsp;6,}&nbsp;encodingTypes;}-(IBAction)&nbsp;startRecording;-(IBAction)&nbsp;stopRecording;-(IBAction)&nbsp;playRecording;-(IBAction)&nbsp;stopPlaying;@endAudioPlayerViewController.m:#import&nbsp;"AudioPlayerViewController.h"@implementation&nbsp;AudioPlayerViewController-&nbsp;(void)viewDidLoad{ &nbsp;&nbsp;&nbsp;&nbsp;[super&nbsp;viewDidLoad]; &nbsp;&nbsp;&nbsp;&nbsp;recordEncoding&nbsp;=&nbsp;ENC_AAC;}-(IBAction)&nbsp;startRecording{NSLog(@"startRecording");[audioRecorder&nbsp;release];audioRecorder&nbsp;=&nbsp;nil;//&nbsp;Init&nbsp;audio&nbsp;with&nbsp;record&nbsp;capabilityAVAudioSession&nbsp;*audioSession&nbsp;=&nbsp;[AVAudioSession&nbsp;sharedInstance];[audioSession&nbsp;setCategory:AVAudioSessionCategoryRecord&nbsp;error:nil];NSMutableDictionary&nbsp;*recordSettings&nbsp;=&nbsp;[[NSMutableDictionary&nbsp;alloc]&nbsp;initWithCapacity:10];if(recordEncoding&nbsp;==&nbsp;ENC_PCM){ &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatLinearPCM]&nbsp;forKey:&nbsp;AVFormatIDKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithFloat:44100.0]&nbsp;forKey:&nbsp;AVSampleRateKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:2]&nbsp;forKey:AVNumberOfChannelsKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:16]&nbsp;forKey:AVLinearPCMBitDepthKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithBool:NO]&nbsp;forKey:AVLinearPCMIsBigEndianKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithBool:NO]&nbsp;forKey:AVLinearPCMIsFloatKey];&nbsp;&nbsp;&nbsp;}else{ &nbsp;&nbsp;&nbsp;&nbsp;NSNumber&nbsp;*formatObject; &nbsp;&nbsp;&nbsp;&nbsp;switch&nbsp;(recordEncoding)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;(ENC_AAC):&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatMPEG4AAC]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;(ENC_ALAC): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatAppleLossless]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;(ENC_IMA4): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatAppleIMA4]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;(ENC_ILBC): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatiLBC]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;(ENC_ULAW): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatULaw]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatAppleIMA4]; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:formatObject&nbsp;forKey:&nbsp;AVFormatIDKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithFloat:44100.0]&nbsp;forKey:&nbsp;AVSampleRateKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:2]&nbsp;forKey:AVNumberOfChannelsKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:12800]&nbsp;forKey:AVEncoderBitRateKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:16]&nbsp;forKey:AVLinearPCMBitDepthKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:&nbsp;AVAudioQualityHigh]&nbsp;forKey:&nbsp;AVEncoderAudioQualityKey];}NSURL&nbsp;*url&nbsp;=&nbsp;[NSURL&nbsp;fileURLWithPath:[NSString&nbsp;stringWithFormat:@"%@/recordTest.caf",&nbsp;[[NSBundle&nbsp;mainBundle]&nbsp;resourcePath]]];NSError&nbsp;*error&nbsp;=&nbsp;nil;audioRecorder&nbsp;=&nbsp;[[&nbsp;AVAudioRecorder&nbsp;alloc]&nbsp;initWithURL:url&nbsp;settings:recordSettings&nbsp;error:&error];if&nbsp;([audioRecorder&nbsp;prepareToRecord]&nbsp;==&nbsp;YES){ &nbsp;&nbsp;&nbsp;&nbsp;[audioRecorder&nbsp;record];}else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;errorCode&nbsp;=&nbsp;CFSwapInt32HostToBig&nbsp;([error&nbsp;code]);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;NSLog(@"Error:&nbsp;%@&nbsp;[%4.4s])"&nbsp;,&nbsp;[error&nbsp;localizedDescription],&nbsp;(char*)&errorCode);&nbsp;}NSLog(@"recording");}-(IBAction)&nbsp;stopRecording{NSLog(@"stopRecording");[audioRecorder&nbsp;stop];NSLog(@"stopped");}-(IBAction)&nbsp;playRecording{NSLog(@"playRecording");//&nbsp;Init&nbsp;audio&nbsp;with&nbsp;playback&nbsp;capabilityAVAudioSession&nbsp;*audioSession&nbsp;=&nbsp;[AVAudioSession&nbsp;sharedInstance];[audioSession&nbsp;setCategory:AVAudioSessionCategoryPlayback&nbsp;error:nil];NSURL&nbsp;*url&nbsp;=&nbsp;[NSURL&nbsp;fileURLWithPath:[NSString&nbsp;stringWithFormat:@"%@/recordTest.caf",&nbsp;[[NSBundle&nbsp;mainBundle]&nbsp;resourcePath]]];NSError&nbsp;*error;audioPlayer&nbsp;=&nbsp;[[AVAudioPlayer&nbsp;alloc]&nbsp;initWithContentsOfURL:url&nbsp;error:&error];audioPlayer.numberOfLoops&nbsp;=&nbsp;0;[audioPlayer&nbsp;play];NSLog(@"playing");}-(IBAction)&nbsp;stopPlaying{NSLog(@"stopPlaying");[audioPlayer&nbsp;stop];NSLog(@"stopped");}-&nbsp;(void)dealloc{[audioPlayer&nbsp;release];[audioRecorder&nbsp;release];[super&nbsp;dealloc];}@end希望这能帮到你们中的一些人。

哆啦的时光机

摇曳的蔷薇虽然这是一个已回答的问题(有点旧),但我决定将我的完整工作代码发布给其他发现很难找到良好工作(开箱即用)播放和录制示例的人-包括编码、pcm、通过扬声器播放、写在这里的文件:AudioPlayerViewController.h:#import&nbsp;<UIKit/UIKit.h>#import&nbsp;<AVFoundation/AVFoundation.h>@interface&nbsp;AudioPlayerViewController&nbsp;:&nbsp;UIViewController&nbsp;{AVAudioPlayer&nbsp;*audioPlayer;AVAudioRecorder&nbsp;*audioRecorder;int&nbsp;recordEncoding;enum{ &nbsp;&nbsp;&nbsp;&nbsp;ENC_AAC&nbsp;=&nbsp;1, &nbsp;&nbsp;&nbsp;&nbsp;ENC_ALAC&nbsp;=&nbsp;2, &nbsp;&nbsp;&nbsp;&nbsp;ENC_IMA4&nbsp;=&nbsp;3, &nbsp;&nbsp;&nbsp;&nbsp;ENC_ILBC&nbsp;=&nbsp;4, &nbsp;&nbsp;&nbsp;&nbsp;ENC_ULAW&nbsp;=&nbsp;5, &nbsp;&nbsp;&nbsp;&nbsp;ENC_PCM&nbsp;=&nbsp;6,}&nbsp;encodingTypes;}-(IBAction)&nbsp;startRecording;-(IBAction)&nbsp;stopRecording;-(IBAction)&nbsp;playRecording;-(IBAction)&nbsp;stopPlaying;@endAudioPlayerViewController.m:#import&nbsp;"AudioPlayerViewController.h"@implementation&nbsp;AudioPlayerViewController-&nbsp;(void)viewDidLoad{ &nbsp;&nbsp;&nbsp;&nbsp;[super&nbsp;viewDidLoad]; &nbsp;&nbsp;&nbsp;&nbsp;recordEncoding&nbsp;=&nbsp;ENC_AAC;}-(IBAction)&nbsp;startRecording{NSLog(@"startRecording");[audioRecorder&nbsp;release];audioRecorder&nbsp;=&nbsp;nil;//&nbsp;Init&nbsp;audio&nbsp;with&nbsp;record&nbsp;capabilityAVAudioSession&nbsp;*audioSession&nbsp;=&nbsp;[AVAudioSession&nbsp;sharedInstance];[audioSession&nbsp;setCategory:AVAudioSessionCategoryRecord&nbsp;error:nil];NSMutableDictionary&nbsp;*recordSettings&nbsp;=&nbsp;[[NSMutableDictionary&nbsp;alloc]&nbsp;initWithCapacity:10];if(recordEncoding&nbsp;==&nbsp;ENC_PCM){ &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatLinearPCM]&nbsp;forKey:&nbsp;AVFormatIDKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithFloat:44100.0]&nbsp;forKey:&nbsp;AVSampleRateKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:2]&nbsp;forKey:AVNumberOfChannelsKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:16]&nbsp;forKey:AVLinearPCMBitDepthKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithBool:NO]&nbsp;forKey:AVLinearPCMIsBigEndianKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithBool:NO]&nbsp;forKey:AVLinearPCMIsFloatKey];&nbsp;&nbsp;&nbsp;}else{ &nbsp;&nbsp;&nbsp;&nbsp;NSNumber&nbsp;*formatObject; &nbsp;&nbsp;&nbsp;&nbsp;switch&nbsp;(recordEncoding)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;(ENC_AAC):&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatMPEG4AAC]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;(ENC_ALAC): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatAppleLossless]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;(ENC_IMA4): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatAppleIMA4]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;(ENC_ILBC): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatiLBC]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;(ENC_ULAW): &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatULaw]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatObject&nbsp;=&nbsp;[NSNumber&nbsp;numberWithInt:&nbsp;kAudioFormatAppleIMA4]; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:formatObject&nbsp;forKey:&nbsp;AVFormatIDKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithFloat:44100.0]&nbsp;forKey:&nbsp;AVSampleRateKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:2]&nbsp;forKey:AVNumberOfChannelsKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:12800]&nbsp;forKey:AVEncoderBitRateKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:16]&nbsp;forKey:AVLinearPCMBitDepthKey]; &nbsp;&nbsp;&nbsp;&nbsp;[recordSettings&nbsp;setObject:[NSNumber&nbsp;numberWithInt:&nbsp;AVAudioQualityHigh]&nbsp;forKey:&nbsp;AVEncoderAudioQualityKey];}NSURL&nbsp;*url&nbsp;=&nbsp;[NSURL&nbsp;fileURLWithPath:[NSString&nbsp;stringWithFormat:@"%@/recordTest.caf",&nbsp;[[NSBundle&nbsp;mainBundle]&nbsp;resourcePath]]];NSError&nbsp;*error&nbsp;=&nbsp;nil;audioRecorder&nbsp;=&nbsp;[[&nbsp;AVAudioRecorder&nbsp;alloc]&nbsp;initWithURL:url&nbsp;settings:recordSettings&nbsp;error:&error];if&nbsp;([audioRecorder&nbsp;prepareToRecord]&nbsp;==&nbsp;YES){ &nbsp;&nbsp;&nbsp;&nbsp;[audioRecorder&nbsp;record];}else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;errorCode&nbsp;=&nbsp;CFSwapInt32HostToBig&nbsp;([error&nbsp;code]);&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;NSLog(@"Error:&nbsp;%@&nbsp;[%4.4s])"&nbsp;,&nbsp;[error&nbsp;localizedDescription],&nbsp;(char*)&errorCode);&nbsp;}NSLog(@"recording");}-(IBAction)&nbsp;stopRecording{NSLog(@"stopRecording");[audioRecorder&nbsp;stop];NSLog(@"stopped");}-(IBAction)&nbsp;playRecording{NSLog(@"playRecording");//&nbsp;Init&nbsp;audio&nbsp;with&nbsp;playback&nbsp;capabilityAVAudioSession&nbsp;*audioSession&nbsp;=&nbsp;[AVAudioSession&nbsp;sharedInstance];[audioSession&nbsp;setCategory:AVAudioSessionCategoryPlayback&nbsp;error:nil];NSURL&nbsp;*url&nbsp;=&nbsp;[NSURL&nbsp;fileURLWithPath:[NSString&nbsp;stringWithFormat:@"%@/recordTest.caf",&nbsp;[[NSBundle&nbsp;mainBundle]&nbsp;resourcePath]]];NSError&nbsp;*error;audioPlayer&nbsp;=&nbsp;[[AVAudioPlayer&nbsp;alloc]&nbsp;initWithContentsOfURL:url&nbsp;error:&error];audioPlayer.numberOfLoops&nbsp;=&nbsp;0;[audioPlayer&nbsp;play];NSLog(@"playing");}-(IBAction)&nbsp;stopPlaying{NSLog(@"stopPlaying");[audioPlayer&nbsp;stop];NSLog(@"stopped");}-&nbsp;(void)dealloc{[audioPlayer&nbsp;release];[audioRecorder&nbsp;release];[super&nbsp;dealloc];}@end希望这能帮到你们中的一些人。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

iOS