Как сразу увидеть новый слой видео после отпускания кнопки? - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть приложение, в котором пользователь может удерживать кнопку, чтобы снять видео.Однако, когда они это делают, новый слой с воспроизведением видео появляется не сразу.Вместо этого существует очень короткая задержка, когда вы можете видеть, что камера все еще показывает то, что видит камера после того, как пользователь отпустил кнопку.Когда задержка заканчивается, видео мгновенно появляется и начинает воспроизводиться.Но как я могу сделать так, чтобы первый кадр видео появлялся до того, как он был готов к воспроизведению, чтобы он оставался там только на мгновение, прежде чем он начнет воспроизводиться?Посмотрите, как работает функция захвата видео в Snapchat, чтобы понять, что я имею в виду

Ниже приведен метод longTap, который у меня есть:

    @objc func longTap(_ sender: UIGestureRecognizer) {
    print("Long tap")

    self.numForVid = numForVid + 1 //shud change this number stuff
    print("\(numForVid)")

    cameraButton.isHidden = true

    if sender.state == .ended {
        print("UIGestureRecognizerStateEnded")

        //stopSession()
        stopRecording()
    }
    else if sender.state == .began {
        print("UIGestureRecognizerStateBegan.")
        //Do Whatever You want on Began of Gesture
        startCapture()
    }
}

Остановить запись func:

    func stopRecording() {

    if movieOutput.isRecording == true {
        movieOutput.stopRecording()
    }
}

и метод, называемыйпосле того, как выходной URL содержит все данные:

    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {

    if (error != nil) {
        print("Error recording movie11: \(error!.localizedDescription)")
    } else {
        newViewVideoPlayback()

        switchIcon.isHidden = true
        switchWhiteUI.isHidden = true
        switchCamButton.isHidden = true
        camWhiteLine.isHidden = true

        let videoRecorded = outputURL! as URL

        playerQueue = AVQueuePlayer(playerItem: AVPlayerItem(url: videoRecorded))
        self.playerQueue?.play()

        playerLayer = AVPlayerLayer(player: playerQueue)
        playerLayer.frame = (camPreview?.bounds)!
        playerLayer?.layoutIfNeeded()
        playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

        camPreview?.layer.insertSublayer(playerLayer, above: previewLayer)

        playerItem1 = AVPlayerItem(url: videoRecorded)

        playerLooper = AVPlayerLooper(player: playerQueue, templateItem: playerItem1)

        if !captureSession.isRunning {
            DispatchQueue.global(qos: .background).async {
                self.startRunningCaptureSession()
            }
        }
    }
}

Обновление:

Я пробовал приведенный ниже код, но он продолжает работать вечно, вызывая сбой xcode, яне понимаю, почему, поскольку предположительно в какой-то момент статус элемента AVPlayer должен быть .readyToPlay

            while playerItem1.status == .unknown {
            print("1111121232432431243123241432143243214324321")
            if playerItem1.status == .readyToPlay {

                playerQueue = AVQueuePlayer(playerItem: playerItem1)
                self.playerQueue?.play()

                playerLayer = AVPlayerLayer(player: playerQueue)
                playerLayer.frame = (camPreview?.bounds)!
                playerLayer?.layoutIfNeeded()
                playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill

                camPreview?.layer.insertSublayer(playerLayer, above: previewLayer)
            }
        }
        playerLooper = AVPlayerLooper(player: playerQueue, templateItem: playerItem1)

1 Ответ

0 голосов
/ 15 декабря 2018

Это можно сделать следующим образом.Установите эти свойства в viewController для хранения миниатюры первого кадра, когда начинается запись видео, и логического значения для сохранения, если захваченная фотография предназначена для миниатюры или обычного захвата фотографии одним нажатием:

private var isSettingThumbnail = false
private var thumbImage: UIImage?

иизменить реализацию цели распознавания жестов одним нажатием

@objc func normalTap(_ sender: UIGestureRecognizer) {
    //self.numForPic = numForPic + 1
    let settings = AVCapturePhotoSettings()
    isSettingThumbnail = false
    photoOutput?.capturePhoto(with: settings, delegate: self)
}

Вам также необходимо удалить слой предварительного просмотра, когда вы останавливаете запись, в противном случае захваченное изображение большого пальца не может быть отображено в ImageView.Здесь 10-секундная задержка просто для того, чтобы проверить, показывает ли изображение большого пальца.Только в целях отладки вы можете избавиться от него в любое время позже.

func stopRecording() {
        if thumbImage != nil {
            camPreview.image = thumbImage!
        }
        previewLayer?.removeFromSuperlayer()
        DispatchQueue.main.asyncAfter(deadline: .now() + 10.0, execute: {
            if self.movieOutput.isRecording == true {
                self.movieOutput.stopRecording()
            }
        })

    }

Теперь добавьте функцию делегата к AVCaptureFileOutputRecordingDelegate, чтобы получить обратный вызов при начале записи.На этом этапе вы устанавливаете логический флаг.

func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) {
    isSettingThumbnail = true
    photoOutput?.capturePhoto(with: AVCapturePhotoSettings(), delegate: self)
}

Теперь мы проверяем этот логический флаг и сохраняем и сохраняем уменьшенное изображение или обычное изображение.

extension ViewController: AVCapturePhotoCaptureDelegate {

    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {

        print("you in this !")

        if let imageData = photo.fileDataRepresentation() {
            print("\(UIImage(data: imageData)) <-- image DALUE FEFE DEDE KEKE LALY")
            if isSettingThumbnail {
                thumbImage = UIImage(data: imageData)
            } else {
                image = UIImage(data: imageData)
            }

            print("\(image) <-- dada dudu creoo IMAGE valu")
        }

    }

}

Я проверил код и работает нормально.Кроме того, во время записи звук затвора не воспроизводится по умолчанию , и мы делаем снимок, когда запись началась, поэтому мы делаем это в соответствии с рекомендациями Apple.Согласно этому яблочному док.Это один из возможных способов сделать это.Также измените класс предварительного просмотра камеры на UIImageView в раскадровке.Вы можете проверить рабочий код на github .Хорошего дня.Это был довольно интересный вопрос.:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...