【问题标题】:How to detect when user has hit "Record" button in UIImagePickerController?如何检测用户何时点击 UIImagePickerController 中的“记录”按钮?
【发布时间】:2011-02-05 21:08:45
【问题描述】:

我想在用户点击 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

【问题讨论】:

    标签: iphone video uiimagepickercontroller


    【解决方案1】:

    在理想情况下,您会希望 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;
    

    然后我为点击定义了事件处理程序,如下所示:

    -(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];
    

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 是的——我试过了,但效果不太好。我希望能够在他们停止录制后播放视频/重新拍摄视频(就像使用标准控件完成的那样。如果我创建自定义覆盖视图,则无法重播视频。也许我应该只使用 AVFoundation?
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        您需要创建一个带有UIVideoEditorController 实例的模态窗口,他的videoPath 属性是您应该处理的imagePickerController:didFinishPickingMediaWithInfo: 方法中userInfo 中的UIImagePickerControllerMediaURL 键。

        HTH

        【讨论】:

          【解决方案5】:

          对于其他任何人,如果您在UIImagePickerController 上使用自定义叠加视图,则可以做到这一点。只需将您想要的所有控件添加到视图,然后将该父视图设置为属性cameraOverlayView

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-01
            • 2011-05-13
            • 2011-02-24
            • 1970-01-01
            相关资源
            最近更新 更多