So i wanna generate an mp4 file when recording , what i am able to do is to generate only .m4a or .caf. when i am trying to generate other files it fails using this code:
import AVFoundation
class ViewController: UIViewController {
var fileName: String = "audioFile.m4a"
var soundRecorder: AVAudioRecorder?
var soundPlayer: AVAudioPlayer?
var audioSession = AVAudioSession.sharedInstance()
override func viewDidLoad() {
super.viewDidLoad()
setUpRecorder()
playBtn.isEnabled = false
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSession.Category.playAndRecord, mode: .measurement, options: .defaultToSpeaker)
try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
} catch {
print(error)
}
}
func getDocDirector() -> URL {
let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return path[0]
}
func setUpRecorder() {
let audioFileName = getDocDirector().appendingPathComponent(fileName)
let recordSettings = [ AVFormatIDKey: Int(kAudioFormatAppleLossless),
AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue,
AVEncoderBitRateKey: 192000,
AVNumberOfChannelsKey: 1,
AVSampleRateKey: 441000 ] as [String: Any]
do {
soundRecorder = try AVAudioRecorder(url: audioFileName, settings: recordSettings)
soundRecorder?.delegate = self
soundRecorder?.prepareToRecord()
} catch {
print(error)
}
}
func setUpPlayer() {
let audioFileName = getDocDirector().appendingPathComponent(fileName)
do {
soundPlayer = try AVAudioPlayer(contentsOf: audioFileName)
soundPlayer?.delegate = self
soundPlayer?.prepareToPlay()
soundPlayer?.volume = 1.0
} catch {
print(error)
}
}
@IBAction func recordAction(_ sender: Any) {
if recordBtn.titleLabel?.text == "Record" {
soundRecorder?.record()
recordBtn.setTitle("Stop", for: .normal)
playBtn.isEnabled = false
} else {
soundRecorder?.stop()
recordBtn.setTitle("Record", for: .normal)
playBtn.isEnabled = false
}
}
@IBAction func playAction(_ sender: Any) {
if playBtn.titleLabel?.text == "Play" {
playBtn.setTitle("Stop", for: .normal)
recordBtn.isEnabled = false
setUpPlayer()
soundPlayer?.play()
} else {
playBtn.setTitle("Play", for: .normal)
recordBtn.isEnabled = false
}
}
extension ViewController: AVAudioRecorderDelegate {
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
playBtn.isEnabled = true
}
func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder, error: Error?) {
print(error!)
}
}
extension ViewController: AVAudioPlayerDelegate {
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
recordBtn.isEnabled = true
playBtn.setTitle("Play", for: .normal)
}
}
So all of this works great yet i cant manage to find the way to write mp4 Is there any way to write straight mp4? my end goal is to generate fragmented mp4 to send through sockets... be glad for an advice
Change your settings dictionary to this one:
let recordSettings: [String: Any] = [AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue,
AVNumberOfChannelsKey: 1,
AVEncoderBitRateKey: 16000,
AVSampleRateKey: 16000]
Also don't forget to change extension in fileName
:
var fileName: String = "audioFile.mp4"