1、使用AVAudioRecorder录制视频

  AVAudioRecorder与AVAudioPlayer类似,它们都属于AVFoundation的类。AVAudioRecorder的功能类似于一个录音器,使用AVAudioRecorder录制音频十分简单,当程序控制AVAudioRecorder对象创建完成之后,可以调用AVAudioRecorder的如下方法进行录制。

  1、prepareToRecord:准备开始录制。调用record方法时,如果音频还没有准备好,程序会隐式先执行该方法。

  2、record:开始或恢复录制。调用该方法是,如果音频还没有准备好,程序会隐式执行prepareToRecord方法。

  3、recordAtTime:在指定时间点开始或恢复录制。

  4、record(atTime time: TimeInterval, forDuration duration: TimeInterval) -> Bool 在指定时间点开始或恢复录制,并指定录制的持续时间。

  5、pause:暂停。stop:停止

  6、prepareToPlay:准备开始播放。如果play方法没有准备好时,会隐式先执行该方法。

  使用AVAudioRecorder录制视频的步骤如下:

  1、创建AVAudioRecorder对象。在创建AVAudioRecorder对象之前,先准备一个Dictionary对象,该对象中封装了音频的相关设置信息。

//创建字典,用于保存录制属性
let recordSettings:[String:Any] = [
//设置录制音频的格式
AVFormatIDKey:kAudioFormatAppleLossless,
AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue,
AVEncoderBitRateKey: ,
//设置录制音频的每个样点的通道数
AVNumberOfChannelsKey: ,
//设置录制音频的采样率
AVSampleRateKey: 44100.0
]

  2、如果需要监听录制完成、录制被中断的事件,则应该为AVAudioRecorder对象设置delegate对象,delegate对象需要实现AVAudioRecorderDelegate协议。

func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
print("录制完成")
stopBtn.isEnabled = false
playBtn.isEnabled = true
recordBtn.setTitle("录制", for: .normal)
//弹窗选择
let alert = UIAlertController(title: "录制", message: "录制完成", preferredStyle:.alert)
alert.addAction(UIAlertAction(title: "保存", style: .default, handler: {[unowned self] _ in
self.recorder = nil
}))
alert.addAction(UIAlertAction(title: "删除", style:.default, handler: { [unowned self] _ in
self.recorder.deleteRecording()
}))
self.present(alert, animated: true, completion: nil)
} func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder,
error: Error?) {
print("\(#function)") if let e = error {
print("\(e.localizedDescription)")
}
}

  3、调用AVAudioRecorder对象的record方法录制视频。

  案例代码:

import UIKit
import AVFoundation
import AVKit
class NAPublishViewController : UIViewController {
var recorder : AVAudioRecorder!
var player : AVAudioPlayer! var meterTimer : Timer!
var soundFileUrl : URL! lazy var recordBtn : UIButton = {
let recordBtn = UIButton()
recordBtn.setTitle("录音", for: .normal)
recordBtn.setTitleColor(.black, for: .normal)
recordBtn.addTarget(self, action: #selector(recordAction(sender:)), for: .touchUpInside)
return recordBtn
}() lazy var stopBtn : UIButton = {
let stopBtn = UIButton()
stopBtn.setTitle("停止", for: .normal)
stopBtn.setTitleColor(.black, for: .normal)
stopBtn.addTarget(self, action:#selector(stopBtnAction(sender:)) , for: .touchUpInside)
return stopBtn
}() lazy var playBtn : UIButton = {
let playBtn = UIButton()
playBtn.setTitle("播放", for: .normal)
playBtn.setTitleColor(.black, for: .normal)
playBtn.addTarget(self , action: #selector(playBtnAction(sender:)), for: .touchUpInside)
return playBtn
}() lazy var statusLabel : UILabel = {
let statusLabel = UILabel()
statusLabel.text = "00:00"
statusLabel.textColor = .black
return statusLabel
}() override func viewDidLoad() {
super.viewDidLoad()
setSubViewsConstraints() stopBtn.isEnabled = false
playBtn.isEnabled = false setSessionPlayback() } @objc func playBtnAction(sender:UIButton) -> Void {
var url: URL?
if self.recorder != nil {
url = self.recorder.url
} else {
url = self.soundFileUrl!
}
print("playing \(String(describing: url))") do {
self.player = try AVAudioPlayer(contentsOf: url!)
stopBtn.isEnabled = true
player.delegate = self
player.prepareToPlay()
player.volume = 1.0
player.play()
} catch {
self.player = nil
print(error.localizedDescription)
}
} @objc func stopBtnAction(sender:UIButton) -> Void {
recorder?.stop()
player?.stop() meterTimer.invalidate()
recordBtn.setTitle("录音", for: .normal)
let session = AVAudioSession.sharedInstance()
do {
try session.setActive(false)
playBtn.isEnabled = true
stopBtn.isEnabled = false
recordBtn.isEnabled = true
} catch {
print(error.localizedDescription)
}
} @objc func recordAction(sender:UIButton) -> Void {
if player != nil && player.isPlaying {
print("stopping")
player.stop()
} if recorder == nil {
recordBtn.setTitle("暂停", for: .normal)
playBtn.isEnabled = false
stopBtn.isEnabled = true
recordWithPermission(true)
return
} if recorder != nil && recorder.isRecording {
recorder.pause()
recordBtn.setTitle("继续", for: .normal)
} else {
recordBtn.setTitle("暂停", for: .normal)
playBtn.isEnabled = false
stopBtn.isEnabled = true
recordWithPermission(false)
} } func recordWithPermission(_ setup: Bool) {
AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
if granted {
DispatchQueue.main.async {
self.setSessionPlayAndRecord() if setup {
self.setupRecorder()
}
self.recorder.record() self.meterTimer = Timer.scheduledTimer(timeInterval: 0.1,
target: self,
selector: #selector(self.updateAudioMeter(_:)),
userInfo: nil,
repeats: true)
}
} else {
print("Permission to record not granted")
}
} if AVAudioSession.sharedInstance().recordPermission == .denied {
print("permission denied")
}
} func setupRecorder() {
let format = DateFormatter()
format.dateFormat="yyyy-MM-dd-HH-mm-ss"
let currentFileName = "recording-\(format.string(from: Date())).m4a"
print(currentFileName)
//获取沙盒文件目录
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[]
//拼接路径
self.soundFileUrl = documentsDirectory.appendingPathComponent(currentFileName)
print("writing to soundfile url: '\(soundFileUrl!)'") if FileManager.default.fileExists(atPath: soundFileUrl.absoluteString) {
print("soundfile \(soundFileUrl.absoluteString) 存在")
} //创建字典,用于保存录制属性
let recordSettings:[String:Any] = [
//设置录制音频的格式
AVFormatIDKey:kAudioFormatAppleLossless,
AVEncoderAudioQualityKey: AVAudioQuality.max.rawValue,
AVEncoderBitRateKey: ,
//设置录制音频的每个样点的通道数
AVNumberOfChannelsKey: ,
//设置录制音频的采样率
AVSampleRateKey: 44100.0
] do {
recorder = try AVAudioRecorder(url: soundFileUrl, settings: recordSettings)
recorder.delegate = self
recorder.isMeteringEnabled = true
recorder.prepareToRecord()
} catch {
recorder = nil
print(error.localizedDescription)
} }
func setSessionPlayAndRecord() {
//获取当前应用的音频会话
let session = AVAudioSession.sharedInstance()
do {
//设置音频类别,PlayAndRecord - 这说明当前音频会话既可播放,又可录制
try session.setCategory(AVAudioSession.Category.playAndRecord, options: AVAudioSession.CategoryOptions.defaultToSpeaker)
} catch {
print(error.localizedDescription)
} do {
try session.setActive(true)
} catch {
print(error.localizedDescription)
}
} func setSessionPlayback() {
//获取当前应用的音频会话
let session = AVAudioSession.sharedInstance() do {
//设置音频类别
try session.setCategory(AVAudioSession.Category.playback, options: AVAudioSession.CategoryOptions.defaultToSpeaker)
} catch {
print("不能设置session category")
print(error.localizedDescription)
} do {
//激活当前应用的音频会话
try session.setActive(true, options: AVAudioSession.SetActiveOptions.notifyOthersOnDeactivation)
} catch {
print("不能设置session active")
print(error.localizedDescription)
}
} @objc func updateAudioMeter(_ timer: Timer) { if let recorder = self.recorder {
if recorder.isRecording {
let min = Int(recorder.currentTime / )
let sec = Int(recorder.currentTime.truncatingRemainder(dividingBy: ))
let s = String(format: "%02d:%02d", min, sec)
statusLabel.text = s
recorder.updateMeters()
}
}
} func setSubViewsConstraints() -> Void {
view.addSubview(recordBtn)
recordBtn.snp.makeConstraints { (make) in
make.left.width.height.equalTo()
make.top.equalTo()
} view.addSubview(stopBtn)
stopBtn.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.width.height.equalTo()
make.top.equalTo()
} view.addSubview(playBtn)
playBtn.snp.makeConstraints { (make) in
make.right.equalTo(-)
make.width.height.equalTo()
make.top.equalTo()
} view.addSubview(statusLabel)
statusLabel.snp.makeConstraints { (make) in
make.centerX.equalToSuperview()
make.width.height.equalTo()
make.top.equalTo(stopBtn.snp_bottom).offset() }
} override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
recorder = nil
player = nil
}
} extension NAPublishViewController : AVAudioRecorderDelegate { func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
print("录制完成")
stopBtn.isEnabled = false
playBtn.isEnabled = true
recordBtn.setTitle("录制", for: .normal)
//弹窗选择
let alert = UIAlertController(title: "录制", message: "录制完成", preferredStyle:.alert)
alert.addAction(UIAlertAction(title: "保存", style: .default, handler: {[unowned self] _ in
self.recorder = nil
}))
alert.addAction(UIAlertAction(title: "删除", style:.default, handler: { [unowned self] _ in
self.recorder.deleteRecording()
}))
self.present(alert, animated: true, completion: nil)
} func audioRecorderEncodeErrorDidOccur(_ recorder: AVAudioRecorder,
error: Error?) {
print("\(#function)") if let e = error {
print("\(e.localizedDescription)")
}
}
} extension NAPublishViewController : AVAudioPlayerDelegate {
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { recordBtn.isEnabled = true
stopBtn.isEnabled = false
} func audioPlayerDecodeErrorDidOccur(_ player: AVAudioPlayer, error: Error?) {
print("\(#function)") if let e = error {
print("\(e.localizedDescription)")
} }
}

使用AVAudioRecorder进行录制视频

  运行效果图:

iOS音频与视频的开发(二)- 使用AVAudioRecorder进行录制音频的更多相关文章

  1. iOS音频与视频的开发(一)-使用AVAudioPlayer播放音乐、使用AVPlayerViewController播放视频

    iOS的多媒体支持非常强大,它提供了多套支持多媒体的API,无论是音频.视频的播放,还是录制,iOS都提供了多种API支持.借助于这些API的支持,iOS应用既可以查看.播放手机相册中的照片.视频,也 ...

  2. Android 音视频开发(二):使用 AudioRecord 采集音频数据并保存到文件

    版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/7457321.html 一.AudioRecord API详解 AudioRecord是Android系统提 ...

  3. Android 音视频开发(二):使用 AudioRecord 采集音频PCM并保存到文件

    版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/7457321.html 一.AudioRecord API详解 AudioRecord是Android系统提 ...

  4. html5页面怎么播放音频和视频

    html5页面怎么播放音频和视频 一.总结 一句话总结:html5 音频和视频标签:(audio And video),局限是不同浏览器对音频视频的格式支持很让人头痛 1.最基础的音频和视频标签的使用 ...

  5. 《转》iOS音频视频初级开发

    代码改变世界 Posts - 73, Articles - 0, Comments - 1539 Cnblogs Dashboard Logout HOME CONTACT GALLERY RSS   ...

  6. Android IOS WebRTC 音视频开发总结(二九)-- 安卓噪声消除交流

    Android上的音质一直被大家所困扰和诟病,这里面有很多原因, 下面是最近一位前UC同行发邮件跟我交流的一些记录,供参考,支持原创,文章来自博客园RTC.Blacker,转载请说明出处. 以下文字来 ...

  7. 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)

    随笔分类 - webrtc   Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...

  8. iOS开发-二维码扫描和应用跳转

    iOS开发-二维码扫描和应用跳转   序言 前面我们已经调到过怎么制作二维码,在我们能够生成二维码之后,如何对二维码进行扫描呢? 在iOS7之前,大部分应用中使用的二维码扫描是第三方的扫描框架,例如Z ...

  9. Android IOS WebRTC 音视频开发总结(四九)-- ffmpeg介绍

    本文主要介绍ffmpeg,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,个人微信公众号blacker,更多详见www.rtc.help 说明: ps1:如果直接从webrtc开始学 ...

随机推荐

  1. vim note (1)

    'vim' go into the vim mode 'i' 'a' 's'    is means insert mode 'v' is means visual mode 'esc' is mea ...

  2. BusHelper

    https://github.com/eltld/-BusHelper https://github.com/eltld/BusLineSAX

  3. libusb 源码阅读

    libusb_init(NULL), 如果传入一个NULL, 则libusb 内部会有一个 usbi_default_context 变量在内部保存上下文. 这样以后调用 libusb 函数时可以不指 ...

  4. iOS RAC常用方法

    一直想写篇关于RAC的文章,一是分享二是做为笔记,由于项目忙先简单的贴一个自己当初学习的时候代码吧 一.RACCommand // RACCommand 的使用: 使用场景,监听按钮点击,网络请求 - ...

  5. java sleep和wait的区别和联系

    Thread.sleep不会改变锁的行为,如果当前线程拥有锁,那么当前线程sleep之后,该锁不会被释放. Thread.sleep和Object.wait都会暂停当前的线程,让出cpu.Thread ...

  6. Studio 3T for MongoDB连接51.212复制集

    Studio 3T for MongoDB连接51.212复制集 [ #DirectConection Authentication Mode - Basic(MONGODB-CR or SCEAM- ...

  7. Cocos2d-js异步图片加载

    这里说的是在需要的使用加载图片,比如游戏中的某个关卡的图片,不用在游戏一开始就加载(万一用户玩不到那关,岂不是很冤,流量费了那么多),否则 载入速度也慢.这种方式加载资源要用到cc.loader官方文 ...

  8. Android 的assets文件资源与raw文件资源读取

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zpf8861/article/details/34504183   res/raw和assets的同 ...

  9. kaminari分页插件样式

    修改国际化文件,zh-cn views: pagination: first: "首页" last: "尾页" previous: "上一页" ...

  10. uptime详解,最通俗的说明了cpu平均负载

    今天又个网友问uptime的三个平均负载值具体要怎么理解,发现要自己解释还真不知道怎么表达~~~~,下面到网上找了篇文章给大家分享:   uptime命令,有两大用处,一个是看您的机器的运行时间,另一 ...