121 lines
3.7 KiB
Swift
121 lines
3.7 KiB
Swift
//
|
|
// 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")
|
|
}
|
|
}
|