[ios] AVFoundation, captureStillImageAsynchronouslyFromConnection시 셔터 소리를 끄는 방법은 무엇입니까?

AVFoundation captureStillImageAsynchronouslyFromConnection에 의해 카메라에서 라이브 미리보기 중에 이미지를 캡처하려고합니다 . 지금까지 프로그램은 예상대로 작동합니다. 그러나 어떻게 셔터 음을 음소거 할 수 있습니까?



답변

이 코드를 한 번 사용하여 iOS 기본 셔터 사운드를 캡처했습니다 (여기에 사운드 파일 이름 목록 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];

그런 다음 타사 앱을 사용 photoShutter.caf하여 Documents 디렉토리 (Mac 용 DiskAid)에서 추출 했습니다. 다음 단계 photoShutter.caf는 Audacity 오디오 편집기에서 열고 반전 효과를 적용했습니다. 높은 확대 / 축소에서 다음과 같이 보입니다.

여기에 이미지 설명 입력

그런 다음이 사운드를로 저장 photoShutter2.caf하고 바로 전에이 사운드를 재생 해 보았습니다 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:
...

그리고 이것은 정말로 작동합니다! 셔터 소리가 들리지 않을 때마다 테스트를 여러 번 실행합니다. 🙂

다음 링크에서 iPhone 5S iOS 7.1.1에서 캡처 한 이미 반전 된 사운드를 얻을 수 있습니다. https://www.dropbox.com/s/1echsi6ivbb85bv/photoShutter2.caf


답변

Swift의 내 솔루션

AVCapturePhotoOutput.capturePhoto아래 코드와 같이 이미지를 캡쳐하기 위해 메소드를 호출 할 때 .

photoOutput.capturePhoto(with: self.capturePhotoSettings, delegate: self)

AVCapturePhotoCaptureDelegate 메서드가 호출됩니다. 그리고 시스템은 willCapturePhotoFor호출 된 후 셔터 소리를 재생하려고합니다 . 따라서 시스템 사운드를 willCapturePhotoFor방법으로 처리 할 수 ​​있습니다 .

여기에 이미지 설명 입력

extension PhotoCaptureService: AVCapturePhotoCaptureDelegate {

    func photoOutput(_ output: AVCapturePhotoOutput, willCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) {
        // dispose system shutter sound
        AudioServicesDisposeSystemSoundID(1108)
    }
}

또한보십시오


답변

방법 1 : 이것이 작동하는지 확실하지 않지만 캡처 이벤트를 보내기 직전에 빈 오디오 파일을 재생 해보십시오.

클립을 재생하려면 Audio Toolbox프레임 워크를 추가 하고 사진을 찍기 직전 에 다음 #include <AudioToolbox/AudioToolbox.h>
과 같은 오디오 파일을 재생합니다 .

 NSString *path = [[NSBundle mainBundle] pathForResource:@"blank" ofType:@"wav"];
 SystemSoundID soundID;
 NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
 AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
 AudioServicesPlaySystemSound(soundID);

필요한 경우 여기에 빈 오디오 파일이 있습니다.
https://d1sz9tkli0lfjq.cloudfront.net/items/0Y3Z0A1j1H2r1c0z3n3t/blank.wav

________________________________________________________________________________________________________________________________________

방법 2 : 이것이 작동하지 않는 경우 대안이 있습니다. 좋은 해상도가 필요하지 않은 한 비디오 스트림에서 프레임을 가져 와서 사진 소리를 완전히 피할 수 있습니다.

________________________________________________________________________________________________________________________________________

방법 3 : 이 작업을 수행하는 또 다른 방법은 응용 프로그램의 “스크린 샷”을 찍는 것입니다. 다음과 같이하십시오.

UIGraphicsBeginImageContext(self.window.bounds.size);
[self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(image);
[data writeToFile:@"foo.png" atomically:YES];

스크린 샷이보기 좋게 보이도록 비디오 스트림의 미리보기로 전체 화면을 채우려면 다음을 수행하십시오.

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];


답변

snapStillImage 함수에서이 코드를 사용하여이 코드를 사용할 수 있었고 iOS 8.3 iPhone 5에서 완벽하게 작동합니다. 또한이 기능을 사용하면 Apple이 앱을 거부하지 않을 것임을 확인했습니다 (거부하지 않았습니다. 나의 것)

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];

앱이 돌아 오면 멋지게 꾸미고 음소거를 해제하세요!


답변

저는 일본에 살고 있기 때문에 보안상의 이유로 사진을 찍을 때 오디오를 음소거 할 수 없습니다. 그러나 비디오에서는 오디오가 꺼집니다. 이유를 모르겠습니다.

셔터 소리없이 사진을 찍는 유일한 방법은 AVCaptureVideoDataOutput 또는 AVCaptureMovieFileOutput을 사용하는 것입니다. 정지 이미지를 분석하려면 AVCaptureVideoDataOutput이 유일한 방법입니다. 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);

내 3GS에서는 CMTimeMake (1, 1)를 설정할 때 매우 무겁습니다. // 초당 1 프레임.

WWDC 2010 샘플 코드 FindMyiCone에서 다음 코드를 찾았습니다.

[output setAlwaysDiscardsLateVideoFrames:YES];

이 API를 사용하면 타이밍이 부여되지 않고 순차적으로 API가 호출됩니다. 나는 이것이 최고의 솔루션입니다.


답변

비디오 스트림에서 프레임을 가져와 전체 해상도가 아닌 이미지를 캡처 할 수도 있습니다.

짧은 간격으로 이미지를 캡처 하는 데 사용 됩니다 .

- (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;
}


답변

다른 종류의 답변은이 게시물을 참조하십시오. 이미지 버퍼에서 이미지를 캡처합니다. 비디오 미리보기 중 화면 캡처 실패