Ich versuche, ein Bild während einer Live-Vorschau von der Kamera mit AVFoundation captureStillImageAsynchronouslyFromConnection aufzunehmen . Bisher funktioniert das Programm wie erwartet. Wie kann ich jedoch den Auslöserton stumm schalten?
Ich versuche, ein Bild während einer Live-Vorschau von der Kamera mit AVFoundation captureStillImageAsynchronouslyFromConnection aufzunehmen . Bisher funktioniert das Programm wie erwartet. Wie kann ich jedoch den Auslöserton stumm schalten?
Antworten:
Ich habe diesen Code einmal verwendet, um den Standard-Shutter-Sound von iOS aufzunehmen (hier ist eine Liste der Sounddateinamen 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];
Dann habe ich eine Drittanbieter-App verwendet, um photoShutter.caf
aus dem Dokumentenverzeichnis (DiskAid für Mac) zu extrahieren . Der nächste Schritt, den ich photoShutter.caf
im Audacity-Audio-Editor geöffnet und den Inversionseffekt angewendet habe, sieht bei hohem Zoom folgendermaßen aus:
Dann habe ich diesen Sound als gespeichert photoShutter2.caf
und versucht, diesen Sound direkt vorher abzuspielen 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:
...
Und das funktioniert wirklich! Ich führe den Test mehrmals durch, jedes Mal, wenn ich keinen Auslöserton höre :)
Über diesen Link können Sie bereits invertierten Sound erhalten, der auf dem iPhone 5S iOS 7.1.1 aufgenommen wurde: https://www.dropbox.com/s/1echsi6ivbb85bv/photoShutter2.caf
Wenn Sie die AVCapturePhotoOutput.capturePhoto
Methode aufrufen , um ein Bild wie den folgenden Code aufzunehmen.
photoOutput.capturePhoto(with: self.capturePhotoSettings, delegate: self)
AVCapturePhotoCaptureDelegate-Methoden werden aufgerufen. Und das System versucht, den Shutter-Sound nach dem willCapturePhotoFor
Aufrufen wiederzugeben. So können Sie den Systemklang in der willCapturePhotoFor
Methode entsorgen .
extension PhotoCaptureService: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, willCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) {
// dispose system shutter sound
AudioServicesDisposeSystemSoundID(1108)
}
}
AudioServicesDisposeSystemSoundID(1108)
aufgerufen wird. Haben Sie Lösungen dafür? :)
Methode 1: nicht sicher, ob dies funktioniert. Versuchen Sie jedoch, eine leere Audiodatei abzuspielen, bevor Sie das Capture-Ereignis senden.
Um einen Clip abzuspielen, fügen Sie das Audio Toolbox
Framework hinzu #include <AudioToolbox/AudioToolbox.h>
und spielen Sie die Audiodatei unmittelbar vor der Aufnahme wie folgt ab:
NSString *path = [[NSBundle mainBundle] pathForResource:@"blank" ofType:@"wav"];
SystemSoundID soundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
AudioServicesPlaySystemSound(soundID);
Hier ist eine leere Audiodatei, wenn Sie sie brauchen. https://d1sz9tkli0lfjq.cloudfront.net/items/0Y3Z0A1j1H2r1c0z3n3t/blank.wav
________________________________________________________________________________________________________________________________________________________
Methode 2: Es gibt auch eine Alternative, wenn dies nicht funktioniert. Solange Sie keine gute Auflösung benötigen, können Sie ein Bild aus dem Videostream abrufen und so den Bildton ganz vermeiden.
________________________________________________________________________________________________________________________________________________________
Methode 3: Eine andere Möglichkeit, dies zu tun, besteht darin, einen "Screenshot" Ihrer Anwendung zu erstellen. Mach es so:
UIGraphicsBeginImageContext(self.window.bounds.size);
[self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(image);
[data writeToFile:@"foo.png" atomically:YES];
Wenn Sie möchten, dass dies den gesamten Bildschirm mit einer Vorschau des Videostreams ausfüllt, damit Ihr Screenshot gut aussieht:
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];
Ich konnte dies mithilfe dieses Codes in der Funktion snapStillImage zum Laufen bringen und es funktioniert perfekt für mich unter iOS 8.3 iPhone 5. Ich habe auch bestätigt, dass Apple Ihre App nicht ablehnt, wenn Sie dies verwenden (sie haben es nicht abgelehnt) Bergwerk)
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];
Denken Sie daran, nett zu sein und die Stummschaltung aufzuheben, wenn Ihre App zurückkehrt!
Ich lebe in Japan, daher kann ich das Audio nicht stumm schalten, wenn wir aus Sicherheitsgründen Fotos machen. In Video wird Audio jedoch ausgeschaltet. Ich verstehe nicht warum.
Die einzige Möglichkeit, ein Foto ohne Auslöserton aufzunehmen, ist die Verwendung von AVCaptureVideoDataOutput oder AVCaptureMovieFileOutput. Für die Analyse von Standbildern ist AVCaptureVideoDataOutput nur möglich. Im AVFoundatation-Beispielcode
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 meinem 3GS ist es sehr schwer, wenn ich CMTimeMake (1, 1) einstelle; // Ein Bild pro Sekunde.
Im WWDC 2010-Beispielcode FindMyiCone habe ich folgenden Code gefunden:
[output setAlwaysDiscardsLateVideoFrames:YES];
Wenn diese API verwendet wird, wird das Timing nicht gewährt, aber die API wird nacheinander aufgerufen. Ich das ist es beste Lösungen.
Sie können auch ein Bild aus einem Videostream aufnehmen, um ein Bild (nicht in voller Auflösung) aufzunehmen.
Es wird hier verwendet , um Bilder in kurzen Intervallen aufzunehmen:
- (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;
}
In diesem Beitrag finden Sie eine andere Antwort: Erfassen Sie das Bild aus dem Bildpuffer. Die Bildschirmaufnahme während der Videovorschau schlägt fehl
Die einzig mögliche Lösung, die ich mir vorstellen kann, besteht darin, den iPhone-Ton stummzuschalten, wenn sie auf die Schaltfläche "Bild aufnehmen" klicken, und ihn eine Sekunde später wieder stummzuschalten.
Ein häufiger Trick in solchen Fällen besteht darin, herauszufinden, ob das Framework eine bestimmte Methode für dieses Ereignis aufruft, und diese Methode dann vorübergehend zu überschreiben, wodurch ihre Wirkung aufgehoben wird.
Es tut mir leid, aber ich bin nicht gut genug, um Ihnen sofort zu sagen, ob das in diesem Fall funktioniert. Sie können den Befehl "nm" für die ausführbaren Framework-Dateien verwenden, um festzustellen, ob eine benannte Funktion einen geeigneten Namen hat, oder gdb mit dem Simulator verwenden, um zu verfolgen, wohin sie führt.
Sobald Sie wissen, was Sie überschreiben müssen, gibt es diese einfachen ObjC-Dispatching-Funktionen, mit denen Sie die Suche nach Funktionen umleiten können, glaube ich. Ich glaube, ich habe das schon vor einiger Zeit gemacht, kann mich aber nicht an die Details erinnern.
Hoffentlich können Sie meine Hinweise verwenden, um ein paar Lösungspfade dazu zu googeln. Viel Glück.