Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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. Thanks!

share|improve this question
1  
In 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
3  
Yeah, 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 2:05
5  
To 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 2 days ago
25  
@NewAlexandria I heard in Japan shutter sounds in vibration mode too. This is law requirement. –  k06a 2 days ago
3  
Btw 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 2 days ago
show 2 more comments

5 Answers

up vote 1295 down vote
+100

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:

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: https://www.dropbox.com/s/1echsi6ivbb85bv/photoShutter2.caf

share|improve this answer
4  
What's wrong with this answer? stackoverflow.com/a/14063081/149533 –  Nestor 2 days ago
63  
Very 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. –  jm333 2 days ago
6  
This 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 yesterday
3  
@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 yesterday
5  
This is how noise-cancelling headphones work, except they capture the sound in realtime –  Daniel Serodio yesterday
show 1 more comment

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. http://cl.ly/3cKi

__________________________________________________________________________________

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];
share|improve this answer
    
I 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
    
I tried playing a background sound by [[AVAudioPlayer alloc] initWithContentsOfURL:soundURL error:nil], the shutter sound overlaps with the background sound. I will try AudioServicesPlaySystemSound too... thanks. –  ohho Dec 14 '10 at 0:56
1  
Give it a shot. I'm not confident it will work, but here's to hoping! –  sudo rm -rf Dec 14 '10 at 5:27
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment

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.

share|improve this answer
    
How to mute the iPhone sound programmatically? Thanks! –  ohho Dec 10 '10 at 0:55
    
even if you could, Apple wouldn't approve that –  user207616 Dec 19 '10 at 11:59
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.