收藏 分销(赏)

iOS_AVFoundation视频播放探究_白亚辉.pdf

上传人:自信****多点 文档编号:230628 上传时间:2023-03-20 格式:PDF 页数:6 大小:1.78MB
下载 相关 举报
iOS_AVFoundation视频播放探究_白亚辉.pdf_第1页
第1页 / 共6页
iOS_AVFoundation视频播放探究_白亚辉.pdf_第2页
第2页 / 共6页
iOS_AVFoundation视频播放探究_白亚辉.pdf_第3页
第3页 / 共6页
iOS_AVFoundation视频播放探究_白亚辉.pdf_第4页
第4页 / 共6页
iOS_AVFoundation视频播放探究_白亚辉.pdf_第5页
第5页 / 共6页
点击查看更多>>
资源描述

1、53软件开发与应用Software Development&Application电子技术与软件工程Electronic Technology&Software Engineering我们开发中很多地方会用到视频播放功能,对于 iOS 平台视频播放大致分为两大类:使用苹果的官方 API 实现视频播放功能。(AVKit,AVFoundation)和使用集成 ffmpeg 框架的第三方库。(ijkplayer,kxmovie 等)。本文现只针对第一种方式做简单的探究。播放一段本地的视频我们貌似可以通过以下几种方法实现。一是通过在 APP 中嵌套 WebView(UIWebView,WKWebVie

2、w)加载 Html5 标签 Video 来实现视频播放的功能。二是通过 AVKit 框架实现视频播放。三是通过底层AVFoundation 框架实现视频播放。实际上,无论哪种方式归根结底仍然离不开底层 AVFoundation 的身影。1 Html5 video标签播放视频特 殊 说 明:基 于 mediaPlayer 类 库 的 MPMediaPlayer Controller(iOS9 后 遭 到 废 弃,被 AVPlayerViewController所 替 代)iOS8 之 后 苹 果 推 荐 使 用 WKWebView 替 代UIWebView,其主要的优点有:(1)WKWebVie

3、w 更多的支持 HTML5 的特性;(2)WKWebView 更快,占用内存可能只有 UIWebView的 1/3 1/4;(3)WKWebView 高达 60fps 的滚动刷新率和丰富的内置手势;(4)WKWebView 具有 Safari 相同的 JavaScript 引擎;(5)WKWebView 增加了加载进度属性将;(6)UIWebViewDelegate 和 UIWebView 重 构 成 了 14个类与 3 个协议。1.1 使用方式通过 webView 嵌套 html 的 video 标签实现视频播放,如下:!DOCTYPE HTML Your browser does not

4、support the video tag.需 要 我 们 做 的 只 是 简 单 的 在 我 们 的 视 图 中 添 加UIWebView(WKWebView)然后调用加载方法去加载 html 文件即可。代码如下:webView=WKWebView(frame:self.view.frame);let path=Bundle.main.path(forResource:movieHtml,ofType:html);let request=URLRequest.init(url:URL(fileURLWithPath:path!)webView?.load(request);self.view

5、.addSubview(webView!);该例当中加载了一个本地html文件播放本地视频文件,实际当中也可以加载自己服务器端的 html 文件播放服务端视频文件。1.2 原理分析首先我们要了解一个概念 WebKit,WebKit 是一个开源的浏览器引擎,我们在浏览器中能够看到各种各样的网页就是因为 WebKit 帮助我们解析 html 代码呈现给我们。很多浏览器包括 safar,Chrome 就是一款基于 WebKit 的浏览器,在我们的 app 中无论原有的 UIWebView 还是现有的WKWebView 其内核也是基于 WebKit 的。有一点我们应当知道,由于各个平台软硬件的不同,不

6、同平台下 WebKit 也有不同的 WebKit port。下面是不同 WebKit por 的异同:WebKit port 共同之处:(1)DOM、winow、document;(2)CSS 对象模型;(3)CSS 解析,键盘事件处理;(4)HTML 解析和 DOM 构建;(5)所有的布局和定位;(6)Chrome开发工具和WebKit检查器的UI与检查器;(7)contenteditable、pushState、文 件 API、大 多 数SVG、CSS Transform math、Web Audio API、localStorage 等功能;(8)很多其他功能与特性。WebKit por

7、t 不同之处:iOS AVFoundation 视频播放探究白亚辉(中国人民武装警察部队河北省总队 河北省石家庄市 050000)摘要:本文主要介绍 iOS 平台下视频播放的几种方式及其常见问题。结合代码与框架深入探究视频播放的整个过程及其原理。关键词:视频播放;iOS;AVFoundation;AVKit;WKWebView54软件开发与应用Software Development&Application电子技术与软件工程Electronic Technology&Software Engineering(1)GPU 相关技术;(2)3D 转换;(3)WebGL;(4)视频解码;(5)将 2

8、D 图像绘制到屏幕;(6)解析方式;(7)SVG 和 CSS 渐变绘制;(8)文字绘制和断字;(9)网络层(SPDY、预渲染、WebSocket 传输);(10)JavaScript 引擎;(11)JavaScriptCore 在 WebKit repo 中。V8 和 JavaScript Core 被绑定在 WebKit 中;(12)表单控制器的渲染;(13)和 的元素表现和解码实现;(14)图像解码;(15)页面导航 前进/后退;(16)pushState()的导航部分;(17)SSL 功能,比如 Strict Transport Security 和 Public Key Pins。从上

9、面可以得知 WebKit 在不同平台下其 和 的元素表现和解码实现并不相同,这也是为什么同样是 标签在 safari 当中和在 Chrome 当中呈现却不同的原因。WebKit 的视频播放流程实际上也是 WebKit 对html5 标签 video 的解析过程。如果我们的 WebView html 标签中用到 video 标签,首先 WebKit 帮我们解析出 video 标签呈现出来,然后我们点击播放按钮,WebKit将事件分发下去,交给设给底层视频模块处理,最后视频开始播放。通过 instrument 可以大致了解其调用堆栈情况,如图 1,可以看到其实质上最后还是调用了 AVKit 框架下

10、的 AVplayerViewController 来实现视频的播放。综上,这种用html 方式播放视频其实本质上是通过 webview 内核 WebKit实现的视频标签video解析然后传递到底层去进行视频播放,这种播放过程交给 AVKit 框架来实现。2 AVKit播放视频关 于 AVKit 苹 果 官 方 给 的 解 释 是“Create view-level 图 1:AVKit 框架图 2:AVKit 框架引用关系55软件开发与应用Software Development&Application电子技术与软件工程Electronic Technology&Software Enginee

11、ringservices for media playback,complete with user controls,chapter navigation,and support for subtitles and closed captioning.The AVKit framework provides a high-level interface for playing video content.”大致意思为:为媒体播放创建视图层级的服务,包括用户控制,章节导航,并且支持副标题,隐藏字幕。AVKit framework 为播放视频能容提供了一个高级的接口。AVKit 框架是 Appl

12、e 为我们提供的一个视频播放高级框架,iOS8 以后可以使用,基于 AVFoundation 实现。AVKit高度封装,可以简化我们的播放视频的过程,当然也会带来一些的弊端,一些高度定制化的功能通过 AVKit 无法实现,例如视频编辑等。那么 AVKit 为我们提供了哪些类,这些类能帮助我们做什么呢?通过查看其引用关系我们应该能大致了解其功能。如 iOS 中的 AVKit 框架引用关系如图 2(iOS 10.3 其中带小旗子的部分为 class 引入方式)。可以看到 AVKit 框架下涉及到的类并不多。主要的只有两个AVPictureInPictureController 和AVPlayerV

13、iewController,其 中 AVPictureInPictureController 用 于 画 中 画 的 相 关 实现。AVPlayerViewController 用于视频播放,AVPlayerView Controller 为我们提供了一个带简单操作条的视频界面。2.1 使用方法通过播放一段本地视频的方法如下:let path=Bundle.main.path(forResource:movie,ofType:mp4);let player=AVPlayer.init(url:URL.init(fileURLWithPath:path!);let playerVC=BAVPla

14、yerViewController();playerVC.player=player;self.present(playerVC,animated:true);其 中 BAVPlayerViewController 继 承 自 AVPlayerView Controller 之所以这样做是因为后面我们会在这个类中做一些视频控制界面的改变(这些改变必须在视图加载后,比如contentOverlayView 要在 viewDidLoad 之后才能获取到)。如果不想做任何修改直接用 AVPlayerViewController 即可。在 iphone 与 iPad 上运行会有些许不同,ipad 上比

15、 iPhone上右下角会多处一个画中画的操作按钮。点击后可进入画中画模式。画中画模式是 iOS9 添加的一个功能,可以通过AVPlayerViewController 的 allowsPictureInPicturePlayback 属性进行控制,默认为 true。2.2 修改视频界面可以看到 AVPlayerViewController 为我们提供的播放界面并不是那么美观。在实际应用也很可能会与我们设计的 app 主题不符,影响用户体验。所以通常情况下我们会对播放界面做相应的修改。修改之前我们先了解下下AVPlayerViewController 的几个重要属性。(1)player:用户播放

16、视频的主要控件。需要初始化后丢入到 AVPlayerViewController。(2)showsPlaybackControls:用于控制是否显示系统默认的控制条。(3)videoGravity:定义了视频应该怎样在 AVPlayer Layer 中显示的字符串,包括 AVLayerVideoGravityResize Aspect(默 认)、AVLayerVideoGravityResizeAspectFill、AVLayerVideoGravityResize 三种。(4)contentOverlayView:一个处于控制视图和视频视图中间的 view,用来添加额外定义的视图。(5)al

17、lowsPictureInPicturePlayback:是否允许画中画模式。我们可能会有一个思路是通过隐藏系统的控制条,然后在 contentOverlayView 添加自己的视图来自定义控制条。事实上这样可能并不能很好的解决我们的问题。contentOverlayView 可以显示我们需要添加的控件,但是它并不能响应事件。通常这种情况会有下面几种可能:(1)view 本身设置 isUserInteractionEnabled=false;(2)view 父控件设置 isUserInteractionEnabled=false;(3)view 前方有其他控件遮挡。所以我们设置 self.co

18、ntentOverlayView?.isUserInteraction Enabled=true;self.contentOverlayView?.superview?.isUser InteractionEnabled=true;验证后仍然无妨响应事件。为了验证遮盖问题我们有必要了解下播放视频时的 view 层次图,如图 3(基于 iOS10.3)。从图 3 中可以看到我们使用的 contentOverlayView 前面确实会存在两个 view,一个 AVTouchIgnoringView 从字面意思理解不处理触摸事件的 view(透明的 UIView),也就是这个 view 会将事件传递

19、的其后面的 view(根据进度条 view可以响应事件也可以推断 AVTouchIgnoringView 并不会拦截图 3:View 层次图56软件开发与应用Software Development&Application电子技术与软件工程Electronic Technology&Software Engineering我们的事件)。另一个用于显示系统进度条的 UIView,这个view 可以响应用户事件,我们 contentOverlayView 无法响应事件应该是这个 view 响应了用户事件,导致响应链无法向下传递,也就无法传递到后面的 contentOverlayView。那么我们是

20、不是可以在这个 view 上做一些自定义控件呢,很遗憾我们并不能 get 到这个 view。使用 playerViewController.view.subviews0.subviews0.subviews1 这种方式获取某个view 并不是很好的方式,因为随着 sdk 的更新这个层次机构并不能保证会一成不变。我们虽然无法使用 contentOverlayView 达到我们想要的效果,但是 contentOverlayView 并不是一个毫无用处的view。实际中我们仍然能用它呈现一些无需与用户交互的界面。比如直播过程的字幕,送礼礼物动画等(暂且不论其好坏),我们再回头品味 Apple 对 c

21、ontentOverlayView 解读:“Use the content overlay view to add additional custom views between the video content and the controls.”其中 between the video content and the controls,或许苹果也不并希望我们将控制放到 contentOverlayView 当中。修改界面的另一个思路:在我们 AVPlayerViewController初始化的过程中,系统会为我们创建了一个 AVPlayerView,然 后 将 这 个 view 添 加

22、到 self.view 当 中。如 果 我 们 无法 在 AVPlayerView 当 中 去 修 改 界 面,那 么 我 们 只 能 在AVPlayerView 上面在添加一个控制层了。当然这样这个控制层就遮盖了原来的控制层 view,其上的双击放大,单击隐藏进度条功能就会消失。这一部分得靠自己去实现了。事实上 AVPlayerView 是苹果为我们封装的一个播放界面,我们完全可以不用 AVPlayerView,去实现自定义界面,这就更接近底层了,我们会在 AVFoundation 播放视频时介绍。在我们自定义界面的时候不免会设计到对视频的控制,比如暂停、开始、跳转。或是一些视频数据的现实问

23、题,这些一般通过 AVPlayerViewController 为我们提供 player 可以做到。通过前面的了解,我们知道 AVKit 框架播放视频其事只是做了两件事:一提供了画中画相关功能。二提供一个viewController,自带并不是很美观的视频播放界面。(修改界面可以做到,但实现方式却比较 low)。真正做到视频播放的其实是 AVPlayer,而 AVPlayer 是 AVFoundation 框架的主要角色之一,所以 AVKit 视频播放其实也是 AVFoundation视频播放过程。3 AVFoundation框架播放视频首先看一下苹果官方网站 AVFoundation 的定义

24、如下:AVFoundation is one of several frameworks that you can use to play and create time-based audiovisual media.It provides an Objective-C interface you use to work on a detailed level with time-based audiovisual data.For example,you can use it to examine,create,edit,or reencode media files.You can al

25、so get input streams from devices and manipulate video during realtime capture and playback.大致意思为:AVFoundation 是几款你可以用来播放和创建基于时间视听媒体的框架之一。它提供了一个用来处理视听媒体数据 Objective-C 接口。比如你可以用它来检查、创建、编辑或着重编码媒体文件,你也可以用它从设备获得输入流,在实时拍摄、播放录像时操作视频。AVFoundation 在 iOS 中所处的位置如图 4 所示。可以看出 AVFoundation 框架处于一个比较低级(相对 UIKit)位

26、置。建 立 在 Core Audio、Core Media、Core Animation 之上。3.1 使用方法最简单的方式只需要(1)生成 AVplayer;(2)生成 AVplayerLayer;(3)将 AVplayerLayer 添加到 view 的 layer 上;(4)AVplayer 调用 play 方法。就像下面这样就像下面这样let vc=UIViewController();/player 的初始化可以通过 playerItem 生成let path=Bundle.main.path(forResource:movie,ofType:mp4);let player=AVPl

27、ayer(url:URL.init(string:path!)!);let layer=AVPlayerLayer.init(layer:player);vc.view.layer.addSublayer(layer);self.present(vc,animated:true)player.play();3.2 自定义界面可能遇到的问题图 4:AVFoundation 在 iOS 中所处的位置57软件开发与应用Software Development&Application电子技术与软件工程Electronic Technology&Software Engineering上述这样就能实现视

28、频的播放了,但是没有控制条。这就需要我们自己去实现了。具体细节不再详细赘述,实现过程中可能会遇到的问题:问题一:屏幕旋转后视频界面不能自适应问题。问题二:视频进度视频总时间显示问题。因为 layer 不支持 autolayout 所以针对问题一比较简单的方法是:自定义一个 view 改变这个 view 的 classLayer为 AVPlayerLayer,让 我 们 的 player 的 layer 为 该 view 的layer。然后我们对这个 view 进行 autolayout 这样就能自动适应屏幕了。代码如下:import UIKitimport AVFoundationclass

29、BVideoPlayLayerView:UIView var videoPreviewLayer:AVPlayerLayer guard let layer=layer as?AVPlayerLayer else fatalError(Expected AVPlayerLayer type for layer.Check PreviewView.layerClass implementation.)return layer var player:AVPlayer?get return videoPreviewLayer.player;set videoPreviewLayer.player=n

30、ewValue;/改变 view layer 用于播放视频 默认 CALayer override class var layerClass:AnyClass return AVPlayerLayer.self;关于屏幕旋转的问题在 iOS6 以后屏幕旋转做了调整,尤其是在项目中用到 navgationcontrler,tabbarcontroller 时问题会变得比较繁琐。这里我们不在详细展开。如果我们的项目中只有一个或者很少界面横屏显示视频,建议采用 modal形式显示 viewcontroller。3.3 深入理解播放过程通过前面关于 html5 方式以及 AVKit 方式的介绍我们图

31、5:AVPlayer 对应初始化过程图 6:VideoToolBox 框架的相关内容58软件开发与应用Software Development&Application电子技术与软件工程Electronic Technology&Software Engineering已经知道播放过程最终都会给到 AVFoundation 层。那么AVFoundation 是怎么样播放的呢?AVFoundation 视 频 播 放 功 能 集 中 到 下 面 几 个 类:AVAsset:用于获取多媒体的相关信息,包括获取多媒体的画面、声音等信息。AVPlayerItem:媒体资源管理对象,管理视频的一些基本信息

32、和状态。AVPlayer:用于控制视频的播放暂停快进等。AVPlayerLayer:视频呈现的图层,用于将 AVPlayer 播放的视频显示出来。初始化过程比较简单,如果按照下面方式初始化AVPlayer。playerItem=AVPlayerItem(url:URL.init(fileURLWithPath:videoPath!)player=AVPlayer.init(playerItem:playerItem);对应初始化过程如图 5。AVPlayer 会通过 AVPlayerItem 去初始化,AVPlayerItem通 过 AVAsset 初 始 化,AVAsset 通 过 URL

33、初 始 化(AVFoundation 为我们封装了一些方法可以直接通过 URL初始化 AVPlayerItem 或者 AVPlayer)。AVPlayer 初始化完毕后,初始化用于显示视频的 AVPlayerLayer,AVPlayer 会作为参数传递进去。这样视频就能播放了。视频播放过程会比较复杂,要想了解视频是怎样播放出来的我们首先要熟悉下视频播放流程。一般而言视频播放需要经过几个步骤:解协议,解封装,解码视音频,视音频同步,解协议是播放网络流媒体时的步骤,如果播放本地视频之需要后面三个步骤即可。解协议:将流媒体协议的数据,解析为标准的相应的封装格式数据。视频数据在网络上传递时会根据不同的

34、流媒体协议标准传播数据,这些协议在传输视音频数据的同时,也会传输一些信令数据。这些信令数据包括对播放的控制(播放,暂停,停止),或者对网络状态的描述等。解协议的过程中会去除掉信令数据而只保留视音频数据。例如,采用RTMP 协议传输的数据,经过解协议操作后,输出 FLV 格式的数据。解封装:将输入的封装格式的数据,分离成为音频流压缩编码数据和视频流压缩编码数据。封装格式种类很多,例如 MP4,MKV,RMVB,TS,FLV,AVI 等等,它的作用就是将已经压缩编码的视频数据和音频数据按照一定的格式放到一起。例如,FLV 格式的数据,经过解封装操作后,输出 H.264 编码的视频码流和 AAC 编

35、码的音频码流。解码:将视频/音频压缩编码数据,解码成为非压缩的视频/音频原始数据。音频的压缩编码标准包含 AAC,MP3,AC-3 等等,视频的压缩编码标准则包含 H.264,MPEG2,VC-1 等等。解码是整个系统中最重要也是最复杂的一个环节。通过解码,压缩编码的视频数据输出成为非压缩的颜色数据,例如 YUV420P,RGB 等等;压缩编码的音频 数据输出成为非压缩的音频抽样数据,例如 PCM 数据。视频解码方式分为硬解和软解。硬解:用硬件来进行解码,通过显卡的视频加速功能对高清视频进行解码,依靠显卡 GPU 的。优点是低功耗、发热少、效率高,缺点是视频兼容性差、支持度低;软解:用软件进行

36、解码,但是实际最终还是要硬件来支持的,这个硬件就是CPU。优点是兼容强、全解码、效果好,缺点是对 CPU 要求高、效率低、发热大。注意:AVFoundation 框架也使用硬件对视频进行硬编码和解码,编码后直接写入文件,解码后直接显示。苹果在 iOS 8.0系统之前,没有开放系统的硬件编码解码功能,不过 Mac OS 系统一直有。在 iOS 8.0 后,苹果将该框架引入 iOS 系统。用户可以直接使用 Video ToolBox 的框架来处理硬件的编码和解码。视音频同步:根据解封装模块处理过程中获取到的参数信息,同步解码出来的视频和音频数据。同步完毕后并将视频音频数据送至系统的显卡和声卡播放出

37、来。有了对上述步骤的理解,我们总结 iOS 中视频播放的流程,首先对 AVPlayer 初始化,完毕后开始播放视频,如果我们播放的是网络上的视频 AVPlayer 首先会有一个解协议的过程,将网络上的流媒体数据解协议成视频封装数据。如果播放本地的视频文件则直接将文件解封装成音视频文件,随后分别对音视频文件进行解码,最后进行音视频同步呈现出来。对于视频播放模块框架 AVFoundation 怎样实现,通过什么代码实现以上几个步骤,苹果没有开放这其过程,所以对其探究也很难深入进去,不过我们仍然可以通过调用函数调用栈大致窥见一二,如图 6 所示,当开始播放视频的时候启动线程调用了 VideoToolBox 框架的相关内容,当然不只是 VideoToolBox,我们在其他线程中还能看到MedioToolBox 框架。再往底层还有绘图相关的框架。参考文献1 Apple Inc.AVFoundation Programming Guide.2015.2 Paul Irish.WebKit for Developers.Feb 28th 2013.3 Bob McCune.AV Foundation 开发秘籍,2015.作者简介白亚辉,安徽建筑大学计算机科学与技术专业,大学本科学历,现任助理工程师岗位。从事软件开发行业 7 年。对iOS、Android 平台的手机应用开发有着丰富经验。

展开阅读全文
相似文档                                   自信AI助手自信AI助手
猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 学术论文 > 自然科学论文

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服