Когда я вхожу в приложение сразу начинает снимать, вместо того, чтобы ждать нажатии на кнопку start
import UIKit
import AVFoundation
import CoreLocation
class ViewController: UIViewController, AVCaptureFileOutputRecordingDelegate, CLLocationManagerDelegate {
let toggleButton = UIButton(type: .system)
let zoomSlider = UISlider()
let statusLabel = UILabel()
let captureSession = AVCaptureSession()
var videoOutput = AVCaptureMovieFileOutput()
var previewLayer: AVCaptureVideoPreviewLayer!
var videoDevice: AVCaptureDevice?
var videoInput: AVCaptureDeviceInput?
let locationManager = CLLocationManager()
var locationLog: [(timestamp: Date, coordinate: CLLocationCoordinate2D)] = []
var locationTimer: Timer?
var videoStartTime: Date?
var sessionConfigured = false
var cameraInitialized = false
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
setupLocationManager()
setupCamera()
}
func setupUI() {
view.backgroundColor = .black
toggleButton.setTitle("Start", for: .normal)
toggleButton.setTitleColor(.white, for: .normal)
toggleButton.titleLabel?.font = UIFont.systemFont(ofSize: 20, weight: .bold)
toggleButton.backgroundColor = .systemBlue
toggleButton.layer.cornerRadius = 40
toggleButton.clipsToBounds = true
toggleButton.addTarget(self, action: #selector(toggleRecording), for: .touchUpInside)
toggleButton.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(toggleButton)
statusLabel.text = ""
statusLabel.textColor = .white
statusLabel.textAlignment = .center
statusLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(statusLabel)
zoomSlider.minimumValue = 1.0
zoomSlider.maximumValue = 5.0
zoomSlider.value = 1.0
zoomSlider.isContinuous = true
zoomSlider.addTarget(self, action: #selector(zoomSliderChanged(_:)), for: .valueChanged)
zoomSlider.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(zoomSlider)
NSLayoutConstraint.activate([
toggleButton.centerXAnchor.constraint(equalTo: view.centerXAnchor),
toggleButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -60),
toggleButton.widthAnchor.constraint(equalToConstant: 80),
toggleButton.heightAnchor.constraint(equalToConstant: 80),
statusLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 10),
statusLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
zoomSlider.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
zoomSlider.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
zoomSlider.bottomAnchor.constraint(equalTo: toggleButton.topAnchor, constant: -30)
])
}
func setupLocationManager() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func setupCamera() {
DispatchQueue.global(qos: .userInitiated).async {
guard let device = AVCaptureDevice.default(for: .video),
let input = try? AVCaptureDeviceInput(device: device) else { return }
self.captureSession.beginConfiguration()
if self.captureSession.canAddInput(input) {
self.captureSession.addInput(input)
self.videoInput = input
self.videoDevice = device
}
self.videoOutput = AVCaptureMovieFileOutput()
if self.captureSession.canAddOutput(self.videoOutput) {
self.captureSession.addOutput(self.videoOutput)
}
self.captureSession.commitConfiguration()
self.captureSession.startRunning()
DispatchQueue.main.async {
self.previewLayer = AVCaptureVideoPreviewLayer(session: self.captureSession)
self.previewLayer.frame = self.view.bounds
self.previewLayer.videoGravity = .resizeAspectFill
self.view.layer.insertSublayer(self.previewLayer, at: 0)
self.sessionConfigured = true
}
}
}
@objc func toggleRecording() {
if videoOutput.isRecording {
stopRecording()
} else {
if CLLocationManager.authorizationStatus() == .authorizedWhenInUse || CLLocationManager.authorizationStatus() == .authorizedAlways {
startRecording()
} else {
locationManager.requestWhenInUseAuthorization()
}
}
}
func startRecording() {
guard sessionConfigured else {
print("Session not ready")
return
}
statusLabel.text = "Recording..."
toggleButton.setTitle("Stop", for: .normal)
videoStartTime = Date()
locationLog = []
locationManager.startUpdatingLocation()
locationTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
if let location = self.locationManager.location {
self.locationLog.append((Date(), location.coordinate))
}
}
let outputPath = NSTemporaryDirectory() + "roadvideo.mov"
let outputURL = URL(fileURLWithPath: outputPath)
if FileManager.default.fileExists(atPath: outputPath) {
try? FileManager.default.removeItem(atPath: outputPath)
}
videoOutput.startRecording(to: outputURL, recordingDelegate: self)
}
func stopRecording() {
statusLabel.text = "Stopped"
toggleButton.setTitle("Start", for: .normal)
videoOutput.stopRecording()
locationManager.stopUpdatingLocation()
locationTimer?.invalidate()
print("Saved GPS points: \(locationLog)")
}
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
if let error = error {
print("Recording error: \(error.localizedDescription)")
} else {
print("Video saved to: \(outputFileURL)")
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse || status == .authorizedAlways {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
if !self.videoOutput.isRecording {
self.startRecording()
}
}
}
}
@objc func zoomSliderChanged(_ sender: UISlider) {
guard let device = videoDevice else { return }
let zoomFactor = CGFloat(sender.value)
do {
try device.lockForConfiguration()
device.videoZoomFactor = zoomFactor
device.unlockForConfiguration()
} catch {
print("Zoom error: \(error.localizedDescription)")
}
}
}