ios - teclado - quitar tono de marcado iphone
AVFoundation, ¿cómo desactivar el sonido del obturador cuando captureStillImageAsynchronouslyFromConnection? (8)
Consulte esta publicación para obtener un tipo diferente de respuesta: capture la imagen desde el búfer de imagen. La captura de pantalla durante la vista previa del video falla
Estoy intentando capturar una imagen durante una vista previa en vivo desde la cámara, mediante AVFoundation captureStillImageAsynchronouslyFromConnection . Hasta ahora el programa funciona como se esperaba. Sin embargo, ¿cómo puedo silenciar el sonido del obturador?
La única solución alternativa posible que se me ocurre sería silenciar el sonido del iPhone cuando presionan el botón "tomar foto", y luego deshabilitarlo un segundo más tarde.
Pude hacer que esto funcionara utilizando este código en la función snapStillImage y funciona perfectamente para mí en el iPhone 5 de iOS 8.3. También confirmé que Apple no rechazará su aplicación si la usa (no rechazaron mía)
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];
Solo recuerda ser amable y no silenciarlo cuando tu aplicación vuelva.
También puede tomar un fotograma de una secuencia de video para capturar una imagen (sin resolución completa).
Se utiliza here para capturar imágenes a intervalos cortos:
- (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;
}
Un truco común en tales casos es averiguar si el marco invoca un determinado método para este evento, y luego sobrescribir ese método temporalmente, anulando así su efecto.
Lo siento, pero no soy lo suficientemente bueno como para decirte de inmediato si eso funciona en este caso. Puede probar el comando "nm" en los ejecutables del marco para ver si hay una función con nombre que tenga un nombre adecuado, o usar gdb con el simulador para rastrear a dónde va.
Una vez que sepa qué sobrescribir, existen esas funciones de despacho ObjC de bajo nivel que puede usar para redirigir la búsqueda de funciones, creo. Creo que lo he hecho una vez hace un tiempo, pero no puedo recordar los detalles.
Con suerte, puede usar mis sugerencias para buscar algunas soluciones a Google. Buena suerte.
Utilicé este código una vez para capturar el sonido del obturador predeterminado de iOS (aquí hay una lista de nombres de archivos de sonido 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];
Luego usé una aplicación de terceros para extraer photoShutter.caf
del directorio Documentos (DiskAid para Mac). El siguiente paso abrí photoShutter.caf
en el editor de audio de Audacity y apliqué el efecto de inversión, se ve así en el zoom alto:
Luego photoShutter2.caf
este sonido como photoShutter2.caf
e intenté reproducir este sonido justo antes de 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:
...
¡Y esto realmente funciona! Realizo la prueba varias veces, cada vez que no escucho ningún sonido del obturador :)
Puede obtener un sonido ya invertido, capturado en iPhone 5S iOS 7.1.1 desde este enlace: https://www.dropbox.com/s/1echsi6ivbb85bv/photoShutter2.caf
Vivo en Japón, así que no puedo silenciar el audio cuando tomamos fotos por razones de seguridad. En el vídeo, sin embargo, el audio se apaga. No entiendo porque
La única forma de tomar una foto sin el sonido del obturador es mediante AVCaptureVideoDataOutput o AVCaptureMovieFileOutput. Para analizar la imagen fija AVCaptureVideoDataOutput es la única manera. En código de ejemplo 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);
En mi 3GS es muy pesado cuando configuro CMTimeMake (1, 1); // Un cuadro por segundo.
En el código de muestra de WWDC 2010, FindMyiCone, encontré el siguiente código,
[output setAlwaysDiscardsLateVideoFrames:YES];
Cuando se utiliza esta API, no se concede el tiempo, pero la API se llama de forma secuencial. Yo esta es la mejor solución.
Método 1: No estoy seguro de si esto funcionará, pero intente reproducir un archivo de audio en blanco justo antes de enviar el evento de captura.
Para reproducir un clip, agregue el marco de la Audio Toolbox
, #include <AudioToolbox/AudioToolbox.h>
y reproduzca el archivo de audio como este inmediatamente antes de tomar la foto:
NSString *path = [[NSBundle mainBundle] pathForResource:@"blank" ofType:@"wav"];
SystemSoundID soundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
AudioServicesPlaySystemSound(soundID);
Aquí hay un archivo de audio en blanco si lo necesita. http://cl.ly/3cKi
________________________________________________________________________________________________________________________________________
Método 2: También hay una alternativa si esto no funciona. Mientras no necesite una buena resolución, puede capturar un fotograma de la transmisión de video , evitando así el sonido de la imagen por completo.
________________________________________________________________________________________________________________________________________
Método 3: Otra forma de hacer esto sería tomar una "captura de pantalla" de su aplicación. Hacerlo de esta forma:
UIGraphicsBeginImageContext(self.window.bounds.size);
[self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(image);
[data writeToFile:@"foo.png" atomically:YES];
Si quieres que esto llene toda la pantalla con una vista previa del flujo de video para que tu captura de pantalla se vea bien:
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];