AV Foundation, 연결에서 비동기적으로 스틸 이미지를 캡처할 때 셔터 소리를 끄는 방법은 무엇입니까?
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
문서 파일(Mac용 DiskAid)에서 다운로드할 수 있습니다.에서는 다음단계열니다습었를다니▁i▁next를 열었습니다.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:
...
그리고 이것은 정말 효과가 있습니다!셔터 소리가 들리지 않을 때마다 테스트를 여러 번 실행합니다 :)
아이폰 5S iOS 7.1.1에서 캡처한 반전 사운드는 다음 링크에서 얻을 수 있습니다. https://www.dropbox.com/s/1echsi6ivbb85bv/photoShutter2.caf
Swift의 솔루션
에 전화할 때.AVCapturePhotoOutput.capturePhoto
아래 코드와 같은 이미지를 캡처하는 방법.
photoOutput.capturePhoto(with: self.capturePhotoSettings, delegate: self)
AVCapture PhotoCaptureDelegate는 AVCapture의 대표자입니다.그리고 시스템은 다음 후에 셔터 소리를 재생하려고 합니다.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에서 완벽하게 작동합니다.당신이 이것을 사용하면 애플이 당신의 앱을 거부하지 않을 것이라는 것도 확인했습니다(그들은 내 앱을 거부하지 않았습니다).
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에서는 CM TimeMake(1, 1)를 설정할 때 매우 무겁습니다. // 초당 한 프레임입니다.
WWDC 2010 샘플 코드인 FindMyCone에서 다음 코드를 찾았습니다.
[output setAlwaysDiscardsLateVideoFrames:YES];
이 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/23758875/capture-image-via-capturestillimageasynchronouslyfromconnection-with-no-shutter
'programing' 카테고리의 다른 글
System.console()이 null을 반환합니다. (0) | 2023.05.03 |
---|---|
ALTER TABLE, null이 아닌 열에 null 설정, PostgreSQL 9.1 (0) | 2023.05.03 |
오류: 지원되지 않는 형식 또는 손상된 파일: BOF 레코드가 필요합니다. (0) | 2023.05.03 |
Eclipse 템플릿에 사용되는 ${user} 변수 값을 변경하는 방법 (0) | 2023.05.03 |
node.js에 대한 10진수 / mongoose 내 부동 소수점 (0) | 2023.05.03 |