AVFounction学习笔记之–音视频播放

AVFounction是用于处理音视频的框架。它位于Core Audio、Core Video、Core Media、Core Animation框架之上。
Core Audio是处理所有音频事件的框架。为音频提供录制、播放、处理等接口。
Core Video是针对视频处理的框架。为框架Core Media提供图片缓存和缓存池的支持。
Core Media 提供音频样本和视频帧处理需要的数据类型和接口。它还提供了AVFounction用到的基于CMTime数据类型的时基模型。
Core Animation用于处理动画相关的框架。

AVSpeechSynthesizer

AVSpeechSynthesizer实现文本转语音的功能。

import AVFoundationclass SpeechSynthesizerViewController: UIViewController {private let speechSynthesizer = AVSpeechSynthesizer()private let voices: [AVSpeechSynthesisVoice] = [AVSpeechSynthesisVoice(language: "en-US")!, AVSpeechSynthesisVoice(language: "en-GB")!]private let speechString: [String] = ["The forum, which will bring together over 1,000 delegates, will be attended by special guests including the former French Prime Minister Jean-Pierre Raffarin, the 2011 Nobel Prize winner for Economics Thomas J.", "Sargent, and Zhu Yeyu, the vice3 president of the Hong Kong University of Science and Technology.", " Co-hosted by China Media Group and the People's Government of Guangdong Province, the forum will showcase the achievements of Guangdong Province in becoming a major gateway4 linking China with the world.", "The province also provides an example of the benefits of China's policy of Reform and Opening Up, which celebrates its 40th anniversary this year."]override func viewDidLoad() {super.viewDidLoad()// 获取所有声音支持列表print(AVSpeechSynthesisVoice.speechVoices())}@IBAction func clickPlay(_ sender: UIButton) {for index in 0..<speechString.count {let utterance = AVSpeechUtterance(string: speechString[index])utterance.voice = voices[index % 2]utterance.rate = 0.4utterance.pitchMultiplier = 0.8utterance.postUtteranceDelay = 0.1speechSynthesizer.speak(utterance)}}
}

播放和录制音频

音频会话分类表:

分类 作用 是否允许混音 音频输入 音频输出
Ambient 游戏、效率应用软件
Solo Ambient(默认) 游戏、效率应用软件
Playback 音频和视频播放器 可选
Record 录音机、音频捕捉
Play and Record VoIP、语音聊天 可选
Audio Processing 离线会话和处理
Multi-Route 使用外部硬件的高级A/V应用程序
  • 使用AVAudioPlayer播放本地音频

AVAudioPlayer可以实现音频的播放、循环、音频计量等,除非需要从网络流中播放音频、需要访问原始音频样本或者需要非常低的时延等,AVAudioPlayerdo都能胜任。

AVAudioPlayer功能:
1、修改播放器的音量
2、修改播放器的Pan值,允许立体声播放声音,范围(-1.0~1.0)
3、调整播放率,范围(0.5~2.0),半速到2倍速
4、通过设置numberOfLoops属性实现音频无缝循环,n大于0,实现循环n次循环,-1为无限循环
5、进行音频计量,获取播放音频力度的平均值和峰值

private func settingSession() {// 配置音频会话let audioSession = AVAudioSession.sharedInstance()do {try audioSession.setCategory(AVAudioSessionCategoryPlayback)try audioSession.setActive(true)} catch let error {print("error = \(error)")}// 配置音频后台播放// 在info.plist 中添加  Required background modes  item = App plays audio or streams audio/video using AirPlay
}// MARK: - AVAudioPlayerprivate func audioPlayer() {// AVAudioPlayer 播放音频let url = Bundle.main.url(forResource: "test", withExtension: "mp3")do {player = try AVAudioPlayer.init(contentsOf: url!)// 制造和处理中断事件  例如: 当有电话呼入的时候NotificationCenter.default.addObserver(self, selector: #selector(handleNotification(_:)), name: .AVAudioSessionInterruption, object: nil)// 音频线路改变的通知 例如插入耳机NotificationCenter.default.addObserver(self, selector: #selector(handleRouteNotification(_:)), name: .AVAudioSessionRouteChange, object: nil)player?.prepareToPlay()} catch let error {print("error = \(error)")}}@IBAction func clickPlayMp3(_ sender: Any) {player?.play()}@objc func handleNotification(_ sender: Notification) {let info = sender.userInfo!let type = info["AVAudioSessionInterruptionTypeKey"] as! UIntif type == AVAudioSessionInterruptionType.began.rawValue {print("开始")player?.pause()} else {print("结束")player?.play()}}@objc func handleRouteNotification(_ sender: Notification) {let info = sender.userInfo!let reasonKey = info["AVAudioSessionRouteChangeReasonKey"] as! UIntif AVAudioSessionRouteChangeReason.oldDeviceUnavailable.rawValue == reasonKey  {print("耳机取出, 暂停播放")player?.pause()}}
  • 使用AVAudioRecorder录制音频

AVAudioRecorder 支持无限时长的录制,支持录制一段时间后暂停,再从这个点开始继续录制。

录制音频关键步骤:
1、提供本地存储文件的URL
2、配置录制音频会话的信息
3、容错处理

private func settingSession() {// 配置音频会话let audioSession = AVAudioSession.sharedInstance()do {try audioSession.setCategory(AVAudioSessionCategoryPlayback)try audioSession.setActive(true)} catch let error {print("error = \(error)")}
}// MARK: - AVAudioRecorder
private func audioRecorderDemo() {// 需要在info.list中配置麦克风权限let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.allDomainsMask, true).last! + "/voice.caf"let url = URL(fileURLWithPath: path)do {/*AVFormatIDKey 音频格式AVSampleRateKey 采样率AVNumberOfChannelsKey 声道数*/recoder = try AVAudioRecorder.init(url: url, settings: [AVFormatIDKey : kAudioFormatAppleIMA4, AVSampleRateKey: 44100.0, AVNumberOfChannelsKey: 1, AVEncoderBitDepthHintKey: 16, AVEncoderAudioQualityKey: AVAudioQuality.medium])recoder?.prepareToRecord()recoder?.delegate = self// 开启音频数据测量
//            recoder?.isMeteringEnabled = true// 获取音频平均分贝值的大小 0 ~ -160db
//            recoder?.averagePower(forChannel: <#T##Int#>)// 获取音频峰值分贝数据大小
//            recoder?.peakPower(forChannel: <#T##Int#>)} catch let error {print("error = \(error)")}
}@IBAction func clickRecoder(_ sender: Any) {print("开始录制")recoder?.record()
}@IBAction func pauseRecoder(_ sender: Any) {recoder?.pause()print("暂停录制")
}@IBAction func stopRecoder(_ sender: Any) {recoder?.stop()print("结束录制")
}extension ViewController: AVAudioRecorderDelegate {func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {print("录制音频停止 对录制的音频做处理,保存?删除? audioRecorderDidFinishRecording")}
}

视频播放

  • 基础知识

AVPlayer是AVFounction中的核心播放类,但是它是一个不可见的组件,需要AVPlayerLayer来显示播放界面。AVPlayer是一个单独资源的播放,如何需要在一个序列中播放多个条目需要用AVQueuePlayer来实现。

AVPlayerLayer构建在Core Animation上用于视频内容的渲染界面。

AVPlayerItem会建立媒体资源动态数据模型,可以获取播放视频中的curretTime和presentationSize等多个动态属性。

  • 示例代码
private var avPlayer: AVPlayer!
private var playerItem: AVPlayerItem!
private var asset: AVAsset!
private var imageGenerator: AVAssetImageGenerator!override func viewDidLoad() {super.viewDidLoad()let url = Bundle.main.url(forResource: "Test", withExtension: "mov")// 网络视频// let url = URL.init(string: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")asset = AVAsset(url: url!)playerItem = AVPlayerItem(asset: asset)playerItem.addObserver(self, forKeyPath:"status", options: [NSKeyValueObservingOptions.old, NSKeyValueObservingOptions.new] , context: nil)avPlayer = AVPlayer(playerItem: playerItem)let playerView = PlayerView.init(UIScreen.main.bounds, avPlayer)view.addSubview(playerView)avPlayer.play()}override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {if playerItem.status == .readyToPlay {print("readyToPlay")// 设置播放监听// 监听时间addPlayerItemTimeObserver()// 监听视频播放完成addItemEndObserverForPlayerItem()// 获取视频指定时间点的缩略图getGenerateThumbnails()// 获取字幕信息loadMediaOptions()}
}private func loadMediaOptions() {// 获取视频包含的字幕信息let gropup = asset.mediaSelectionGroup(forMediaCharacteristic: AVMediaCharacteristic.legible)if let gropup = gropup {var subtitles: [String] = Array()for item in gropup.options {print("displayName = \(item.displayName)")subtitles.append(item.displayName)}} else {print("gropup = nil, 没有字幕信息")}}private func getGenerateThumbnails() {imageGenerator = AVAssetImageGenerator(asset: asset)// 设置生成图片的宽高imageGenerator.maximumSize = CGSize(width: 200, height: 0)// 获取20张缩略图let duration = asset.durationvar times: [NSValue] = Array()let increment = duration.value / 20var currentValue = kCMTimeZero.valuewhile currentValue <= duration.value {let time = CMTimeMake(currentValue, duration.timescale)times.append(NSValue.init(time: time))currentValue += increment}var images: [UIImage] = Array()imageGenerator.generateCGImagesAsynchronously(forTimes: times) { (requestedTime, cgImage, actualTime, result, error) inif result == AVAssetImageGeneratorResult.succeeded {let image = UIImage(cgImage: cgImage!)images.append(image)// 将图片更新到UI组件} else {print("生成缩略图失败")}}
}private func addItemEndObserverForPlayerItem() {NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: OperationQueue.main) { (notification) inprint("播放完成")}
}// 监听播放时间
private func addPlayerItemTimeObserver() {/*监听时间1、定期监听 利用AVPlayer的方法 addPeriodicTimeObserverForInterval:<#(CMTime)#> queue:<#(nullable dispatch_queue_t)#> usingBlock:<#^(CMTime time)block#>2、边界时间监听 利用AVPlayer的方法定义边界标记 addBoundaryTimeObserverForTimes:<#(nonnull NSArray<NSValue *> *)#> queue:<#(nullable dispatch_queue_t)#> usingBlock:<#^(void)block#>*/// 定义0.5秒时间间隔来更新时间let time = CMTimeMakeWithSeconds(0.5, Int32(NSEC_PER_SEC))avPlayer.addPeriodicTimeObserver(forInterval: time, queue: DispatchQueue.main) { [weak self] (time) inlet currentTime = CMTimeGetSeconds(time)let duration = CMTimeGetSeconds((self?.playerItem.duration)!)print("更新当前播放的时间 = \(currentTime), 视频总时长 = \(duration)")}
}deinit {NotificationCenter.default.removeObserver(self)
}
  • 利用AVKit播放视频

AVKit是iOS8新出的一个框架,可用于快速构建一个简单的播放功能。在MediaPlayer框架中的MPMoviePlayerViewController也有类似的功能,只不过在iOS9.0已经废弃了。

// 播放视频就是这么简单
let avplayer = AVPlayerViewController()
// 是否显示底部播放控制条
avplayer.showsPlaybackControls = false
let url = Bundle.main.url(forResource: "Test", withExtension: "mov")
avplayer.player = AVPlayer(url: url!)
avplayer.view.frame = UIScreen.main.bounds
view.addSubview(avplayer.view)
avplayer.player?.play()

AVFounction学习笔记之--音视频播放.md相关推荐

  1. HTML5学习笔记之音视频标签

    HTML5学习笔记之音视频标签 其他HTML5相关文章 HTML5学习笔记之HTML5基本介绍 HTML5学习笔记之基础标签 HTML5学习笔记之表格标签 HTML5学习笔记之表单标签 HTML5学习 ...

  2. 学习笔记-抖音分析报告

    学习笔记-产品分析报告-抖音 一. 产品概述 1. 背景 2. 体验环境 3. 产品概括 4. 产品定位 5. 用户需求分析 6. 市场现状和分析 7. 竞品分析 二. 产品分析 1. 产品结构图 2 ...

  3. spring-狂神学习笔记-联系我获取md文档

    1.Spring(概述) 1.1.简介 Spring:春---->给软件行业带来了春天 2002,首次推出了Spring框架的雏形: interface21框架 Spring框架即以interf ...

  4. 播放视频android学习笔记---44_在线视频播放器,网络视频解析器,SurfaceView 控件使用方法...

    最近用使开辟的过程中涌现了一个小题问,顺便录记一下因原和法方--播放视频 44_在线视频播放器 ------------------------- 1.注意这里,在模拟器中,android2.2和an ...

  5. android学习笔记---44_在线视频播放器,网络视频解析器,SurfaceView 控件使用方法

    44_在线视频播放器 ------------------------- 1.注意这里,在模拟器中,android2.2和android2.1视频是没有播放效果的,这个主要是因为模拟器的原因和程序代码 ...

  6. 法语初级学习笔记-01-语音

    字母表 A/ɑ/A/ɑ/A/ɑ/ B/be/B/be/B/be/ C/se/C/se/C/se/ D/de/D/de/D/de/ E/ə/E/ə/E/ə/ F/ɛf/F/ɛf/F/ɛf/ G/ʒe/G ...

  7. 各种音视频编解码学习详解之 编解码学习笔记(四):Mpeg系列——Mpeg 4

    最近在研究音视频编解码这一块儿,看到@bitbit大神写的[各种音视频编解码学习详解]这篇文章,非常感谢,佩服的五体投地.奈何大神这边文章太长,在这里我把它分解成很多小的篇幅,方便阅读.大神博客传送门 ...

  8. Java中如何创建自定义的注解学习笔记(MD版)

    概要 Java中如何创建自定义的注解学习笔记(MD版). 博客 博客地址:IT老兵驿站. 前言 记得这篇笔记还是在泉州的龙玲酒店记录的,是一个周六的晚上,坐飞机从上海到泉州,从笔记中能勾起一些旅游的回 ...

  9. NDK学习笔记:一起来变萝莉音!FMOD学习总结(下)

    NDK学习笔记:一起来变萝莉音!FMOD学习总结(下) 一.创建自己的变音demo 上一节我已经能够在AndroidStudio上跑起了fmod的基础教程.还有疑问的同学可以重新阅读跟着来跑一次.这章 ...

最新文章

  1. Python 字符串及基本语句
  2. 初识 ElasticSearch,一个上天下地的搜索引擎 No.158
  3. 漫谈视频目标跟踪与分割
  4. 小猿圈自学web前端之CSS3动画练习案例:用CSS3做个钟表
  5. 嵌入式移植NTP(Network Time Protocol)
  6. 获取win7时区所有信息
  7. 【python科学计算发行版】
  8. DotNet操作Excel汇总
  9. C语言之设计模式——单例模式
  10. 《Python游戏趣味编程》 第6章 见缝插针
  11. 小程序实现“类吸顶”效果交流处
  12. 使用matplotlib绘制K线图以及和成交量的组合图
  13. Leetcode804.Unique Morse Code Words唯一摩尔斯密码词
  14. eclipse mars2汉化包下载
  15. CSS 实现炫酷的动态背景效果
  16. 计算机专业硕士论文评语,硕士论文评审意见范文
  17. matlab-高数 diff 方向导数
  18. 100Mbps 和 100Mb/s 单位Mbps和Mb/s有什么不同
  19. windows使用scp远程传输文件的方法
  20. 怎样用android平板玩和平精英不卡,和平精英:难怪有那么多人喜欢用平板玩游戏,优势很大,一起来看看吧...

热门文章

  1. 新研究挑战DNA随机突变进化理论
  2. 中国医护服装制造行业投资前景与盈利能力分析报告2022版
  3. C#在Pdf画统计图表之【雷达图】(以五边形为例)
  4. 有没有测试游戏天赋的软件,测测你的电竞天赋有多高游戏-抖音测测你的电竞天赋有多高官网版游戏V1.0...
  5. DENdb:human增强子数据库
  6. 金富瑞UCML2.0应用框架平台 for Asp.Net WEB 开发平台
  7. mysql练习-数据库安全性与完整性
  8. 腾讯云轻量2核4G/4核8G/8核16G/16核32G服务器配置详解
  9. 2022年龙岩市高新技术企业奖励补贴,高企网上申报流程是什么?
  10. Debian 7.x 安装教程、网络配置、软件源配置、磁盘分区、LVM、U盘安装、网络安装...