// // TestingKaraokeVC.swift // WOKA // // Created by MacBook Pro on 09/07/24. // import AVFAudio import UIKit import AVFoundation class TestingKaraokeVC : UIViewController{ var player: AVPlayer! var audioEngine: AVAudioEngine! var micInput: AVAudioInputNode! var playerNode: AVAudioPlayerNode! var audioFile: AVAudioFile! var fileURL: URL! override func viewDidLoad() { super.viewDidLoad() let videoURL = URL(string: "https://content.jwplatform.com/videos/DOhtETio-Ysj2G4DQ.mp4")! setupPlayer(with: videoURL) setupAudioEngine() setupAudioFile() } func setupPlayer(with url: URL) { player = AVPlayer(url: url) let playerLayer = AVPlayerLayer(player: player) playerLayer.frame = view.bounds view.layer.addSublayer(playerLayer) player.play() } func setupAudioEngine() { audioEngine = AVAudioEngine() micInput = audioEngine.inputNode playerNode = AVAudioPlayerNode() audioEngine.attach(playerNode) let format = micInput.inputFormat(forBus: 0) audioEngine.connect(micInput, to: audioEngine.mainMixerNode, format: format) audioEngine.connect(playerNode, to: audioEngine.mainMixerNode, format: format) try! audioEngine.start() } func setupAudioFile() { let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] fileURL = documentsDirectory.appendingPathComponent("output.m4a") let format = audioEngine.mainMixerNode.outputFormat(forBus: 0) do { audioFile = try AVAudioFile(forWriting: fileURL, settings: format.settings) } catch { print("Error creating audio file: \(error)") } } func startRecording() { let mixer = audioEngine.mainMixerNode let format = mixer.outputFormat(forBus: 0) mixer.installTap(onBus: 0, bufferSize: 1024, format: format) { (buffer, time) in do { try self.audioFile.write(from: buffer) } catch { print("Error writing audio buffer: \(error)") } } } func stopRecording() { let mixer = audioEngine.mainMixerNode mixer.removeTap(onBus: 0) // Save the file to Files app presentDocumentPicker() } func presentDocumentPicker() { // let documentPicker = UIDocumentPickerViewController(forExporting: [fileURL]) // documentPicker.delegate = self // present(documentPicker, animated: true, completion: nil) guard let mixedAudioURL = fileURL else { return } DispatchQueue.main.async { let documentPicker = UIDocumentPickerViewController(url: mixedAudioURL, in: .exportToService) documentPicker.delegate = self self.present(documentPicker, animated: true, completion: nil) } } @IBAction func startButtonPressed(_ sender: UIButton) { startRecording() } @IBAction func stopButtonPressed(_ sender: UIButton) { stopRecording() } } extension TestingKaraokeVC: UIDocumentPickerDelegate { func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) { guard let selectedURL = urls.first else { return } do { try FileManager.default.moveItem(at: fileURL, to: selectedURL) } catch { print("Error saving file to Files app: \(error)") } } func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) { print("Document picker was cancelled") } }