[ad_1]
My use case is kind of like SnapChat : I launch my app the digicam is show, I can file movies and show/play the video consequence proper after the file.
Then I am attempting to combine different app audio (like Spotify) once I’m recording with the AVAudioSession properties and play the consequence with the blended sound.
First drawback is once I play a Spotify music and open my app, the music is immediately killed by the digicam opening. But when I’m going again to Spotify, play music once more, and return on my app it is working wonderful and I can file accurately with .mixWithOther.
Second drawback once I play the video proper after the file, regardless of my config typically there isn’t any sound or typically there’s a battle between video sound and background.
Right here is my logic :
- Setup the digicam machine
- Init audio session class
- Configure inputs / outputs session
- Begin session
- Report a video
- Cease file and clear audio
- Cease present session
- Play the video
var sessionQueue = DispatchQueue.international()
var session: AVCaptureSession?
let photoOutput = AVCapturePhotoOutput()
let videoOutput = AVCaptureMovieFileOutput()
var audioDevice: AVCaptureDevice?
var audioInput: AVCaptureDeviceInput?
var cameraInput: AVCaptureDeviceInput?
let audioSession = AVAudioSession.sharedInstance()
var currentCamera: AVCaptureDevice?
non-public func setupCamera() {
currentCamera = AVCaptureDevice.default(.builtInWideAngleCamera, for: .video, place: cameraPosition)
if(currentCamera != nil) {
let sizeCamera = CMVideoFormatDescriptionGetPresentationDimensions(currentCamera!.activeFormat.formatDescription, usePixelAspectRatio: true, useCleanAperture: true);
aspectRatio = sizeCamera.width / sizeCamera.top
let minZoom = currentCamera!.minAvailableVideoZoomFactor
let maxZoom = currentCamera!.maxAvailableVideoZoomFactor
let minExposure = currentCamera!.minExposureTargetBias
let maxExposure = currentCamera!.maxExposureTargetBias
initSession()
}
else if(initializationCompletion != nil) {
initializationCompletion!(false)
}
}
func initSession() {
print("init digicam session")
do {
attempt audioSession.setCategory(AVAudioSession.Class.playAndRecord,
choices: [.mixWithOthers,
.allowBluetoothA2DP,
.defaultToSpeaker,
.allowAirPlay
])
attempt audioSession.setActive(true)
cameraInput = attempt AVCaptureDeviceInput(machine: currentCamera!)
audioDevice = AVCaptureDevice.default(for: AVMediaType.audio)
audioInput = attempt AVCaptureDeviceInput(machine: audioDevice!)
// Assign as soon as or after a stopSession() to deal with the swap digicam case
if(session == nil) {
session = AVCaptureSession()
}
session!.beginConfiguration()
session!.automaticallyConfiguresApplicationAudioSession = false
if session!.canAddInput(cameraInput!) {
session!.addInput(cameraInput!)
}
if session!.canAddOutput(photoOutput) {
session!.addOutput(photoOutput)
}
if session!.canAddOutput(videoOutput) {
session!.addOutput(videoOutput)
}
if session!.canAddInput(audioInput!) {
session!.addInput(audioInput!)
}
session!.sessionPreset = .hd1920x1080;
session!.commitConfiguration()
previewLayer.session = session
if(session != nil) {
self.session!.startRunning()
self.initializationCompletion!(true)
}
}
catch {
}
}
public func startRecord(completion: ((Bool?)-> Void)? = nil) {
guard let captureSession = self.session, captureSession.isRunning else {
print(CameraControllerError.captureSessionIsMissing)
return
}
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let fileUrl = paths[0].appendingPathComponent("temp.mp4")
attempt? FileManager.default.removeItem(at: fileUrl)
DispatchQueue.important.async {
self.videoOutput.startRecording(to: fileUrl, recordingDelegate: self)
completion!(true)
}
}
func stopRecording(completion: ((String?)-> Void)? = nil) {
guard let captureSession = self.session, captureSession.isRunning else {
print(CameraControllerError.captureSessionIsMissing)
return
}
// Reset the audio session to default to play the video recorded
do {
attempt audioSession.setActive(false)
attempt audioSession.setCategory(.ambient)
attempt audioSession.setActive(true)
}
catch {
}
DispatchQueue.important.async {
self.videoOutput.stopRecording()
self.videoRecordCompletionBlock = completion
stopSession()
}
}
func startSession(completion: ((Bool?)->Void)? = nil) {
print("working the digicam session")
initializationCompletion = completion
sessionQueue.async {
self.setupCamera()
}
}
func stopSession(completion: ((Bool?)->Void)? = nil) {
if(self.session != nil) {
sessionQueue.async {
let inputs = self.session!.inputs
for oldInput:AVCaptureInput in inputs {
self.session!.removeInput(oldInput)
}
let outputs = self.session!.outputs
for oldOutput:AVCaptureOutput in outputs {
self.session!.removeOutput(oldOutput)
}
do {
attempt self.audioSession.setCategory(AVAudioSession.Class.playback)
attempt self.audioSession.setActive(true)
} catch {
print("error reset audio session")
}
self.session!.stopRunning()
if(completion != nil) {
completion!(true)
}
//previewLayer.removeFromSuperlayer()
}
}
}
I need to open my app with out killing different audio app, file video correctly, show and play the video with out sound conflicts.
The place my logic or implementation is flawed and tips on how to enhance this ?
[ad_2]
