programing

AVFoundation, StillImageSynchronousFromConnection을 캡처할 때 셔터음을 끄는 방법?

yellowcard 2023. 9. 17. 12:13
반응형

AVFoundation, StillImageSynchronousFromConnection을 캡처할 때 셔터음을 끄는 방법?

AVFoundation capture StillImageSynchronousFromConnection을 통해 카메라에서 라이브 프리뷰를 하는 동안 이미지를 캡처하려고 합니다.지금까지는 프로그램이 예상대로 작동합니다.하지만 셔터 소리는 어떻게 음소거 할 수 있습니까?

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문서 디렉토리(DiskAid for Mac)에서.다음 단계를 열었습니다.photoShutter.cafAudacity 오디오 편집기와 적용된 반전 효과에서, 고줌에서는 다음과 같이 보입니다.

enter image description here

그 다음에 이 소리를 저장했습니다.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에서 캡처된 이미 반전된 사운드를 다음 링크에서 얻을 수 있습니다.

스위프트에서의 나의 솔루션

AVCapturePhotoOutput.capturePhoto하기 코드와 같은 이미지를 캡쳐하는 방법.

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

AVCapturePhotoCaptureDelegate 메서드가호출됩니다호출됩니다.그리고 시스템은 다음에 셔터 사운드를 재생하려고 합니다.willCapturePhotoFor④번 ⑤번 ⑥번 ⑦번에서 처리할 수 있습니다.willCapturePhotoFor방법.

enter image description here

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 아이폰 5에서 완벽하게 작동합니다.당신이 이것을 사용한다면 애플이 당신의 앱을 거부하지 않을 것이라는 것도 확인했습니다 (그들은 내 앱을 거부하지 않았습니다).

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이 유일한 방법입니다.AV Foundation 샘플 코드에서,

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 샘플 코드, Find MyiCone에서 다음 코드를 찾았습니다.

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

제가 생각할 수 있는 유일한 해결책은 "사진 찍기" 버튼을 눌렀을 때 아이폰 소리를 음소거하고 잠시 후 음소거를 해제하는 것입니다.

이 경우 일반적인 방법은 프레임워크가 이 이벤트에 대해 특정 메서드를 호출하는지 확인한 다음 해당 메서드를 일시적으로 덮어쓰므로 해당 효과를 방지하는 것입니다.

죄송하지만 이 경우에 효과가 있는지 바로 말씀드리기에는 제가 부족합니다.프레임워크 실행 파일에서 "nm" 명령을 사용하여 적합한 이름을 가진 명명된 함수가 있는지 확인하거나 시뮬레이터와 함께 gdb를 사용하여 위치를 추적할 수 있습니다.

무엇을 덮어쓸지 알면 함수에 대한 조회를 재연결하는 데 사용할 수 있는 낮은 수준의 ObjC 디스패치 함수들이 있다고 생각합니다.조금 전에 한 번 그런 적이 있는 것 같은데 자세한 내용은 기억이 안 나요.

제 힌트를 이용해서 이 문제에 대한 몇 가지 해결책을 찾아보세요.행운을 빌어요.

언급URL : https://stackoverflow.com/questions/4401232/avfoundation-how-to-turn-off-the-shutter-sound-when-capturestillimageasynchrono

반응형