一个可以录音录视频、视频预览播放、并删除视频音频的小demo~标题好长
界面丑的掉渣,这是为了测试写的一个demo,主要解决了播放视频之后再播放音频不成功的问题
预览界面足够丑
播放界面更丑
因为录制完要跳转到视频播放页面,但是本页的viewController为空,跳不过去,所以要在AppDelegate.m里面稍作处理
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease]; //这里自己定义新的UINavigationController UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:self.viewController]; [self.window addSubview:nav.view]; // self.window.rootViewController = self.viewController;//这是原来的 [self.window makeKeyAndVisible]; return YES; }
然后倒入这些库MediaPlayer.framework,CoreMedia.framework,MobileCoreServices.framework,AudioToolbox.framework,AVFoundation.framework,CoreAudio.framework
ViewController.m
// // ViewController.m // testRecord // // Created by changjian on 13-6-1. // Copyright (c) 2013年 changjian. All rights reserved. // #import "ViewController.h" #import <AVFoundation/AVFoundation.h> #import <MobileCoreServices/MobileCoreServices.h> #import "PreviousViewController.h" @interface ViewController ()<AVAudioRecorderDelegate,AVAudioPlayerDelegate,UINavigationControllerDelegate,UIImagePickerControllerDelegate>{ AVAudioRecorder *_audioRecorder; AVAudioPlayer *_audioPlayer; NSString *_mediaPath; } @property (retain, nonatomic) IBOutlet UIButton *recordVoice; @property (retain, nonatomic) IBOutlet UIButton *recordVideo; @property (retain, nonatomic) IBOutlet UIButton *playVoiceButton; @property (retain, nonatomic)NSString *voicePath; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)tapRecordVoice:(id)sender { UIButton *voiceButton = (UIButton *)sender; voiceButton.selected = !voiceButton.isSelected; if (voiceButton.isSelected) { [_audioRecorder release]; _audioRecorder = nil;
//下面两句是避免播视频之后不能正常播音频的,全文中一共有三处 AVAudioSession *session = [AVAudioSession sharedInstance]; [session setCategory:AVAudioSessionCategoryRecord error:nil]; /*******路径*******/ NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; [dateFormatter setDateFormat:@"yyyymmddhhmmss"]; NSString *dateString = [dateFormatter stringFromDate:[NSDate date]]; NSString *fileName = [dateString stringByAppendingString:@".caf"]; NSString *filePath = ITTPathForCacheResource([NSString stringWithFormat:@"%@",fileName]); // NSLog(@"lujing===%@",filePath); self.voicePath = filePath; /*****参数******/ NSMutableDictionary *recordSettings=[[NSMutableDictionary alloc]init]; NSNumber *formatObject; formatObject = [NSNumber numberWithInt: kAudioFormatMPEG4AAC]; [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]; NSError *error = nil; _audioRecorder = [[AVAudioRecorder alloc]initWithURL:[NSURL URLWithString:filePath] settings:recordSettings error:&error]; [recordSettings release]; _audioRecorder.delegate = self; if ([_audioRecorder prepareToRecord] == YES) { [_audioRecorder record]; }else { int errorCode = CFSwapInt32HostToBig ([error code]); NSLog(@"Error: %@ [%4.4s])" , [error localizedDescription], (char*)&errorCode); } [dateFormatter release]; }else{ [_audioRecorder stop]; AVAudioSession *session = [AVAudioSession sharedInstance]; [session setCategory:AVAudioSessionCategoryPlayback error:nil]; } } - (IBAction)tapPlayVoice:(id)sender { UIButton *playeButton = (UIButton*)sender; playeButton.selected = !playeButton.isSelected; NSString *path = [NSString stringWithString:_voicePath]; if (playeButton.isSelected) { AVAudioSession *session = [AVAudioSession sharedInstance]; [session setCategory:AVAudioSessionCategoryPlayback error:nil]; if(_audioPlayer){ [_audioPlayer release]; _audioPlayer = nil; } _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:nil]; _audioPlayer.delegate = self; if ([_audioPlayer prepareToPlay] == YES) { [_audioPlayer play]; } }else{ [_audioPlayer stop]; } } - (IBAction)clearRecordVoice:(id)sender { NSFileManager * fm = [NSFileManager defaultManager]; [fm removeItemAtPath:self.voicePath error:nil]; NSLog(@"清除录音"); _playVoiceButton.hidden = YES; _recordVoice.hidden = NO; } - (IBAction)clearVideo:(id)sender { NSFileManager *fm = [NSFileManager defaultManager]; [fm removeItemAtPath:_mediaPath error:nil]; NSLog(@"清除视频"); _recordVideo.selected = NO; } #pragma mark - AVAudioRecorderDelegate - (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag{ NSLog(@"recorder successfully"); _recordVoice.hidden = YES; _playVoiceButton.hidden = NO; } #pragma mark - AVAudioPlayerDelegate - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ NSLog(@"播放录音完成"); _playVoiceButton.selected = NO; } - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer*)player error:(NSError *)error{ NSLog(@"出错了"); } #pragma mark UIImagePickerControllerDelegate - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType]; NSString *cacheDirectory = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0]; NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init]; [dateFormatter setDateFormat:@"yyyymmddhhmmss"]; NSString *dateString = [dateFormatter stringFromDate:[NSDate date]]; [dateFormatter release]; NSString *path = nil; if ([mediaType isEqualToString:(NSString*)kUTTypeImage]) { UIImage *editImage = [info objectForKey:UIImagePickerControllerOriginalImage]; NSData *imageData = UIImageJPEGRepresentation(editImage,0.1);//压缩图片系数 path = [dateString stringByAppendingString:@".jpg"]; [imageData writeToFile:[cacheDirectory stringByAppendingPathComponent:path] atomically:YES]; }else if ([mediaType isEqualToString:(NSString*)kUTTypeMovie]){ NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL]; NSData *videoData = [NSData dataWithContentsOfURL:videoURL]; path = [dateString stringByAppendingString:@".mov"]; [videoData writeToFile:[cacheDirectory stringByAppendingPathComponent:path] atomically:YES]; } NSLog(@"媒体地址%@",[cacheDirectory stringByAppendingPathComponent:path]); _mediaPath = [[NSString stringWithString:[cacheDirectory stringByAppendingPathComponent:path]]retain]; [picker dismissViewControllerAnimated:YES completion:^{ _recordVideo.selected = YES; }]; } - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker { [picker dismissViewControllerAnimated:YES completion:^{ }]; } - (IBAction)recordVideo:(id)sender { UIButton *button = (UIButton*)sender; if (button.isSelected == YES) { PreviousViewController *previousViewController = [[PreviousViewController alloc]init]; previousViewController.mediaPath = _mediaPath; [self.navigationController pushViewController:previousViewController animated:YES]; NSLog(@"self.navigationController==%@",self.navigationController); [previousViewController release]; }else{ if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) { NSLog(@"相机不可用"); return; } UIImagePickerController *imagePickViewController = [[UIImagePickerController alloc]init]; imagePickViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical; imagePickViewController.sourceType = UIImagePickerControllerSourceTypeCamera; imagePickViewController.cameraDevice = UIImagePickerControllerCameraDeviceRear; NSArray *sourceType = [UIImagePickerController availableMediaTypesForSourceType:imagePickViewController.sourceType]; if ([sourceType containsObject:(NSString*)kUTTypeMovie]) { imagePickViewController.mediaTypes = [NSArray arrayWithObjects:(NSString*)kUTTypeMovie,(NSString*)kUTTypeImage, nil]; } imagePickViewController.allowsEditing = NO; imagePickViewController.delegate = self; [self presentViewController:imagePickViewController animated:YES completion:^{ }]; [imagePickViewController release]; } } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /** * 返回Cache资源路径 */ NSString *ITTPathForCacheResource(NSString* relativePath){ static NSString* documentsPath = nil; if (nil == documentsPath) { NSArray* dirs = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); documentsPath = [dirs[0] retain]; } return [documentsPath stringByAppendingPathComponent:relativePath]; } - (void)dealloc { [_mediaPath release]; [_recordVoice release]; [_recordVideo release]; [_playVoiceButton release]; [super dealloc]; } @end
播放视频类
PreviousViewController.h
// // PreviousViewController.h // testRecord // // Created by changjian on 13-6-1. // Copyright (c) 2013年 changjian. All rights reserved. // #import <UIKit/UIKit.h> @interface PreviousViewController : UIViewController @property(nonatomic,copy)NSString *mediaPath; @end
PreviousViewController.//// PreviousViewController.m
// testRecord // // Created by changjian on 13-6-1. // Copyright (c) 2013年 changjian. All rights reserved. // #import "PreviousViewController.h" #import <CoreMedia/CoreMedia.h> #import <AVFoundation/AVFoundation.h> #import <MediaPlayer/MediaPlayer.h> @interface PreviousViewController (){ MPMoviePlayerController *_moviePlayerController;//注意这个对象必须定义为全局的,不然播放时会出错! } @property (retain, nonatomic) IBOutlet UIButton *playButton; @property (retain, nonatomic) IBOutlet UIImageView *backImageView; @property (retain, nonatomic) IBOutlet UIView *backView; @end @implementation PreviousViewController - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; if ([_mediaPath hasSuffix:@".jpg"]) { NSLog(@"无视频"); }else if([_mediaPath hasSuffix:@".mov"]){ [NSThread detachNewThreadSelector:@selector(getGenerateThumbNailDataWithVideo:) toTarget:self withObject:_mediaPath]; } [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(playDidFinish) name:MPMoviePlayerPlaybackDidFinishNotification object:nil]; // Do any additional setup after loading the view from its nib. } - (void)playDidFinish{ [UIView animateWithDuration:0.5 animations:^{ _playButton.alpha = 1.0; _backImageView.alpha = 1.0; if (_moviePlayerController) { // [_moviePlayerController stop]; [_moviePlayerController.view removeFromSuperview]; } }completion:^(BOOL finish){ }]; NSLog(@"播放完了"); } //下面这个方法用来获得视频的截图 -(void)getGenerateThumbNailDataWithVideo:(NSString*)path { NSURL *url = [NSURL fileURLWithPath:path];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil]; AVAssetImageGenerator *generate = [[AVAssetImageGenerator alloc] initWithAsset:asset]; generate.appliesPreferredTrackTransform = YES; NSError *err = NULL; CMTime time = CMTimeMake(1, 60); CGImageRef imgRef = [generate copyCGImageAtTime:time actualTime:NULL error:&err]; [generate release]; [asset release]; UIImage *currentImg = [[[UIImage alloc] initWithCGImage:imgRef]autorelease]; CGImageRelease(imgRef); [self performSelectorOnMainThread:@selector(updateView:) withObject:currentImg waitUntilDone:YES]; } - (void)updateView:(UIImage*)image{ [_backImageView setImage:image]; } - (IBAction)tapPlayVideo:(id)sender withFilePath:(NSString *)path{ if(!_moviePlayerController){ _moviePlayerController = [[MPMoviePlayerController alloc]init]; _moviePlayerController.contentURL = [NSURL fileURLWithPath:_mediaPath]; _moviePlayerController.controlStyle = MPMovieControlStyleDefault; _moviePlayerController.scalingMode =MPMovieScalingModeAspectFill; _moviePlayerController.view.frame = CGRectMake(30, 20, 250, 350); [_moviePlayerController play]; } [self.view addSubview:_moviePlayerController.view]; [UIView animateWithDuration:0.5 animations:^{ _playButton.alpha = 0; _backImageView.alpha = 0; }completion:^(BOOL finish){ }]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)dealloc { [[NSNotificationCenter defaultCenter]removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:nil]; if (_moviePlayerController) { [_moviePlayerController stop]; [_moviePlayerController.view removeFromSuperview]; } [_playButton release]; [_moviePlayerController release]; [_backImageView release]; [_backView release]; [super dealloc]; } @end