【问题标题】:show record timer while making video制作视频时显示记录计时器
【发布时间】:2014-03-06 10:34:31
【问题描述】:

我已经实现了 AVCaptureSession 的概念来录制视频。

-(void)startRecordingWithOrientation:(AVCaptureVideoOrientation)videoOrientation 
{

    AVCaptureConnection *videoConnection = [AVCamUtilities   
                                           connectionWithMediaType:AVMediaTypeVideo  
                                           fromConnections:[[self movieFileOutput] connections]];
    if ([videoConnection isVideoOrientationSupported])
        [videoConnection setVideoOrientation:videoOrientation];

    [[self movieFileOutput] startRecordingToOutputFileURL:[self outputFileURL]  
    recordingDelegate:self];
 } 

它正在正确录制视频,但屏幕上没有录制计时器。任何人都知道如何在制作视频时显示计时器。

提前致谢。

【问题讨论】:

    标签: ios objective-c avcapturedevice avcam


    【解决方案1】:

    我使用在录制时显示视频的视图中添加 UILabel,并使用此代码显示录制时间

    @property (weak, nonatomic) IBOutlet UILabel *labelTime;
    
    @property(nonatomic, strong) NSTimer *timer;
    @property(nonatomic) int timeSec;
    @property(nonatomic) int timeMin;
    

    //开始录制的方法

    - (void)startRecord {
        self.timeMin = 0;
        self.timeSec = 0;
    
        //String format 00:00
        NSString* timeNow = [NSString stringWithFormat:@"%02d:%02d", self.timeMin, self.timeSec];
        //Display on your label
        //[timeLabel setStringValue:timeNow];
        self.labelTime.text= timeNow;
    
        self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
    
        //Start recording
        [movieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];
    
    }
    
    
    //Event called every time the NSTimer ticks.
    - (void)timerTick:(NSTimer *)timer {
        self.timeSec++;
        if (self.timeSec == 60)
        {
            self.timeSec = 0;
            self.timeMin++;
        }
        //String format 00:00
        NSString* timeNow = [NSString stringWithFormat:@"%02d:%02d", self.timeMin, self.timeSec];
        //Display on your label
        self.labelTime.text= timeNow;
    }
    

    【讨论】:

    • 仅供参考,请记住scheduledTimerWithTimeInterval 调用会将NSTimer 添加到当前运行循环中,因此以后无需手动添加。
    • @Fran Martin 因为我在 Swift 中使用它,所以我使用了错误的 Timer 方法。我使用的是 Timer(timeInterval:...) 而不是 Timer.scheduledTimer()。我最终想通了。你的回答很好用!!!谢谢:)
    【解决方案2】:

    @Fran Martin 接受的答案效果很好!

    自从我在 Swift 中使用它以来,我花了大约一个小时来找出正确的 Timer() 函数。为了帮助下一个不流利使用Objective C的人,这里是接受答案的Swift版本,带有一些额外的功能到invalidate计时器,将计时器重置回00:00,当在viewWillAppear 中使用它,以及何时在invalidate

    总是 invalidate viewWillDisappearviewDidDisappear 中的计时器,否则如果它是 repeat 计时器并且它正在运行,您可以获得memory leak

    我遇到了一个无法预料的问题,即使我会停止它,计时器仍会继续运行,我发现这个SO Answer 说你必须在再次启动它之前停止它,当你声明计时器时使用weak

    @IBOutlet weak fileprivate var yourLabel: UILabel!
    
    var timeMin = 0
    var timeSec = 0
    weak var timer: Timer?
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        // if your presenting this vc yourLabel.txt will show 00:00
        yourLabel.txt = String(format: "%02d:%02d", timeMin, timeSec)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
    
        resetTimerToZero()
    }
    
    // MARK:- recordButton
    @IBAction fileprivate func recordButtonTapped(_ sender: UIButton) {
    
        startTimer()
        
        movieFileOutput.startRecording(to: videoUrl, recordingDelegate: self)
    }
    
    // MARK:- Timer Functions
    fileprivate func startTimer(){
        
        // if you want the timer to reset to 0 every time the user presses record you can uncomment out either of these 2 lines
    
        // timeSec = 0
        // timeMin = 0
    
        // If you don't use the 2 lines above then the timer will continue from whatever time it was stopped at
        let timeNow = String(format: "%02d:%02d", timeMin, timeSec)
        yourLabel.txt = timeNow
    
        stopTimer() // stop it at it's current time before starting it again
        timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
                    self?.timerTick()
                }
    }
        
    @objc fileprivate func timerTick(){
         timeSec += 1
            
         if timeSec == 60{
             timeSec = 0
             timeMin += 1
         }
            
         let timeNow = String(format: "%02d:%02d", timeMin, timeSec)
            
         yourLabel.txt = timeNow
    }
    
    // resets both vars back to 0 and when the timer starts again it will start at 0
    @objc fileprivate func resetTimerToZero(){
         timeSec = 0
         timeMin = 0
         stopTimer()
    }
    
    // if you need to reset the timer to 0 and yourLabel.txt back to 00:00
    @objc fileprivate resetTimerAndLabel(){
    
         resetTimerToZero()
         yourLabel.txt = String(format: "%02d:%02d", timeMin, timeSec)
    }
    
    // stops the timer at it's current time
    @objc fileprivate stopTimer(){
    
         timer?.invalidate()
    }
    

    【讨论】:

    • 你好@lance Samaria,我已经尝试了上述相同的方法,但是在这个方法中,首先开始录制,然后在录制停止后开始计时。并行两者都是为了一起工作。你能帮我解决这个问题吗?提前谢谢
    • @puja 听起来您在录制停止时启动计时器,而您应该在录制开始时启动计时器并在录制停止时停止计时器。听起来您只是将代码放在错误的位置。你应该慢慢地逐行查看你的代码。这是一个简单的错误。你应该做的是 c+p 上面的代码完全一样。添加一个类var isRecording = false,当点击按钮时将其设置为true然后启动计时器,当您再次按下它时将其设置为false并停止计时器。如果它有效,则将其与您的其他代码进行比较
    • 在按钮中简单地检查if !isRecording { isRecording = true; startTimer() } else { isRecording = false ; stopTimer() }
    【解决方案3】:

    记住开始录制时的时间(NSTimeInterval),将其保存在实例变量中,然后在每秒触发两次左右的计时器中计算与当前时间的差值(NSDate timeIntervalSinceReferenceDate),并将结果时间显示为一个 UITextView?

    为避免漂移,请在每次显示后在计时器上设置“触发时间”,并将其设置为直到下一整秒(或半秒或无论如何频繁)消失的时间。这样,如果例如显示时间需要 0.1 秒,下一次开火时间更有可能是整整一秒左右。

    【讨论】:

    • 我可以这样做,但是相机的默认计时器呢?
    • 你的意思是你的相机在它的小屏幕上显示时间?这就是相机所做的事情。它通常不会向您提供这些信息。您必须查看相机的手册。
    • 我不认为为您提供 CVPixelBuffer 的回调包含 MPEG 时间戳,以防您正在寻找。
    • 我没有得到你。我必须制作我的自定义计时器吗?我们不能使用相机默认计时器吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多