I am trying to capture an image during a live preview from the camera, by AVFoundation captureStillImageAsynchronouslyFromConnection. So far the program works as expected. However, how can I mute the shutter sound?
-
I don't think that is possible. Even if it is it shouldn't be. There could be some user privacy infringement problems for that. – nacho4d Dec 09 '10 at 18:09
-
What are the "user privacy infringement problems"? Now the user can turn off the shutter sound anytime by the hardware mute switch. What I want is a way to turn off the sound independent of the hardware mute switch setting. – ohho Dec 10 '10 at 02:20
-
6In Japan for example you can't do that. There the shutter sound always plays even if you muted the phone. (Some weird rules to prevent privacy infringement, aka upskirt photography are in place in Japan as far as i know) So I don't think there is a way to do that. – Dunkelstern Dec 16 '10 at 15:28
-
3Yeah, it might be that your iPhone doesn't allow for muted camera shots. I'm in the US and my iPhone doesn't make a sound when I take a picture with the phone muted; my girlfriend's, on the other hand, does make a sound (hers is from Korea). – donkim Dec 18 '10 at 02:05
-
5To be clear, this is a solution for when the phone is not muted / vibrate mode. In that mode, no sound is made when taking a picture. – New Alexandria May 23 '14 at 17:50
-
32@NewAlexandria I heard in Japan shutter sounds in vibration mode too. This is law requirement. – k06a May 23 '14 at 19:30
-
3Btw AudioServicesPlaySystemSound will not play if device is muted. So Japanese devices will still make a sound when muted, but not when non-muted... – Filip Radelic May 23 '14 at 23:27
9 Answers
I used this code once to capture iOS default shutter sound (here is list of sound file names 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];
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:
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: https://www.dropbox.com/s/1echsi6ivbb85bv/photoShutter2.caf

- 17,755
- 10
- 70
- 110
-
Awesome hack! I wonder if this trick could also be used to suppress the UIPickerView sound, which can't be disabled through a public API: http://stackoverflow.com/q/1441849/214070 – bugloaf May 23 '14 at 18:16
-
105Very cool. Only caveat is that when flash is turned on, this will result in a double shutter sound because the default system sound is not played when captureStillImageAsynchronouslyFromConnection: is called, but rather when image is actually captured (during flash sequence). Instead add a key-value observer on self.stillImageOutput for keyPath 'capturingStillImage' to detect when capture truly starts, then play inverse sound in callback method. – Jeff Mascia May 23 '14 at 23:20
-
17This is how modern military aircraft defeat radar. This is why you don't see the "stealth shape" silhouette on new fighter designs: There is an electronics package that handles what is basically a radar-defeating phase shift that broadcasts an "inverted" (phase-shifted) duplicate signal. – L0j1k May 24 '14 at 02:43
-
5@L0j1k: It depends on what kind of stealth ship you are talking about. The F22 an ilk aren't interested in being undetected but in being unlockable. Problem with phase shift technology is you are incredibly obvious from every other position, since they won't see the same shift. – Guvante May 24 '14 at 03:05
-
14This is how noise-cancelling headphones work, except they capture the sound in realtime – Daniel Serodio May 24 '14 at 03:19
-
1I'm wondering how this achieves sample accurate overlap of two waves. AFAIK, even if it's a single sample off, the cancelation won't be perfect. – notthetup Jun 02 '14 at 08:18
-
This will probably be a good way to get rejected from the app store, once Apple catches on. – nobody Jun 09 '14 at 18:20
-
4This was great for iOS7, but it no longer works on iOS8, any idea how to solve this on iOS8 ? – Ticko Oct 28 '14 at 11:32
-
@kO6a:yeah, Its not working on iOS8 devices. Please give some solution. – V-Xtreme Nov 18 '14 at 03:51
-
@Ticko did you used attached audio file from my dropbox or inverted your own? iOS8 may have changed sound or/and random sleep before shutter sound... – k06a Nov 19 '14 at 10:39
-
2This works fine while capturing single image not for multiple, I have implemented burst mode, and capturing 5 images within 1.5 sec, so using above logic camera shutter sound doesn't get suppress. – iLearner May 20 '15 at 10:59
-
3Still works on iOS 8. This is the Swift code if anyone wants it: `if let soundURL = NSBundle.mainBundle().URLForResource("photoShutter2", withExtension: "caf") { var mySound: SystemSoundID = 0 AudioServicesCreateSystemSoundID(soundURL, &mySound) AudioServicesPlaySystemSound(mySound); }` – Sam Oct 28 '15 at 13:17
-
-
@iLearner If you need to mute the sound while taking *BURST* photos, you can do it at a slight quality loss using this method: http://stackoverflow.com/a/9672242/2057171 ——— I've edited this into the question for future readers O:) – Albert Renshaw Apr 22 '16 at 17:23
-
@AlbertRenshaw you added link to this answer with solution that you can find anywhere: just capturing frames from video. Sorry, I've removed this link from answer – I think this solution is enough wide-popular to be found in google or SO. – k06a Apr 23 '16 at 18:12
-
@AlbertRenshaw You can record and invert several sounds and use concrete sound for concrete iOS version. iOS7, iOS8, iOS9 have same sound :) – k06a Apr 23 '16 at 19:26
-
Yes but if Apple changes the sound in say iOS 10, this could be bad for apps capturing say 60 frames a second, with shutter sounds going off 60 times a second and also an invert of the old sound also going off 60 times a second. @k06a – Albert Renshaw Apr 23 '16 at 21:24
-
@AlbertRenshaw sure, but app developers will have 3-5 months to adopt their apps to new iOS version. Hope it will be named iOS X :) – k06a Apr 23 '16 at 21:44
-
This answer simply not true. Tried it with iOS 9.3 and iPhone 6+ and it's not working. – raven99 May 10 '16 at 13:13
-
1@raven99 Apple may change sound in any future version of iOS. Any 5ms latency in audio playback can break all magic. This method is not production-ready I think. This is about tricking and fun :) – k06a May 10 '16 at 15:13
-
@k06a I am using AVCapturePhotoCaptureDelegate methods in which method i should put this code to disable shutter sound? I have tried by adding this code in "didCapturePhotoForResolvedSettings" method but its not working. any help? – Satish Mavani May 17 '17 at 10:21
-
@SatishMavani I wrote it right before `captureStillImageAsynchronouslyFromConnection:` method call. Not sure this method will work on all iOS versions because it needs very high precision of synchronization of sound playback and image capturing... – k06a May 17 '17 at 10:27
-
@k06a captureStillImageAsynchronouslyFromConnection: is deprecated now and there is no such method i can find with AVCapturePhotoCaptureDelegate, can you help with any other solution? – Satish Mavani May 17 '17 at 10:30
-
As of XCode 9.3 using AVCapturePhotoCaptureDelegate this does not work. The photoOutput(_:willCapturePhotoFor:) documentation says "The photo output calls this method as close as possible to the initial moment of capture. If the shutter sound is enabled, this call occurs immediately after the photo output begins playing the shutter sound." Both this method and the photoOutput(_:willBeginCaptureFor:) method do not align with the shutter sound begin event. – Glavid Apr 18 '18 at 20:27
-
@Glavid awesome, after 4 years they finally made protection from this trick. – k06a Apr 19 '18 at 08:36
-
3Works like a charm! I'm playing it in the delegate callback `photoOutput(:willCapturePhotoFor:)`. Also got this working on iOS 11.3.1 built with Xcode 9.3.1 – silicon_valley May 26 '18 at 17:56
-
Not working for me on iOS 11.1 ... Actually, I'm trying to achieve this in the AVCaptureMetadataOutputObjectsDelegate as my requirement is when scanning is done then I need to capture the photo of the scanned barcode. Can you please help me how I can achieve the above mentioned feature. – iGW Jul 03 '18 at 05:21
-
1@iGW try to do it in `photoOutput(:willCapturePhotoFor:)` like @silicon_valley suggested in the previous comment, it seems it working for him even in 11.3.1. – k06a Jul 04 '18 at 05:55
-
I applied the solution suggested by @silicon_valley and on clicking camera icon many times 1-2 out of 10 gave shutter sound. Also as per my requirements as I already mentioned in my previous comment that :- On getting barcode result inside - didOutputMetadataObjects I just need to click the photo of the scanned barcode at the same time and save that result along with the image in Core data. – iGW Jul 06 '18 at 06:35
-
Currently , I'm reading the barcode with the help of AVCaptureMetadataOutputObjectsDelegate and used captureStillImageAsynchronously method to capture image inside this delegate. Hoping I could able to explain my requirement properly. – iGW Jul 06 '18 at 07:16
-
This method actually works. However, it is necessary to pay attention to the following points. - Play a shutter sound even when the device is muted or connected to headphones - Ringing the shutter sound exactly at the same time as a real shutter sound – shtnkgm Nov 11 '18 at 05:25
-
@Glavid I was able to make it work on iPhone 10's by adding a small delay (of 0.02 seconds) to when i play the sound, doing it like this seems to be working for me – Quinn Mar 06 '19 at 19:31
-
1Scratch my previous comment, it works like 99% of the time with the delay but sometimes the sound will happen :( – Quinn Mar 06 '19 at 19:48
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.
extension PhotoCaptureService: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, willCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) {
// dispose system shutter sound
AudioServicesDisposeSystemSoundID(1108)
}
}
See also

- 1,107
- 9
- 16
-
5This is a beautiful solution and it works perfectly. Great answer too. Thanks @kyle – Warpling Mar 21 '19 at 22:57
-
1This is perfectly work. If you need to separate silent mode and normal mode, Use AudioServicesPlaySytemSoundID(1108) reversely. Thank you. – MJ Studio Apr 10 '19 at 05:05
-
1It works! I want to know if you have any trouble uploading to AppStore with such a method? – Liew Jun Tung Nov 22 '19 at 10:03
-
3@LiewJunTung No trouble with this solution. I already uploaded apps with this solution. There are a lot of apps that used this kind of solution. Happy coding. – Won Nov 23 '19 at 04:25
-
I have discovered a problem. I am wondering if you have discovered this problem. It's basically a memory leak that only happens when `AudioServicesDisposeSystemSoundID(1108)` is called. Do you have any solutions for this? :) – Liew Jun Tung Dec 12 '19 at 01:38
-
You don't need to separate silent to normal mode @MJStudio. Set the Category of AVAudioSession.sharedInstance() to .soloAmbient. It that way your audio is silenced by screen locking and by the Silent switch – gafos May 28 '20 at 21:43
-
2This answer usually works, but it creates a race condition dependent on system load. Sometimes, iOS doesn't get around to calling `photoOutput` until after part of the shutter sound has been played. – Edward Brey Oct 01 '20 at 17:20
-
@Won Thanks for the solution! I tried this and it generally works, but when I tap a button multiple times quickly, it still plays a short sound... Does this happen to you all?? – Yuuu Aug 17 '22 at 03:39
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. https://d1sz9tkli0lfjq.cloudfront.net/items/0Y3Z0A1j1H2r1c0z3n3t/blank.wav
________________________________________________________________________________________________________________________________________
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];

- 37,241
- 25
- 195
- 267

- 29,408
- 19
- 102
- 161
-
2I don't think that would work, it would just play a "blank" sound while the shutter noise plays. Its quite possible to play 2 sounds at the same time. The other 2 methods seem workable! – Linuxmint Dec 13 '10 at 22:46
-
2Give it a shot. I'm not confident it will work, but here's to hoping! – sudo rm -rf Dec 14 '10 at 05:27
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!

- 832
- 1
- 11
- 32
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.

- 59
- 1
See this post for a different kind of answer: Capture the image from the image buffer. Screen capture during video preview fails

- 1
- 1

- 6,051
- 2
- 39
- 70
You can also take a frame from a video stream to capture a (not full resolution) image.
It is used here to capture images at short intervals:
- (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;
}

- 10,792
- 3
- 58
- 102
-
Are you able to get AVCaptureVideoDataOutput to work while AVCaptureMovieFileOutput is being used? When I try to use both of them the AVCaptureVideoDataOutput's delegate methods are not called. – Paul Cezanne Aug 28 '14 at 16:56
-
The only possible work-around I can think of would be to mute the iphone sound when they press the "take picture" button, and then un-mute it a second later.

- 4,716
- 11
- 44
- 64
A common trick in such cases is to find out if the framework invokes a certain method for this event, and then to overwrite that method temporarily, thereby voiding its effect.
I'm sorry but I am not a good enough hack to tell you right away if that works in this case. You could try the "nm" command on the framework executables to see if there's a named function that has a suitatable name, or use gdb with the Simulator to trace where it goes.
Once you know what to overwrite, there are those low level ObjC dispatching functions that you can use to redirect the lookup for functions, I believe. I think I've done that once a while ago, but can't remember the details.
Hopefully, you can use my hints to google a few solutions paths to this. Good luck.

- 11,045
- 8
- 74
- 149