AVFoundation,如何captureStillImageAsynchronouslyFromConnectionclosures快门声音?
我正尝试从AVFoundation captureStillImageAsynchronouslyFromConnection的实时预览中捕捉图像。 到目前为止,该scheme按预期工作。 但是,如何使快门声音静音?
我用这个代码一次捕捉iOS默认的快门声音(这里是声音文件名称列表https://github.com/TUNER88/iOSSystemSoundsLibrary ):
NSString *path = @"/System/Library/Audio/UISounds/photoShutter.caf"; NSString *docs = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSData *data = [NSData dataWithContentsOfFile:path]; [data writeToFile:[docs stringByAppendingPathComponent:@"photoShutter.caf"] atomically:YES];
然后,我使用第三方应用程序从Documents目录(DiskAid for Mac)中提取photoShutter.caf
。 下一步,我打开Audacityaudio编辑器中的photoShutter.caf
并应用反转效果,在高变焦时看起来像这样:
然后我保存了这个声音作为photoShutter2.caf
并试图播放这个声音之前captureStillImageAsynchronouslyFromConnection
:
static SystemSoundID soundID = 0; if (soundID == 0) { NSString *path = [[NSBundle mainBundle] pathForResource:@"photoShutter2" ofType:@"caf"]; NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO]; AudioServicesCreateSystemSoundID((__bridge CFURLRef)filePath, &soundID); } AudioServicesPlaySystemSound(soundID); [self.stillImageOutput captureStillImageAsynchronouslyFromConnection: ...
这真的有用! 我跑了几次testing,每次我听不到快门声:)
你可以得到已经倒立的声音,从iPhone 5S iOS 7.1.1捕获从这个链接: https : //www.dropbox.com/s/1echsi6ivbb85bv/photoShutter2.caf
方法1:不知道这是否会工作,但在发送捕捉事件之前尝试播放空白audio文件。
要播放剪辑,请在添加Audio Toolbox
框架#include <AudioToolbox/AudioToolbox.h>
并在拍摄照片之前立即播放audio文件:
NSString *path = [[NSBundle mainBundle] pathForResource:@"blank" ofType:@"wav"]; SystemSoundID soundID; NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO]; AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID); AudioServicesPlaySystemSound(soundID);
如果你需要的话,这是一个空白的audio文件。 http://cl.ly/3cKi
________________________________________________________________________________________________________________________________________
方法2:如果这不起作用,也有一个select。 只要你不需要有一个好的分辨率,你可以从videostream中抓取一个帧 ,从而完全避免了图像的声音。
________________________________________________________________________________________________________________________________________
方法3:另一种方法是获取应用程序的“截图”。 这样做:
UIGraphicsBeginImageContext(self.window.bounds.size); [self.window.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); NSData * data = UIImagePNGRepresentation(image); [data writeToFile:@"foo.png" atomically:YES];
如果你想要这个填充整个屏幕的videostream的预览,以便您的屏幕截图看起来不错:
AVCaptureSession *captureSession = yourcapturesession; AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:captureSession]; UIView *aView = theViewYouWantTheLayerIn; previewLayer.frame = aView.bounds; // Assume you want the preview layer to fill the view. [aView.layer addSublayer:previewLayer];
我可以通过在snapStillImage函数中使用此代码来实现此function,并且在iOS 8.3 iPhone 5上完全适用于我。我还确认,如果使用此function,Apple不会拒绝您的应用程序(它们不会拒绝矿)
MPVolumeView* volumeView = [[MPVolumeView alloc] init]; //find the volumeSlider UISlider* volumeViewSlider = nil; for (UIView *view in [volumeView subviews]){ if ([view.class.description isEqualToString:@"MPVolumeSlider"]){ volumeViewSlider = (UISlider*)view; break; } } // mute it here: [volumeViewSlider setValue:0.0f animated:YES]; [volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
只要记住当你的应用程序返回时很好,并取消静音!
我住在日本,所以出于安全原因拍照时,我不能将audio静音。 在video中,audioclosures。 我不明白为什么。
拍摄没有快门声的照片的唯一方法是使用AVCaptureVideoDataOutput或AVCaptureMovieFileOutput。 对于分析静止图像AVCaptureVideoDataOutput是唯一的方法。 在AVFoundatation示例代码中,
AVCaptureVideoDataOutput *output = [[[AVCaptureVideoDataOutput alloc] init] autorelease]; // If you wish to cap the frame rate to a known value, such as 15 fps, set // minFrameDuration. output.minFrameDuration = CMTimeMake(1, 15);
在我的3GS中,当我设置CMTimeMake(1,1)时,它非常重。 //每秒一帧
在WWDC 2010示例代码FindMyiCone中,我发现了以下代码,
[output setAlwaysDiscardsLateVideoFrames:YES];
当使用这个API时,时序不被授权,但API被顺序地调用。 我这是最好的解决scheme。
您也可以从videostream中获取一帧来拍摄(而不是全分辨率)图像。
它在这里用于短时间间隔捕获图像:
- (IBAction)startStopPictureSequence:(id)sender { if (!_capturingSequence) { if (!_captureVideoDataOutput) { _captureVideoDataOutput = [AVCaptureVideoDataOutput new]; _captureVideoDataOutput.videoSettings = @{(NSString *)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)}; [_captureVideoDataOutput setSampleBufferDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)]; if (_sequenceCaptureInterval == 0) { _sequenceCaptureInterval = 0.25; } } if ([_captureSession canAddOutput:_captureVideoDataOutput]) { [_captureSession addOutput:_captureVideoDataOutput]; _lastSequenceCaptureDate = [NSDate date]; // Skip the first image which looks to dark for some reason _sequenceCaptureOrientation = (_currentDevice.position == AVCaptureDevicePositionFront ? // Set the output orientation only once per sequence UIImageOrientationLeftMirrored : UIImageOrientationRight); _capturingSequence = YES; } else { NBULogError(@"Can't capture picture sequences here!"); return; } } else { [_captureSession removeOutput:_captureVideoDataOutput]; _capturingSequence = NO; } } - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { // Skip capture? if ([[NSDate date] timeIntervalSinceDate:_lastSequenceCaptureDate] < _sequenceCaptureInterval) return; _lastSequenceCaptureDate = [NSDate date]; UIImage * image = [self imageFromSampleBuffer:sampleBuffer]; NBULogInfo(@"Captured image: %@ of size: %@ orientation: %@", image, NSStringFromCGSize(image.size), @(image.imageOrientation)); // Execute capture block dispatch_async(dispatch_get_main_queue(), ^ { if (_captureResultBlock) _captureResultBlock(image, nil); }); } - (BOOL)isRecording { return _captureMovieOutput.recording; }
看到这个post的不同types的答案:从图像缓冲区捕获图像。 video预览期间的屏幕截图失败
唯一可能的解决办法,我可以想到的是,当他们按下“拍照”button,然后取消静音一秒钟后,静音iPhone的声音。
在这种情况下,一个常见的技巧就是找出框架是否为这个事件调用某个方法,然后暂时覆盖该方法,从而消除它的效果。
我很抱歉,但如果在这种情况下工作,我不是马上就告诉你。 您可以在框架可执行文件上尝试“nm”命令来查看是否存在具有适合名称的命名函数,或者在模拟器中使用gdb来跟踪它的位置。
一旦你知道要覆盖什么,我相信有一些低级的ObjC调度函数可以用来redirect函数的查找。 我想我以前曾经这样做过,但不记得细节。
希望你可以使用我的提示谷歌几个解决scheme的path。 祝你好运。