ios - AVFoundation, how to turn off the shutter sound when captureStillImageAsynchronouslyFromConnection?

ID : 5669

viewed : 175

Tags : iosiphonecocoa-touchcameraavfoundationios

Top 5 Answer for ios - AVFoundation, how to turn off the shutter sound when captureStillImageAsynchronouslyFromConnection?

vote vote


I used this code once to capture iOS default shutter sound (here is list of sound file names

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

Then I used third-party app to extract photoShutter.caf from Documents directory (DiskAid for Mac). Next step I opened photoShutter.caf in Audacity audio editor and applied inversion effect, it looks like this on high zoom:

enter image description here

Then I saved this sound as photoShutter2.caf and tried to play this sound right before 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: ... 

And this really works! I runs test several times, every time I hear no shutter sound :)

You can get already inverted sound, captured on iPhone 5S iOS 7.1.1 from this link:

vote vote


My Solution in Swift

When you call AVCapturePhotoOutput.capturePhoto method to capture an image like the below code.

photoOutput.capturePhoto(with: self.capturePhotoSettings, delegate: self) 

AVCapturePhotoCaptureDelegate methods will be invoked. And the system tries to play shutter sound after willCapturePhotoFor invoked. So you can dispose of system sound in willCapturePhotoFor method.

enter image description here

extension PhotoCaptureService: AVCapturePhotoCaptureDelegate {      func photoOutput(_ output: AVCapturePhotoOutput, willCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) {         // dispose system shutter sound         AudioServicesDisposeSystemSoundID(1108)     } } 

See also

vote vote


Method 1: Not sure if this will work, but try playing a blank audio file right before you send the capture event.

To play a clip, add the Audio Toolbox framework, #include <AudioToolbox/AudioToolbox.h> and play the audio file like this immediately before you take the picture:

 NSString *path = [[NSBundle mainBundle] pathForResource:@"blank" ofType:@"wav"];  SystemSoundID soundID;  NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];  AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);  AudioServicesPlaySystemSound(soundID); 

Here is a blank audio file if you need it.


Method 2: There's also an alternative if this doesn't work. As long as you don't need to have a good resolution, you can grab a frame from the video stream, thus avoiding the picture sound altogether.


Method 3: Another way to do this would be to take a "screenshot" of your application. Do it this way:

UIGraphicsBeginImageContext(self.window.bounds.size); [self.window.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); NSData * data = UIImagePNGRepresentation(image); [data writeToFile:@"foo.png" atomically:YES]; 

If you're wanting this to fill the whole screen with a preview of the video stream so that your screenshot looks good:

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


I was able to get this to work by using this code in the snapStillImage function and it works perfectly for me on iOS 8.3 iPhone 5. I have also confirmed that Apple won't reject your app if you use this (they didn't reject mine)

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

Just remember to be nice and unmute it when your app returns!

vote vote


I live in in Japan, so I can not mute the audio when we take photos for security reason. In video, however audio turns off. I don't understand why.

The only way I take a photo without shutter sound is using AVCaptureVideoDataOutput or AVCaptureMovieFileOutput. For analyze still image AVCaptureVideoDataOutput is only way. In AVFoundatation sample code,

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); 

In my 3GS it is very heavy when I set CMTimeMake(1, 1); // One frame per second.

In WWDC 2010 Sample code, FindMyiCone, I found following code,

[output setAlwaysDiscardsLateVideoFrames:YES]; 

When this API is used, the timing is not granted, but API is called sequentially. I this it is best solutions.

Top 3 video Explaining ios - AVFoundation, how to turn off the shutter sound when captureStillImageAsynchronouslyFromConnection?