Камеры мобильных устройств Android/iOS/etc. при фотосъёмке издают характерный звук срабатывания затвора. В некоторых странах это требуется законодательно. Но что делать, если нашей программе нужно всё-таки беззвучно снять фотографию, пусть даже незаметно для пользователя? Такой способ есть.
Пользователь Хабрахабра k06a (Антон Буков) на Stackoverflow предложил универсальный способ, который должен работать на всех платформах. Он предлагает использовать активное шумоподавление, то есть инвертировать звук и запустить инвертированную копию непосредственно перед оригинальной. Мы получаем абсолютно беззвучную фотосъёмку!
k06a объясняет на примере iOS.
1. Записываем системный звук затвора. Пути, по которым звуки лежат в файловой системе, можно посмотреть в коде iOSSystemSoundsLibrary.
2. Извлекаем файл
3. Открываем
4. Сохраняем получившийся звук в iOS и запускаем непосредственно перед
Антон уверяет, что работает отлично.
Если что, то уже инвертированный
Пользователь Хабрахабра k06a (Антон Буков) на Stackoverflow предложил универсальный способ, который должен работать на всех платформах. Он предлагает использовать активное шумоподавление, то есть инвертировать звук и запустить инвертированную копию непосредственно перед оригинальной. Мы получаем абсолютно беззвучную фотосъёмку!
k06a объясняет на примере iOS.
1. Записываем системный звук затвора. Пути, по которым звуки лежат в файловой системе, можно посмотреть в коде 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];
2. Извлекаем файл
photoShutter.caf
из папки Documents, можно использовать DiskAid for Mac.3. Открываем
photoShutter.caf
в звуковом редакторе (Audacity) и применяем инвесрсию.4. Сохраняем получившийся звук в iOS и запускаем непосредственно перед
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:
...
Антон уверяет, что работает отлично.
Если что, то уже инвертированный
photoShutter2.caf
можно взять здесь (зеркало).