iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
📷

Enabling Haptic Feedback on the Camera Screen #iOS #Swift

に公開

When trying to customize camera features, you will likely find yourself primarily using AVCaptureSession from AVFoundation (excluding things like ARKit).
For example, there are situations where you want to provide a reaction to the user using the Haptic Feedback feature when they press the shutter or change the zoom magnification.
However, Haptic Feedback doesn't work even if you configure it straightforwardly, which had me scratching my head.
By the way, I thought setting try AVAudioSession.sharedInstance().setAllowHapticsAndSystemSoundsDuringRecording(true) would be enough, but it behaved as if that was being completely ignored.

However, it seems the order of the configuration was wrong.

    let session = AVCaptureSession()
    let audioDevice = AVCaptureDevice.default(for: .audio)
    var audioDeviceInput: AVCaptureDeviceInput?
    var videoDeviceInput: AVCaptureDeviceInput?

    let backVideoDeviceDiscoverySession = AVCaptureDevice.DiscoverySession(
        deviceTypes: [.builtInDualCamera, .builtInWideAngleCamera],
        mediaType: .video,
        position: .back
    )

    let fileOutput = AVCaptureMovieFileOutput()

    func configureSettings() throws {
        // before
	try AVAudioSession.sharedInstance().setAllowHapticsAndSystemSoundsDuringRecording(true)
        session.beginConfiguration()
        if let audioDevice {
            let audioInput = try AVCaptureDeviceInput(device: audioDevice)
            if session.canAddInput(audioInput) {
                session.addInput(audioInput)
            }
            else {
                throw VideoRecorderErrors.audioInputAddFailed
            }
            audioDeviceInput = audioInput
        }
        if let device = backVideoDeviceDiscoverySession.devices.first {
            let videoInput = try AVCaptureDeviceInput(device: device)
            if session.canAddInput(videoInput) {
                session.addInput(videoInput)
            }
            else {
                throw VideoRecorderErrors.videoInputAddFailed
            }
            videoDeviceInput = videoInput
        }
        fileOutput.maxRecordedDuration = maxTimeDuration
        session.addOutput(fileOutput)

        session.commitConfiguration()
    }

Originally, I was configuring AVAudioSession before configuring AVCaptureSession like this, but

        session.commitConfiguration()
	// after
	try AVAudioSession.sharedInstance().setAllowHapticsAndSystemSoundsDuringRecording(true)
    }

It worked correctly when I updated the AVAudioSession settings after completing the AVCaptureSession configuration like this.

It seems that the AVAudioSession settings are reset when AVCaptureDeviceInput(device: audioDevice) is added to the AVCaptureSession. I also encountered an issue where attempting to play video and music simultaneously resulted in different behavior depending on whether the camera screen had been launched.
This could be avoided by executing the following before video playback:

try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: .mixWithOthers)

Summary

It sort of makes sense if you think about it from the OS's perspective, but I couldn't think calmly because I was panicking while the bug was occurring.
I'm glad I managed to fix it.

Discussion