如何检测用户何时在UIImagePickerController中点击“Record”按钮?

时间:2011-02-05 21:08:45

标签: iphone video uiimagepickercontroller

我想在用户点击UIImagePicker控制器中的记录按钮时显示倒计时,但是没有委托方法告诉我们他们何时记录。我可以设置一个最大持续时间,但我想给出一个1分钟的警告或者那个效果,但我不知道该怎么做

videoPickerCtrl = [[UIImagePickerController alloc] init];
videoPickerCtrl.delegate = self;
videoPickerCtrl.sourceType =      UIImagePickerControllerSourceTypeCamera;
videoPickerCtrl.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:videoPickerCtrl.sourceType];   
videoPickerCtrl.allowsEditing = NO;
videoPickerCtrl.videoMaximumDuration = 170;
videoPickerCtrl.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];

编辑:

我无法找到解决方案,所以我制作了自己的自定义视频选择器控制器。希望其他人能发现它有用: https://github.com/saliksyed/CustomVideoCapture

5 个答案:

答案 0 :(得分:0)

当用户点按按钮时您不会收到通知,但您可以提供自己的录制按钮:设置图像选择器以隐藏其标准控件(showsCameraControls)并提供自定义叠加视图({{1 }})。在该叠加层视图中,放置一个连接到目标/操作的自定义按钮,并在操作方法中调用cameraOverlayView

答案 1 :(得分:0)

好。所以我很确定我想要达到的目标是不可能的。我将使用AVFoundation作为后端为视频重新创建标准的UIImagePickerController接口。希望一旦完成,我会将它发布在github或其他东西上。

答案 2 :(得分:0)

我使用自定义叠加视图创建了您正在寻找的相同效果。

您需要使用UIVideoEditorController方法创建一个videoPath UIImagePickerControllerMediaURLuserInfo属性imagePickerController:didFinishPickingMediaWithInfo:属性{{1}}实例的模态窗口处理。

HTH

答案 3 :(得分:0)

对于其他任何人,如果您在UIImagePickerController上使用自定义叠加层视图,则可以执行此操作。只需将所需的所有控件添加到视图中,然后将该父视图设置为属性cameraOverlayView

答案 4 :(得分:0)

在一个完美的世界中,你希望Apple只提供几个能够做到这一点的代表。例如:

  • (void)imagePickerControllerDidStartVideoCapturing:(UIImagePickerController *)picker
  • (void)imagePickerControllerDidStopVideoCapturing:(UIImagePickerController *)picker

然而现实(根据苹果文档)是:

  • UIImagePickerController的协议太基础了
  • 此类旨在按原样使用,不支持子类化
  • 此类的视图层次结构是私有的,不得修改

文档还指出:“您可以为cameraOverlayView属性分配自定义视图,并使用该视图显示其他信息或管理相机界面与代码之间的交互”。

在我的应用程序中,我需要提供“UIProgressView”来指示视频可以记录多长时间。为了实现这一点,我需要能够检测视频捕获开始的那一刻。

我不想禁用原生相机控制,因为它们很酷而且我很懒,所以我不想花很多时间重新发明轮子。我所需要的只是捕捉到一个巨大的红色按钮被点击以开始或停止录制的事实。

我的解决方案是使用自定义视图“覆盖”原始的“开始/停止”录制按钮,并启用该视图的用户互动,如下所示:

overlayView = [[UIView alloc] initWithFrame:self.view.frame];

// Start/ Stop fake button
UIView *ssView = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.size.width / 2 - 35, self.view.frame.size.height - 71, 70, 70)];
[ssView setUserInteractionEnabled:YES];

// Background color below is only there to make sure my pseudo-button overlaps native Start/Stop button. Comment out the line below to leave it transparent
[ssView setBackgroundColor:[UIColor colorWithRed:0 green:1 blue:0 alpha:0.5f]];

UITapGestureRecognizer *t = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
[ssView addGestureRecognizer:t];

[overlayView addSubview:ssView];  

// My own progress bar
UIProgressView *p = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
[p setTintColor:[UIColor redColor]];
[p setCenter:CGPointMake(30, 130)];
[p setTransform:CGAffineTransformMakeRotation( M_PI / 2 )];
[p setProgress:0];

[overlayView addSubview:p];

pickerController.cameraOverlayView = overlayView;

然后,我按照以下步骤定义了一个tap的事件处理程序:

-(void)tapped:(id)sender {

    if (isRecording) {
        [pickerController stopVideoCapture];
        NSLog(@"Video capturing stopped...");
        // add your business logic here ie stop updating progress bar etc...
        [pickerController.cameraOverlayView setHidden:YES];
        isRecording = NO;
        return;
    }

    if ([pickerController startVideoCapture]) {
        NSLog(@"Video capturing started...");
        // add your business logic here ie start updating progress bar etc...
        isRecording = YES;
    }

}

接口文件的完整代码:

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

@interface ViewController : UIViewController <UIImagePickerControllerDelegate>
- (IBAction)openCamera:(id)sender;

@end

实施档案:

#import "ViewController.h"

@interface ViewController () {
    UIImagePickerController *pickerController;
    UIView* overlayView;
    BOOL isRecording;
}

@end

@implementation ViewController

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

    isRecording = NO;

    pickerController = [[UIImagePickerController alloc] init];
    pickerController.delegate = self;
    pickerController.allowsEditing = NO;
    pickerController.videoMaximumDuration = 30.0f;
    pickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
    pickerController.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];

    // I want default controls be available here...
    pickerController.showsCameraControls = YES;

    overlayView = [[UIView alloc] initWithFrame:self.view.frame];

    // Start/ Stop fake button
    UIView *ssView = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.size.width / 2 - 35, self.view.frame.size.height - 71, 70, 70)];
    [ssView setUserInteractionEnabled:YES];
    // Background color below is only there to make sure myt pseudo-button overlaps native Start/Stop button
    [ssView setBackgroundColor:[UIColor colorWithRed:0 green:1 blue:0 alpha:0.5f]];

   UITapGestureRecognizer *t = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
   [ssView addGestureRecognizer:t];

   [overlayView addSubview:ssView];

   // My own progress bar
   UIProgressView *p = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
   [p setTintColor:[UIColor redColor]];
   [p setCenter:CGPointMake(30, 130)];
   [p setTransform:CGAffineTransformMakeRotation( M_PI / 2 )];
   [p setProgress:0];

   [overlayView addSubview:p];

   pickerController.cameraOverlayView = overlayView;

}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    // Cancel button tapped
    [picker dismissViewControllerAnimated:YES completion:nil];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {

    NSLog(@"Got image : %@", info);
    [picker dismissViewControllerAnimated:YES completion:nil];

    // Do something with video captured
}

-(void)tapped:(id)sender {

    if (isRecording) {
        [pickerController stopVideoCapture];
        NSLog(@"Video capturing stopped...");
        // add your business logic here ie stop updating progress bar etc...
        [pickerController.cameraOverlayView setHidden:YES];
        isRecording = NO;
        return;
    }

    if ([pickerController startVideoCapture]) {
        NSLog(@"Video capturing started...");
        // add your business logic here ie start updating progress bar etc...
        isRecording = YES;
    }

}

- (IBAction)openCamera:(id)sender {
    [pickerController.cameraOverlayView setHidden:NO];
    [self presentViewController:pickerController animated:YES completion:nil];    
}
@end

您可能已经注意到,一旦视频捕获停止,我就会隐藏cameraOverlayView。

[pickerController.cameraOverlayView setHidden:YES];

这是为了让“重拍/播放和使用”原生控件在录制视频后正常工作。