现在我们使用的手机,无论是苹果还是安卓,都能够录音、拍照和录像,而且感觉这是在正常不过的了,不仅如此,现在的手机还能够修音,修图在这里就不介绍了,这里主要介绍如何实现录音、拍照和录像的功能。

一、录音

     录音的介绍:使用的框架和音乐播放器一样使用的AVFoundation

     录音使用到的类

   (1)AVAudioRecord(输入)

   (2)相关的设置属性

 <1>AVNumberOfChannelsKey:通道数

 <2>AVSampleRateKey:采样率 44100

 <3>AVLinearPCMBitDepthKey:比特率 设置成16 32

 <4>AVEncoderAudioQualityKey:质量

 <5>AVEncoderBitRateKey:比特采样率 128000

  录音的步骤

  1、初始化了录音对象

  2、开始录音

  3、停止录音


具体代码


#import "ViewController.h"

#import <AVFoundation/AVFoundation.h>

@interface ViewController ()<AVAudioRecorderDelegate>

{

    AVAudioRecorder *audionRecorder;

}

@end

@implementation ViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

    button.frame = CGRectMake(100, 100, 100, 100);

    [button setTitle:@"TICK" forState:UIControlStateNormal];

    button.backgroundColor = [UIColor brownColor];

    [button addTarget:self action:@selector(startAudioRecorder:) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:button];

}


- (void)startAudioRecorder:(UIButton *)sender{

    sender.selected = !sender.selected;

    if (sender.selected != YES) {

        [audionRecorder stop];//停止录音

    }

//    URL是本地的URL,audioRecorder

    NSString *name = [NSString stringWithFormat:@"%d.aiff",(int)[NSDatedate].timeIntervalSince1970];

    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:name];

  //   1、初始化录音机

    NSError *error;

    audionRecorder = [[AVAudioRecorder alloc] initWithURL:[NSURL URLWithString:path] settings:@{AVNumberOfChannelsKey:@2,AVSampleRateKey:@44100,AVLinearPCMBitDepthKey:@32,AVEncoderAudioQualityKey:@(AVAudioQualityMax),AVEncoderBitRateKey:@128000} error:&error];

/*

 AVNumberOfChannelsKey:通道数,通常为双声道 值2

 AVSampleRateKey:采样率 HZ 通常设置为44100 44.1KHZ

 AVLinearPCMBitDepthKey:比特率,通常为8 16 24 32

 AVEncoderAudioQualityKey:声音质量,参数是一个枚举

 AVAudioQualityMin    = 0,最小的质量

  AVAudioQualityLow    = 0x20,比较低的质量

 AVAudioQualityMedium = 0x40,中间的质量

 AVAudioQualityHigh   = 0x60,高的质量

 AVAudioQualityMax    = 0x7F最好的质量

 AVEncoderBitRateKey:音频编码的比特率 单位BPS(传输速率)128000bps

 */

    [audionRecorder prepareToRecord];//欲录音

    [audionRecorder record];//开始录音

    audionRecorder.delegate = self;

    NSLog(@"%@",path);

}

//录音结束的时候调用

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

//    NSLog(@"录音结束");

    

    NSString *path = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];

//    文件操作的类

    NSFileManager *fileManager = [NSFileManager defaultManager];

//    获得当前文件的所有子文件subpathsAtPath:

    NSArray *pathList = [fileManager subpathsAtPath:path];

//    NSLog(@"%@",pathList);

//    NSString *path1 = pathList[2];

//    NSLog(@"%@",path1.pathExtension);

    

//    需要只获得录音文件

    NSMutableArray *audioPathList = [NSMutableArray array];

//    遍历所有这个文件夹下面的子文件

    for (NSString *audioPath in pathList) {

//        通过文件的扩展名(尾缀)来区分是不是录音文件

        if ([audioPath.pathExtension isEqualToString:@"aiff"]) {

//            把筛选出来的文件放到数组,得到所有的音频wenjian

            [audioPathList addObject:audioPath];

       }

    }

      NSLog(@"%@",audioPathList);

}




录像和拍照的使用很相似,在这里就将它们两个一块讲了


录像、拍照


录像和拍照使用的框架是UIKit框架,使用的类是:UIImagePickerController




介绍一些属性和方法


区分选择摄像头还是相册:sourceType

 UIImagePickerControllerSourceTypePhotoLibrary,

 保存的相册

 UIImagePickerControllerSourceTypeCamera,摄像头

 UIImagePickerControllerSourceTypeSavedPhotosAlbum相册

 

 区分录像和拍照cameraCaptureMode

  拍照:UIImagePickerControllerCameraCaptureModePhoto

  录像:UIImagePickerControllerCameraCaptureModeVideo

 

 设置视频清晰度

 UIImagePickerControllerQualityTypeHigh高清

 UIImagePickerControllerQualityTypeMedium普通

 UIImagePickerControllerQualityTypeLow

 UIImagePickerControllerQualityType 640x480

 UIImagePickerControllerQualityTypeIFrame 1280x720

 UIImagePickerControllerQualityTypeIFrame 960x540

 

 设置视频最大的持续时间

 videoMaximumDuration 默认最大十分钟

 

 

 区分前后摄像头:cameraDevice

 前置:UIImagePickerControllerCameraDeviceFront

 后置:UIImagePickerControllerCameraDeviceRear

 

 是否显示控制控件:showsCameraControls

 默认YES显示控制控件

 

 设置拍照:takePicture

 

 录像:startVideoCapture

 停止:stopVideoCapture

 

 闪光模式:cameraFlashMode,默认自动

 UIImagePickerControllerCameraFlashModeOff  = -1,关闭

 UIImagePickerControllerCameraFlashModeAuto = 0,自动

 UIImagePickerControllerCameraFlashModeOn   = 1

 开启

 

 设置调用摄像头视图页面 覆盖视图

 cameraOverlayView

 

 设置拍照页面的形态 camereViewTransform

 

 代理:需要导入两个代理

 @property(nullable,nonatomic,weak)      id <UINavigationControllerDelegate, UIImagePickerControllerDelegate> delegate;

 

 代理方法:不区分录像和拍照

采集完成之后调用 不区分拍照和录像

 - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info;

 采集取消的时候调用

 - (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker;







具体代码


#import "ViewController.h"

#import <AVKit/AVKit.h>

#import <AVFoundation/AVFoundation.h>

#import <MobileCoreServices/MobileCoreServices.h>


#define SCREEN_BOUNDS [UIScreen mainScreen].bounds//屏幕尺寸

#define SCREEN_WIDTH CGRectGetWidth([UIScreen mainScreen].bounds)//屏幕宽

#define SCREEN_HEIGHT CGRectGetHeight([UIScreen mainScreen].bounds)//屏幕高


@interface ViewController ()<UINavigationControllerDelegate,UIImagePickerControllerDelegate>

{

    UILabel *lable;//显示拍照或者录像的控件

    BOOL isMovie;//判断摄像的依据

    

    UIImageView *imageView;//显示拍照录像结果的视图

}

@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];

    button.frame = CGRectMake(100, 100, 100, 100);

    [button setTitle:@"Camera" forState:UIControlStateNormal];

    button.backgroundColor = [UIColor brownColor];

    [button addTarget:self action:@selector(doit) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:button];

    

    UISwitch *medioSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(SCREEN_WIDTH-100, 50, 50, 30)];

    [medioSwitch addTarget:self action:@selector(changeMedio:) forControlEvents:UIControlEventValueChanged];

    [self.view addSubview:medioSwitch];

    

    lable = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMinX(medioSwitch.frame), CGRectGetMinY(medioSwitch.frame)-30, 50, 50)];

    lable.textAlignment = NSTextAlignmentCenter;

    lable.textColor = [UIColor purpleColor];

    lable.text = @"拍照";

    [self.view addSubview:lable];

    

    imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 150, 200, 300)];

    [self.view addSubview:imageView];

}


- (void)changeMedio:(UISwitch *)sender{


    lable.text = sender.isOn != YES ? @"拍照":@"录像";


    isMovie = sender.isOn;


}


- (void)doit{

    //    创建录像、拍照对象

    UIImagePickerController *pickImageController = [[UIImagePickerController alloc] init];

    if (isMovie == YES) {

        

 //    选择摄像头设备

//     默认选择相册

    pickImageController.sourceType = UIImagePickerControllerSourceTypeCamera;

    

//    设置选择录像

//    默认拍照 选择cameraCaptureMode录像,一定要选择媒体的类型 不然会崩溃

    

//    选择媒体的类型

//    拍照的时候不选择媒体类型,不会崩溃,因为默认设置是kUTTypeImage

//    kUTTypeImage包含在MobileCoreServices框架中

//    MobileCoreServices需要的内容不是OC中字符串的类型,需要强转

    

//    mediaTypes录制视频,类型要选择movie,因为movie里面包含了audio和video

    pickImageController.mediaTypes = @[(NSString *)kUTTypeMovie];

    

    pickImageController.cameraCaptureMode =  UIImagePickerControllerCameraCaptureModeVideo;

    

     }

//    delegate里面包含两个协议

//    UINavigationBarDelegate

//    UIImagePickerControllerDelegate

    pickImageController.delegate = self;

    

    [self presentViewController:pickImageController animated:YES completion:nil];


}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info{


    NSLog(@"完成");

    

    NSLog(@">>>>%@",info);

   

    

    if ([info [UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeMovie]) {

        NSLog(@"录像。。。。。");

        

        NSLog(@"******%@",[info[UIImagePickerControllerMediaURL] path]);

        

//        将URL转换成path

        NSString *path = (NSString *)[info[UIImagePickerControllerMediaURL] path];

//        UIImagePickerControllerMediaURL

//        保存视频到URL

        UISaveVideoAtPathToSavedPhotosAlbum(path, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);

    }

    

    if ([info [UIImagePickerControllerMediaType ] isEqualToString:(NSString *)kUTTypeImage]) {

        NSLog(@"拍照了。。。。。");

        

//        UIImagePickerControllerOriginalImage

        

//        NSLog(@"%@",info [UIImagePickerControllerOriginalImage]);

        

        UIImage *finishImage = info[UIImagePickerControllerOriginalImage];

        

        imageView.image = nil;

        imageView.image = finishImage;

      

//        .jpeg的图片转换成二进制

     NSData *imageData = UIImageJPEGRepresentation(finishImage, 0.1);

//        .png的图片转换成二进制

    NSData *imageData1 = UIImagePNGRepresentation(finishImage);

        

//        通过这个方法将图片保存到相册

        UIImageWriteToSavedPhotosAlbum(finishImage, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);

    }

 [self dismissViewControllerAnimated:YES completion:nil];

}

//视频保存到相册之后调用

- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(void*)contextInfo{

    

    AVPlayer *player = [AVPlayer playerWithURL:[NSURL fileURLWithPath:videoPath]];

    

    AVPlayerViewController *palyerVC = [[AVPlayerViewController alloc] init];

    

//    [self.view addSubview:palyerVC.view];

    palyerVC.player = player;

    

    [self presentViewController:palyerVC animated:YES completion:nil];

    

    

    [palyerVC.player play];

}

//图片保存到相册之后调用

- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void*)contextInfo{


    NSLog(@"保存图片成功");


}


- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{

    NSLog(@"取消");

    [self dismissViewControllerAnimated:YES completion:nil];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


@end