Saya mencoba untuk menangkap gambar selama pratinjau langsung dari kamera, dengan AVFoundation captureStillImageAsynchronouslyFromConnection . Sejauh ini program berjalan sesuai harapan. Namun demikian, bagaimana cara membungkam suara rana?
Saya mencoba untuk menangkap gambar selama pratinjau langsung dari kamera, dengan AVFoundation captureStillImageAsynchronouslyFromConnection . Sejauh ini program berjalan sesuai harapan. Namun demikian, bagaimana cara membungkam suara rana?
Jawaban:
Saya menggunakan kode ini sekali untuk menangkap suara rana default iOS (berikut adalah daftar nama file suara 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];
Kemudian saya menggunakan aplikasi pihak ketiga untuk mengekstrak photoShutter.caf
dari direktori Dokumen (DiskAid untuk Mac). Langkah selanjutnya saya buka photoShutter.caf
di editor audio Audacity dan menerapkan efek inversi, terlihat seperti ini pada zoom tinggi:
Kemudian saya menyimpan suara ini photoShutter2.caf
dan mencoba memutar suara ini sebelumnya 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:
...
Dan ini benar-benar berhasil! Saya menjalankan tes beberapa kali, setiap kali saya tidak mendengar suara rana :)
Anda bisa mendapatkan suara yang sudah terbalik, ditangkap di iPhone 5S iOS 7.1.1 dari tautan ini: https://www.dropbox.com/s/1echsi6ivbb85bv/photoShutter2.caf
Ketika Anda memanggil AVCapturePhotoOutput.capturePhoto
metode untuk menangkap gambar seperti kode di bawah ini.
photoOutput.capturePhoto(with: self.capturePhotoSettings, delegate: self)
Metode AVCapturePhotoCaptureDelegate akan dipanggil. Dan sistem mencoba memutar suara rana setelah willCapturePhotoFor
dipanggil. Jadi Anda dapat membuang suara sistem dalam willCapturePhotoFor
metode.
extension PhotoCaptureService: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, willCapturePhotoFor resolvedSettings: AVCaptureResolvedPhotoSettings) {
// dispose system shutter sound
AudioServicesDisposeSystemSoundID(1108)
}
}
AudioServicesDisposeSystemSoundID(1108)
dipanggil. Apakah Anda punya solusi untuk ini? :)
Metode 1: Tidak yakin apakah ini akan berhasil, tetapi coba putar file audio kosong tepat sebelum Anda mengirim acara pengambilan.
Untuk memutar klip, tambahkan Audio Toolbox
kerangka kerja, #include <AudioToolbox/AudioToolbox.h>
dan putar file audio seperti ini segera sebelum Anda mengambil gambar:
NSString *path = [[NSBundle mainBundle] pathForResource:@"blank" ofType:@"wav"];
SystemSoundID soundID;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
AudioServicesPlaySystemSound(soundID);
Ini adalah file audio kosong jika Anda membutuhkannya. https://d1sz9tkli0lfjq.cloudfront.net/items/0Y3Z0A1j1H2r1c0z3n3t/blank.wav
________________________________________________________________________________________________________________________________________
Metode 2: Ada juga alternatif jika ini tidak berhasil. Selama Anda tidak perlu memiliki resolusi yang bagus, Anda dapat mengambil bingkai dari aliran video , sehingga menghindari suara gambar sama sekali.
________________________________________________________________________________________________________________________________________
Metode 3: Cara lain untuk melakukannya adalah dengan mengambil "tangkapan layar" dari aplikasi Anda. Lakukan dengan cara ini:
UIGraphicsBeginImageContext(self.window.bounds.size);
[self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData * data = UIImagePNGRepresentation(image);
[data writeToFile:@"foo.png" atomically:YES];
Jika Anda ingin ini memenuhi seluruh layar dengan pratinjau aliran video sehingga tangkapan layar Anda terlihat bagus:
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];
Saya bisa membuat ini berfungsi dengan menggunakan kode ini di fungsi snapStillImage dan berfungsi dengan sempurna untuk saya di iOS 8.3 iPhone 5. Saya juga telah mengonfirmasi bahwa Apple tidak akan menolak aplikasi Anda jika Anda menggunakan ini (mereka tidak menolak Milikku)
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];
Ingatlah untuk bersikap baik dan menyuarakannya saat aplikasi Anda kembali!
Saya tinggal di Jepang, jadi saya tidak dapat menonaktifkan audio saat kami mengambil foto untuk alasan keamanan. Dalam video, bagaimanapun audio dimatikan. Saya tidak mengerti kenapa.
Satu-satunya cara saya mengambil foto tanpa suara rana adalah menggunakan AVCaptureVideoDataOutput atau AVCaptureMovieFileOutput. Untuk menganalisis gambar diam AVCaptureVideoDataOutput hanya cara. Dalam kode contoh 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);
Di 3GS saya, ini sangat berat ketika saya mengatur CMTimeMake (1, 1); // Satu frame per detik.
Dalam kode Contoh WWDC 2010, FindMyiCone, saya menemukan kode berikut,
[output setAlwaysDiscardsLateVideoFrames:YES];
Saat API ini digunakan, waktunya tidak diberikan, tetapi API dipanggil secara berurutan. Saya ini adalah solusi terbaik.
Anda juga dapat mengambil bingkai dari aliran video untuk mengambil gambar (bukan resolusi penuh).
Ini digunakan di sini untuk mengambil gambar dalam interval pendek:
- (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;
}
Lihat posting ini untuk jenis jawaban yang berbeda: Tangkap gambar dari penyangga gambar. Tangkapan layar selama pratinjau video gagal
Satu-satunya solusi yang mungkin saya pikirkan adalah mematikan suara iphone saat mereka menekan tombol "ambil gambar", dan kemudian mengaktifkannya beberapa saat kemudian.
Trik umum dalam kasus seperti itu adalah mencari tahu apakah kerangka kerja memanggil metode tertentu untuk kejadian ini, dan kemudian menimpa metode itu untuk sementara, sehingga menghilangkan efeknya.
Saya minta maaf, tetapi saya bukan peretas yang cukup baik untuk segera memberi tahu Anda apakah itu berhasil dalam kasus ini. Anda dapat mencoba perintah "nm" pada kerangka kerja yang dapat dieksekusi untuk melihat apakah ada fungsi bernama yang memiliki nama yang sesuai, atau gunakan gdb dengan Simulator untuk melacak kemana perginya.
Setelah Anda tahu apa yang harus ditimpa, ada fungsi pengiriman ObjC tingkat rendah yang dapat Anda gunakan untuk mengarahkan pencarian fungsi, saya yakin. Saya pikir saya telah melakukannya sekali beberapa waktu yang lalu, tetapi tidak dapat mengingat detailnya.
Mudah-mudahan, Anda dapat menggunakan petunjuk saya ke google beberapa jalur solusi untuk ini. Semoga berhasil.