2016-11-02 11 views
3

의 시작 가입일 :아이폰 OS 올바른 방법 AVFoundation이 캡처 파이프 라인을 사용하여 녹화 중 시간 라벨을 업데이트하는 방법 녹화

Mic -> AVCaptureDeviceInput -> AVCaptureSession -> AVCaptureAudioDataOutput 

AVCaptureAudioDataOutput 출력 파일에 sampleBuffers을 쓰고 위임 및 AVAssetWritter 있습니다. 이 솔루션에서는 녹음 시간을 업데이트하고 싶습니다. 사용자가 녹음/일시 정지/다시 시작/중지 버튼을 누를 때 시간을 기록 할 수 있지만 처음에는 00:00:00 시간으로 UILabel을 업데이트하는 방법은 Apple의 공식적인 방법입니다. 나는 NSTimer를 사용할 수 있습니다 알고 있지만 내가 AVAudioRecorder 일하던 나는 재산했다 : 위의 속성이 일시 정지 작업을했다

var currentTime: TimeInterval 
// The time, in seconds, since the beginning of the recording. 

/뿐만 아니라 버튼을 계속합니다.

이 새로운 파이프 라인에서 나는이 속성을 가지지 않고 무언가를 놓치고 어디서나 찾을 수 없는지 궁금합니다. 또한 AVCaptureSession에는 masterClock이라는 CMClock 속성이 있지만 녹음 시작부터 시간을 계산하는 방법을 모르겠습니다.

CMClockGetHostTimeClock() 
CMSyncConvertTime 

어떻게 sampleBuffer에 따라 AVCaptureAudioDataOutputSampleBufferDelegate 방법의 녹화 시작부터 초 수를 구하는 :

내가 좋아하는 시계 및 방법이 모든 생각을하지?

UPDATE 나는 CMTimebase라는 클래스를 발견하고 나는 이것이 내가 찾던 exacly 생각합니다. 현재 나는 그것을 사용하는 방법을 모르지만 놀이터에서 몇 가지 실험을 한 후에 발견했습니다.

import CoreMedia 

let masterClock = CMClockGetHostTimeClock() // This masterclock should be from captureSession 
var timebase: CMTimebase? = nil 
CMTimebaseCreateWithMasterClock(kCFAllocatorDefault, masterClock, &timebase) 

print(CMTimeGetSeconds(CMTimebaseGetTime(timebase!))) 

CMTimebaseSetRate(timebase!, 1.0) // Start/Resume recording 

sleep(1) 
print(CMTimeGetSeconds(CMTimebaseGetTime(timebase!))) 

sleep(1) 
CMTimebaseSetRate(timebase!, 0.0) // Pause Recording 
print(CMTimeGetSeconds(CMTimebaseGetTime(timebase!))) 


sleep(1) 
print(CMTimeGetSeconds(CMTimebaseGetTime(timebase!))) 

이 개체는 정말 유용합니다. 속도를 1.0으로 설정하면 masterClock과 동기화되어 시간 측정이 시작됩니다. 속도를 0.0으로 설정하면 시간 측정이 중지됩니다. 나는이 객체에 Timer를 첨부 할 수 있다는 것을 알았다. 불행히도 애플 사이트의 API 문서에는이 핵심 미디어 자료에 대한 훌륭한 자습서가 없습니다. CoreMedia Framework와 관련된 주제에 대한 WWDC의 훌륭한 자습서/비디오가 있다면 누구도 알고 있습니까?

+0

나는 전에 CMTimebase를 사용하지 않았지만 원하는 것을하기 위해 사용할 수 있어야합니다. 녹화를 시작할 때 AVCaptureSession 시계에 연결하고 시간을 업데이트하려면 CMTimebase를 읽으십시오. 당신은 여전히 ​​타이머 또는 트리거를 필요로 할 것이고 "너무 자주"버퍼가 디스플레이 업데이트를 얻는다. 불행히도 나는 어떤 문서에 익숙하지 않고 빠른 구글도 어떤 것도 보여주지 않는다. 행운을 빕니다! –

답변

2

AVCaptureAudioOutput을 다룰 때 이제 샘플 버퍼로 작업하고 있습니다. 비디오인지 오디오인지에 관계없이 중요한 두 가지 정보, 샘플 데이터 및 샘플 데이터가 기록 된 시간이 필요합니다. 시간의 경과를 측정 하드웨어 일반적 편 :

이것은 "시계"https://developer.apple.com/reference/coremedia/cmclock

이 시계의 시간 정보의 소스를 표시한다.

매우 정확하며 그게 중요한 부분입니다. 읽기 전용이므로 참조를 얻을 수는 있지만 설정할 수는 없습니다. 모든 종류의 일은 버퍼에 발생할 수 있으며 대기열에 넣어 네트워크를 통해 전달 될 수 있지만 CMTime 참조가 있으면 올바른 순서와 올바른 시간으로 재구성 할 수 있습니다.

CMSync는 시계 드리프트 (약간 다른 값을보고하는 두 개의 다른 시계 사이)를 다루는 함수의 하위 집합입니다. 당신은 이것들에 대해 전혀 걱정할 필요가 없습니다.

실제로 원하는 작업을 수행하는 것은 매우 간단합니다. 다음은 잘라내어 놀이터에 붙여 넣을 수있는 예입니다. 당신의 초 값을 제공한다

import AVFoundation 

let masterClock : CMClock = CMClockGetHostTimeClock() 
let startTime : CMTime = CMClockGetTime(masterClock) 
sleep(1) 
let endTime : CMTime = CMClockGetTime(masterClock) 
let difference : CMTime = CMTimeSubtract(endTime, startTime) 
let seconds = CMTimeGetSeconds(difference) 

약간>

1. 당신이 당신의 응용 프로그램에서 녹화 버튼을 클릭 AVCaptureSession 시계를 움켜 잡고 startTime을 캡처합니다.

UI를 업데이트하려면 AVCaptureSession 클럭을 다시 확인하고 두 CMTime을 빼고 초로 변환하십시오.

모든 샘플 버퍼의 UI를 너무 자주 업데이트하지 않도록하십시오. 따라서 14,000 샘플마다 (또는 사용중인 오디오 주파수에 맞는 방식으로) . 또한 별도의 스레드로 오프로드해야합니다.

희망 사항이 도움이되고 시계에 대해 조금 설명합니다. 행운을 빕니다!

+1

대단한 위대한 답변, 매우 유익한. 나는 이것으로 놀이터에서 놀려고 노력할 것이다. 나는 60fps의 디스플레이를 가지고있을 때 초당 44100 회 (오디오 샘플 레이트 주파수로) UILabel을 업데이트하려고하지 않는 것이 의미가 없다는 것을 알고 있습니다. 나는 내일에 갈거야. 대단히 감사합니다! –

+0

도움이 되니 기뻤습니다. 한번 테스트 해보고 행복하다면, 자유롭게 답을하고 대답 해주세요. –

+0

팀 내 질문에 대한 내 업데이트를보고 내 발견을 검토 할 수 있습니다. 아마도 CoreMedia Framework에 대한 유용한 자습서/자료를 알고 있습니까? –