iOS 개발-사용자 정의 카메라 인 스 턴 스(위 챗 모방)
다음 라 이브 러 리 를 사 용 했 습 니 다:
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
사용 할 때 Info.plist 에 관련 권한 을 적어 야 합 니 다:
Privacy - Microphone Usage Description
Privacy - Photo Library Usage Description
Privacy - Camera Usage Description
제 가 이 demo 를 쓸 때 위 챗 의 스타일 에 따라 썼 습 니 다.똑 같이 사진 찍 기,길 게 누 르 기 동 영상 입 니 다.동 영상 녹화 가 끝나 면 바로 재생 합 니 다.여 기 는 간단 하고 간단 한 재생 기 를 봉 했 습 니 다.파일
#import "HAVPlayer.h"
#import <AVFoundation/AVFoundation.h>
@interface HAVPlayer ()
@property (nonatomic,strong) AVPlayer *player;//
@end
@implementation HAVPlayer
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (instancetype)initWithFrame:(CGRect)frame withShowInView:(UIView *)bgView url:(NSURL *)url {
if (self = [self initWithFrame:frame]) {
//
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame = self.bounds;
[self.layer addSublayer:playerLayer];
if (url) {
self.videoUrl = url;
}
[bgView addSubview:self];
}
return self;
}
- (void)dealloc {
[self removeAvPlayerNtf];
[self stopPlayer];
self.player = nil;
}
- (AVPlayer *)player {
if (!_player) {
_player = [AVPlayer playerWithPlayerItem:[self getAVPlayerItem]];
[self addAVPlayerNtf:_player.currentItem];
}
return _player;
}
- (AVPlayerItem *)getAVPlayerItem {
AVPlayerItem *playerItem=[AVPlayerItem playerItemWithURL:self.videoUrl];
return playerItem;
}
- (void)setVideoUrl:(NSURL *)videoUrl {
_videoUrl = videoUrl;
[self removeAvPlayerNtf];
[self nextPlayer];
}
- (void)nextPlayer {
[self.player seekToTime:CMTimeMakeWithSeconds(0, _player.currentItem.duration.timescale)];
[self.player replaceCurrentItemWithPlayerItem:[self getAVPlayerItem]];
[self addAVPlayerNtf:self.player.currentItem];
if (self.player.rate == 0) {
[self.player play];
}
}
- (void) addAVPlayerNtf:(AVPlayerItem *)playerItem {
//
[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
//
[playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}
- (void)removeAvPlayerNtf {
AVPlayerItem *playerItem = self.player.currentItem;
[playerItem removeObserver:self forKeyPath:@"status"];
[playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)stopPlayer {
if (self.player.rate == 1) {
[self.player pause];//
}
}
/**
* KVO
*
* @param keyPath
* @param object
* @param change
* @param context
*/
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
AVPlayerItem *playerItem = object;
if ([keyPath isEqualToString:@"status"]) {
AVPlayerStatus status= [[change objectForKey:@"new"] intValue];
if(status==AVPlayerStatusReadyToPlay){
NSLog(@" ..., :%.2f",CMTimeGetSeconds(playerItem.duration));
}
}else if([keyPath isEqualToString:@"loadedTimeRanges"]){
NSArray *array=playerItem.loadedTimeRanges;
CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//
float startSeconds = CMTimeGetSeconds(timeRange.start);
float durationSeconds = CMTimeGetSeconds(timeRange.duration);
NSTimeInterval totalBuffer = startSeconds + durationSeconds;//
NSLog(@" :%.2f",totalBuffer);
}
}
- (void)playbackFinished:(NSNotification *)ntf {
Plog(@" ");
[self.player seekToTime:CMTimeMake(0, 1)];
[self.player play];
}
@end
또한 위 챗 아래 버튼 을 길 게 누 르 면 원호 시간 대가 나타 납 니 다.파일
#import "HProgressView.h"
@interface HProgressView ()
/**
* 0-1.0
*/
@property (nonatomic,assign)CGFloat progressValue;
@property (nonatomic, assign) CGFloat currentTime;
@end
@implementation HProgressView
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef ctx = UIGraphicsGetCurrentContext();//
Plog(@"width = %f",self.frame.size.width);
CGPoint center = CGPointMake(self.frame.size.width/2.0, self.frame.size.width/2.0); //
CGFloat radius = self.frame.size.width/2.0-5; //
CGFloat startA = - M_PI_2; //
CGFloat endA = -M_PI_2 + M_PI * 2 * _progressValue; //
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startA endAngle:endA clockwise:YES];
CGContextSetLineWidth(ctx, 10); //
[[UIColor whiteColor] setStroke]; //
CGContextAddPath(ctx, path.CGPath); //
CGContextStrokePath(ctx); //
}
- (void)setTimeMax:(NSInteger)timeMax {
_timeMax = timeMax;
self.currentTime = 0;
self.progressValue = 0;
[self setNeedsDisplay];
self.hidden = NO;
[self performSelector:@selector(startProgress) withObject:nil afterDelay:0.1];
}
- (void)clearProgress {
_currentTime = _timeMax;
self.hidden = YES;
}
- (void)startProgress {
_currentTime += 0.1;
if (_timeMax > _currentTime) {
_progressValue = _currentTime/_timeMax;
Plog(@"progress = %f",_progressValue);
[self setNeedsDisplay];
[self performSelector:@selector(startProgress) withObject:nil afterDelay:0.1];
}
if (_timeMax <= _currentTime) {
[self clearProgress];
}
}
@end
다음은 카메라 의 컨트롤 러 입 니 다.임시로 쓴 것 이기 때문에 xib 를 사용 합 니 다.여러분 은 직접 사용 하지 말고 m 파일 코드 에 직접 올 리 세 요.
#import "HVideoViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "HAVPlayer.h"
#import "HProgressView.h"
#import <Foundation/Foundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
typedef void(^PropertyChangeBlock)(AVCaptureDevice *captureDevice);
@interface HVideoViewController ()<AVCaptureFileOutputRecordingDelegate>
// ,
@property (strong, nonatomic) IBOutlet UILabel *labelTipTitle;
//
@property (strong,nonatomic) AVCaptureMovieFileOutput *captureMovieFileOutput;
//
//@property (strong,nonatomic) AVCaptureStillImageOutput *captureStillImageOutput;//
// AVCaptureDevice
@property (strong,nonatomic) AVCaptureDeviceInput *captureDeviceInput;
//
@property (assign,nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier;
@property (assign,nonatomic) UIBackgroundTaskIdentifier lastBackgroundTaskIdentifier;
@property (weak, nonatomic) IBOutlet UIImageView *focusCursor; //
//
@property(nonatomic)AVCaptureSession *session;
// ,
@property(nonatomic)AVCaptureVideoPreviewLayer *previewLayer;
@property (strong, nonatomic) IBOutlet UIButton *btnBack;
//
@property (strong, nonatomic) IBOutlet UIButton *btnAfresh;
//
@property (strong, nonatomic) IBOutlet UIButton *btnEnsure;
//
@property (strong, nonatomic) IBOutlet UIButton *btnCamera;
@property (strong, nonatomic) IBOutlet UIImageView *bgView;
// 60
@property (assign, nonatomic) NSInteger seconds;
//
@property (strong, nonatomic) NSURL *saveVideoUrl;
//
@property (assign, nonatomic) BOOL isFocus;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *afreshCenterX;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *ensureCenterX;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *backCenterX;
//
@property (strong, nonatomic) HAVPlayer *player;
@property (strong, nonatomic) IBOutlet HProgressView *progressView;
// YES NO
@property (assign, nonatomic) BOOL isVideo;
@property (strong, nonatomic) UIImage *takeImage;
@property (strong, nonatomic) UIImageView *takeImageView;
@property (strong, nonatomic) IBOutlet UIImageView *imgRecord;
@end
// ,
#define TimeMax 1
@implementation HVideoViewController
-(void)dealloc{
[self removeNotification];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UIImage *image = [UIImage imageNamed:@"sc_btn_take.png"];
self.backCenterX.constant = -(SCREEN_WIDTH/2/2)-image.size.width/2/2;
self.progressView.layer.cornerRadius = self.progressView.frame.size.width/2;
if (self.HSeconds == 0) {
self.HSeconds = 60;
}
[self performSelector:@selector(hiddenTipsLabel) withObject:nil afterDelay:4];
}
- (void)hiddenTipsLabel {
self.labelTipTitle.hidden = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self customCamera];
[self.session startRunning];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
[self.session stopRunning];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}
- (void)customCamera {
// ,
self.session = [[AVCaptureSession alloc] init];
// ( )
if ([self.session canSetSessionPreset:AVCaptureSessionPresetHigh]) {
self.session.sessionPreset = AVCaptureSessionPresetHigh;
}
//
AVCaptureDevice *captureDevice = [self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];
//
AVCaptureDevice *audioCaptureDevice=[[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
//
NSError *error = nil;
self.captureDeviceInput = [[AVCaptureDeviceInput alloc] initWithDevice:captureDevice error:&error];
if (error) {
Plog(@" , :%@",error.localizedDescription);
return;
}
//
error = nil;
AVCaptureDeviceInput *audioCaptureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:audioCaptureDevice error:&error];
if (error) {
NSLog(@" , :%@",error.localizedDescription);
return;
}
//
self.captureMovieFileOutput = [[AVCaptureMovieFileOutput alloc] init];//
//
if ([self.session canAddInput:self.captureDeviceInput]) {
[self.session addInput:self.captureDeviceInput];
[self.session addInput:audioCaptureDeviceInput];
//
AVCaptureConnection *connection = [self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo];
if ([connection isVideoStabilizationSupported]) {
connection.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeCinematic;
}
}
// ( )
if ([self.session canAddOutput:self.captureMovieFileOutput]) {
[self.session addOutput:self.captureMovieFileOutput];
}
// ,
self.previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session];
self.previewLayer.frame = self.view.bounds;//CGRectMake(0, 0, self.view.width, self.view.height);
self.previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//
[self.bgView.layer addSublayer:self.previewLayer];
[self addNotificationToCaptureDevice:captureDevice];
[self addGenstureRecognizer];
}
- (IBAction)onCancelAction:(UIButton *)sender {
[self dismissViewControllerAnimated:YES completion:^{
[Utility hideProgressDialog];
}];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
if ([[touches anyObject] view] == self.imgRecord) {
Plog(@" ");
//
AVCaptureConnection *connection = [self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeAudio];
//
if (![self.captureMovieFileOutput isRecording]) {
//
if ([[UIDevice currentDevice] isMultitaskingSupported]) {
self.backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
}
if (self.saveVideoUrl) {
[[NSFileManager defaultManager] removeItemAtURL:self.saveVideoUrl error:nil];
}
//
connection.videoOrientation = [self.previewLayer connection].videoOrientation;
NSString *outputFielPath=[NSTemporaryDirectory() stringByAppendingString:@"myMovie.mov"];
NSLog(@"save path is :%@",outputFielPath);
NSURL *fileUrl=[NSURL fileURLWithPath:outputFielPath];
NSLog(@"fileUrl:%@",fileUrl);
[self.captureMovieFileOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self];
} else {
[self.captureMovieFileOutput stopRecording];
}
}
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
if ([[touches anyObject] view] == self.imgRecord) {
Plog(@" ");
if (!self.isVideo) {
[self performSelector:@selector(endRecord) withObject:nil afterDelay:0.3];
} else {
[self endRecord];
}
}
}
- (void)endRecord {
[self.captureMovieFileOutput stopRecording];//
}
- (IBAction)onAfreshAction:(UIButton *)sender {
Plog(@" ");
[self recoverLayout];
}
- (IBAction)onEnsureAction:(UIButton *)sender {
Plog(@" ");
if (self.saveVideoUrl) {
WS(weakSelf)
[Utility showProgressDialogText:@" ..."];
ALAssetsLibrary *assetsLibrary=[[ALAssetsLibrary alloc]init];
[assetsLibrary writeVideoAtPathToSavedPhotosAlbum:self.saveVideoUrl completionBlock:^(NSURL *assetURL, NSError *error) {
Plog(@"outputUrl:%@",weakSelf.saveVideoUrl);
[[NSFileManager defaultManager] removeItemAtURL:weakSelf.saveVideoUrl error:nil];
if (weakSelf.lastBackgroundTaskIdentifier!= UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:weakSelf.lastBackgroundTaskIdentifier];
}
if (error) {
Plog(@" , :%@",error.localizedDescription);
[Utility showAllTextDialog:KAppDelegate.window Text:@" "];
} else {
if (weakSelf.takeBlock) {
weakSelf.takeBlock(assetURL);
}
Plog(@" .");
[weakSelf onCancelAction:nil];
}
}];
} else {
//
UIImageWriteToSavedPhotosAlbum(self.takeImage, self, nil, nil);
if (self.takeBlock) {
self.takeBlock(self.takeImage);
}
[self onCancelAction:nil];
}
}
//
- (IBAction)onCameraAction:(UIButton *)sender {
Plog(@" ");
AVCaptureDevice *currentDevice=[self.captureDeviceInput device];
AVCaptureDevicePosition currentPosition=[currentDevice position];
[self removeNotificationFromCaptureDevice:currentDevice];
AVCaptureDevice *toChangeDevice;
AVCaptureDevicePosition toChangePosition = AVCaptureDevicePositionFront;//
if (currentPosition == AVCaptureDevicePositionUnspecified || currentPosition == AVCaptureDevicePositionFront) {
toChangePosition = AVCaptureDevicePositionBack;//
}
toChangeDevice=[self getCameraDeviceWithPosition:toChangePosition];
[self addNotificationToCaptureDevice:toChangeDevice];
//
AVCaptureDeviceInput *toChangeDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:toChangeDevice error:nil];
// ,
[self.session beginConfiguration];
//
[self.session removeInput:self.captureDeviceInput];
//
if ([self.session canAddInput:toChangeDeviceInput]) {
[self.session addInput:toChangeDeviceInput];
self.captureDeviceInput = toChangeDeviceInput;
}
//
[self.session commitConfiguration];
}
- (void)onStartTranscribe:(NSURL *)fileURL {
if ([self.captureMovieFileOutput isRecording]) {
-- self.seconds;
if (self.seconds > 0) {
if (self.HSeconds - self.seconds >= TimeMax && !self.isVideo) {
self.isVideo = YES;// TimeMax
self.progressView.timeMax = self.seconds;
}
[self performSelector:@selector(onStartTranscribe:) withObject:fileURL afterDelay:1.0];
} else {
if ([self.captureMovieFileOutput isRecording]) {
[self.captureMovieFileOutput stopRecording];
}
}
}
}
#pragma mark -
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections{
Plog(@" ...");
self.seconds = self.HSeconds;
[self performSelector:@selector(onStartTranscribe:) withObject:fileURL afterDelay:1.0];
}
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{
Plog(@" .");
[self changeLayout];
if (self.isVideo) {
self.saveVideoUrl = outputFileURL;
if (!self.player) {
self.player = [[HAVPlayer alloc] initWithFrame:self.bgView.bounds withShowInView:self.bgView url:outputFileURL];
} else {
if (outputFileURL) {
self.player.videoUrl = outputFileURL;
self.player.hidden = NO;
}
}
} else {
//
self.saveVideoUrl = nil;
[self videoHandlePhoto:outputFileURL];
}
}
- (void)videoHandlePhoto:(NSURL *)url {
AVURLAsset *urlSet = [AVURLAsset assetWithURL:url];
AVAssetImageGenerator *imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:urlSet];
imageGenerator.appliesPreferredTrackTransform = YES; //
NSError *error = nil;
CMTime time = CMTimeMake(0,30);// CMTime , , .( CMTimeMake )
CMTime actucalTime; //
CGImageRef cgImage = [imageGenerator copyCGImageAtTime:time actualTime:&actucalTime error:&error];
if (error) {
Plog(@" :%@",error.localizedDescription);
}
CMTimeShow(actucalTime);
UIImage *image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
if (image) {
Plog(@" ");
} else {
Plog(@" ");
}
self.takeImage = image;//[UIImage imageWithCGImage:cgImage];
[[NSFileManager defaultManager] removeItemAtURL:url error:nil];
if (!self.takeImageView) {
self.takeImageView = [[UIImageView alloc] initWithFrame:self.view.frame];
[self.bgView addSubview:self.takeImageView];
}
self.takeImageView.hidden = NO;
self.takeImageView.image = self.takeImage;
}
#pragma mark -
//
- (void)setupObservers
{
NSNotificationCenter *notification = [NSNotificationCenter defaultCenter];
[notification addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication]];
}
//
- (void)applicationDidEnterBackground:(NSNotification *)notification {
[self onCancelAction:nil];
}
/**
*
*/
-(void)addNotificationToCaptureDevice:(AVCaptureDevice *)captureDevice{
//
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
captureDevice.subjectAreaChangeMonitoringEnabled=YES;
}];
NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
//
[notificationCenter addObserver:self selector:@selector(areaChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
}
-(void)removeNotificationFromCaptureDevice:(AVCaptureDevice *)captureDevice{
NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
}
/**
*
*/
-(void)removeNotification{
NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:self];
}
-(void)addNotificationToCaptureSession:(AVCaptureSession *)captureSession{
NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
//
[notificationCenter addObserver:self selector:@selector(sessionRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:captureSession];
}
/**
*
*
* @param notification
*/
-(void)deviceConnected:(NSNotification *)notification{
NSLog(@" ...");
}
/**
*
*
* @param notification
*/
-(void)deviceDisconnected:(NSNotification *)notification{
NSLog(@" .");
}
/**
*
*
* @param notification
*/
-(void)areaChange:(NSNotification *)notification{
NSLog(@" ...");
}
/**
*
*
* @param notification
*/
-(void)sessionRuntimeError:(NSNotification *)notification{
NSLog(@" .");
}
/**
*
*
* @param position
*
* @return
*/
-(AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position{
NSArray *cameras= [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
for (AVCaptureDevice *camera in cameras) {
if ([camera position] == position) {
return camera;
}
}
return nil;
}
/**
*
*
* @param propertyChange
*/
-(void)changeDeviceProperty:(PropertyChangeBlock)propertyChange{
AVCaptureDevice *captureDevice= [self.captureDeviceInput device];
NSError *error;
// lockForConfiguration: unlockForConfiguration
if ([captureDevice lockForConfiguration:&error]) {
//
if ([captureDevice isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) {
[captureDevice setWhiteBalanceMode:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance];
}
//
if ([captureDevice isFlashModeSupported:AVCaptureFlashModeAuto]) {
[captureDevice setFlashMode:AVCaptureFlashModeAuto];
}
propertyChange(captureDevice);
[captureDevice unlockForConfiguration];
}else{
NSLog(@" , :%@",error.localizedDescription);
}
}
/**
*
*
* @param flashMode
*/
-(void)setFlashMode:(AVCaptureFlashMode )flashMode{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
if ([captureDevice isFlashModeSupported:flashMode]) {
[captureDevice setFlashMode:flashMode];
}
}];
}
/**
*
*
* @param focusMode
*/
-(void)setFocusMode:(AVCaptureFocusMode )focusMode{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
if ([captureDevice isFocusModeSupported:focusMode]) {
[captureDevice setFocusMode:focusMode];
}
}];
}
/**
*
*
* @param exposureMode
*/
-(void)setExposureMode:(AVCaptureExposureMode)exposureMode{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
if ([captureDevice isExposureModeSupported:exposureMode]) {
[captureDevice setExposureMode:exposureMode];
}
}];
}
/**
*
*
* @param point
*/
-(void)focusWithMode:(AVCaptureFocusMode)focusMode exposureMode:(AVCaptureExposureMode)exposureMode atPoint:(CGPoint)point{
[self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
// if ([captureDevice isFocusPointOfInterestSupported]) {
// [captureDevice setFocusPointOfInterest:point];
// }
// if ([captureDevice isExposurePointOfInterestSupported]) {
// [captureDevice setExposurePointOfInterest:point];
// }
if ([captureDevice isExposureModeSupported:exposureMode]) {
[captureDevice setExposureMode:exposureMode];
}
if ([captureDevice isFocusModeSupported:focusMode]) {
[captureDevice setFocusMode:focusMode];
}
}];
}
/**
* ,
*/
-(void)addGenstureRecognizer{
UITapGestureRecognizer *tapGesture=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapScreen:)];
[self.bgView addGestureRecognizer:tapGesture];
}
-(void)tapScreen:(UITapGestureRecognizer *)tapGesture{
if ([self.session isRunning]) {
CGPoint point= [tapGesture locationInView:self.bgView];
// UI
CGPoint cameraPoint= [self.previewLayer captureDevicePointOfInterestForPoint:point];
[self setFocusCursorWithPoint:point];
[self focusWithMode:AVCaptureFocusModeContinuousAutoFocus exposureMode:AVCaptureExposureModeContinuousAutoExposure atPoint:cameraPoint];
}
}
/**
*
*
* @param point
*/
-(void)setFocusCursorWithPoint:(CGPoint)point{
if (!self.isFocus) {
self.isFocus = YES;
self.focusCursor.center=point;
self.focusCursor.transform = CGAffineTransformMakeScale(1.25, 1.25);
self.focusCursor.alpha = 1.0;
[UIView animateWithDuration:0.5 animations:^{
self.focusCursor.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
[self performSelector:@selector(onHiddenFocusCurSorAction) withObject:nil afterDelay:0.5];
}];
}
}
- (void)onHiddenFocusCurSorAction {
self.focusCursor.alpha=0;
self.isFocus = NO;
}
//
- (void)changeLayout {
self.imgRecord.hidden = YES;
self.btnCamera.hidden = YES;
self.btnAfresh.hidden = NO;
self.btnEnsure.hidden = NO;
self.btnBack.hidden = YES;
if (self.isVideo) {
[self.progressView clearProgress];
}
self.afreshCenterX.constant = -(SCREEN_WIDTH/2/2);
self.ensureCenterX.constant = SCREEN_WIDTH/2/2;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
self.lastBackgroundTaskIdentifier = self.backgroundTaskIdentifier;
self.backgroundTaskIdentifier = UIBackgroundTaskInvalid;
[self.session stopRunning];
}
//
- (void)recoverLayout {
if (self.isVideo) {
self.isVideo = NO;
[self.player stopPlayer];
self.player.hidden = YES;
}
[self.session startRunning];
if (!self.takeImageView.hidden) {
self.takeImageView.hidden = YES;
}
// self.saveVideoUrl = nil;
self.afreshCenterX.constant = 0;
self.ensureCenterX.constant = 0;
self.imgRecord.hidden = NO;
self.btnCamera.hidden = NO;
self.btnAfresh.hidden = YES;
self.btnEnsure.hidden = YES;
self.btnBack.hidden = NO;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
사용 도 간단 하 다.
- (IBAction)onCameraAction:(UIButton *)sender {
// 。。 demo, xib, , demo ,
HVideoViewController *ctrl = [[NSBundle mainBundle] loadNibNamed:@"HVideoViewController" owner:nil options:nil].lastObject;
ctrl.HSeconds = 30;//
ctrl.takeBlock = ^(id item) {
if ([item isKindOfClass:[NSURL class]]) {
NSURL *videoURL = item;
// url
} else {
//
}
};
[self presentViewController:ctrl animated:YES completion:nil];
}
demo 주소 도 주세요.여기 서 끝 났 습 니 다.간단하게 썼 습 니 다.여러분 께 도움 이 되 었 으 면 좋 겠 습 니 다.감사합니다!
x 효과 도 붙 여 주세요:
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Swift의 패스트 패스Objective-C를 대체하기 위해 만들어졌지만 Xcode는 Objective-C 런타임 라이브러리를 사용하기 때문에 Swift와 함께 C, C++ 및 Objective-C를 컴파일할 수 있습니다. Xcode는 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.