在一個完美的世界裏,你會希望蘋果提供只是一對夫婦的代表,將做到這一點的。例如:
- (無效)imagePickerControllerDidStartVideoCapturing:(的UIImagePickerController *)選擇器
- (無效)imagePickerControllerDidStopVideoCapturing:(的UIImagePickerController *)選擇器
現實然而(按照蘋果文檔)是:
- 針對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
Implementati on file:
#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];
這是爲了讓「重拍/播放和使用」本地控制工作視頻錄製結束後正常。
是的 - 我試過這個,但它不工作。我希望能夠在停止錄製後重放視頻/重新錄製視頻(就像使用標準控件一樣,如果我創建自定義重疊視圖,則無法重放視頻,也許我應該只使用AVFoundation? – user491880 2011-02-07 22:28:06