iOS视频播放常用重点知识
let url = Bundle.main.url(forResource: "video", withExtension: "mp4")!
let playerItem = AVPlayerItem(url: url)
let player = AVPlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = view.bounds
view.layer.addSublayer(playerLayer)
player.play()
代码举例
let asset = AVAsset(url: videoURL)
let reader = try! AVAssetReader(asset: asset)
let videoTrack = asset.tracks(withMediaType: .video).first! //输出样本的buffer设置
let outputSettings: [String: Any] = [
kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32BGRA)
]
//从视频轨道中读取buffer样本,并输出出来
let readerOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: outputSettings)
reader.add(readerOutput)
reader.startReading() while reader.status == .reading {
if let sampleBuffer = readerOutput.copyNextSampleBuffer() {
// 处理样本数据
}
}
处理视频帧数据,将视频数据写入文件
let writer = try! AVAssetWriter(outputURL: outputURL, fileType: .mp4)
let videoTrack = asset.tracks(withMediaType: .video).first!
//设置写入文件的视频编码
let outputSettings: [String: Any] = [
AVVideoCodecKey: AVVideoCodecType.h264,
AVVideoWidthKey: 640,
AVVideoHeightKey: 480,
]
let writerInput = AVAssetWriterInput(mediaType: .video, outputSettings: outputSettings)
writer.add(writerInput) let adapter = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: writerInput, sourcePixelBufferAttributes: outputSettings)
writer.startWriting()
writer.startSession(atSourceTime: CMTime.zero) while // 读取视频数据 {
if adapter.assetWriterInput.isReadyForMoreMediaData {
adapter.append(pixelBuffer, withPresentationTime: // 时间戳)
}
} writerInput.markAsFinished()
writer.finishWriting {
// 导出完成
}
/ 本地播放
// let url = Bundle.main.url(forResource: "video", withExtension: "mp4")!
// let playerItem = AVPlayerItem(url: url)
// 网络播放
let url = URL(string: "http://example.com/video.mp4")!
let asset = AVAsset(url: url)
let playerItem = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: playerItem)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = view.bounds
view.layer.addSublayer(playerLayer)
player.play()
另外对AVPlayer的其他常见操作还有AVPlayer的pause()、seek(to:)方法,表示暂停、快进;还可以通过KVO监听AVPlayer的状态和播放进度等信息。 AVPlayerViewController提供了常用的播放器控制器界面,包括播放/暂停按钮、播放进度条、播放时间等。可以开箱即用,方便开发。
let playerViewController = AVPlayerViewController()
let url = URL(string: "http://example.com/video.mp4")!
let asset = AVAsset(url: url)
let playerItem = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: playerItem) playerViewController.player = player
present(playerViewController, animated: true, completion: nil)
使用NSURLSession进行缓存
// 创建NSURLSessionConfiguration对象
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
// 设置缓存策略为NSURLRequestReturnCacheDataElseLoad
configuration.requestCachePolicy = NSURLRequestReturnCacheDataElseLoad;
// 创建NSURLSession对象
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
// 创建NSURLRequest对象
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/video.mp4"]];
// 发起网络请求
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"Error: %@", error);
} else {
// 将视频数据保存到本地缓存
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [cachePath stringByAppendingPathComponent:@"video.mp4"];
[data writeToFile:filePath atomically:YES];
// 播放视频
AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init];
playerViewController.player = [AVPlayer playerWithURL:[NSURL fileURLWithPath:filePath]];
[self presentViewController:playerViewController animated:YES completion:nil];
}
}];
[task resume];
// 创建AVAsset对象
AVAsset *asset = [AVAsset assetWithURL:[NSURL URLWithString:@"http://example.com/video.mp4"]];
// 创建AVAssetDownloadURLSessionConfiguration对象
AVAssetDownloadURLSessionConfiguration *configuration = [AVAssetDownloadURLSessionConfiguration new];
configuration.maximumActiveDownloads = 1;
configuration.allowsCellularAccess = NO;
// 设置缓存路径为Caches目录下的VideoCache文件夹
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *cacheFolder = [cachePath stringByAppendingPathComponent:@"VideoCache"];
NSURL *cacheURL = [NSURL fileURLWithPath:cacheFolder isDirectory:YES];
configuration.destinationURL = cacheURL;
// 创建AVAssetDownloadURLSession对象
AVAssetDownloadURLSession *session = [AVAssetDownloadURLSession sessionWithConfiguration:configuration assetDownloadDelegate:self delegateQueue:nil];
// 创建AVAssetDownloadTask对象
AVAssetDownloadTask *task = [session assetDownloadTaskWithURLAsset:asset assetTitle:@"video" assetArtworkData:nil options:nil];
// 启动下载任务
[task resume]; 在AVAssetDownloadDelegate协议方法中,做视频播放
当下载完成时,保存视频文件的本地路径,并使用AVPlayerViewController进行播放:
- (void)URLSession:(NSURLSession *)session assetDownloadTask:(AVAssetDownloadTask *)assetDownloadTask didFinishDownloadingToURL:(NSURL *)location {
// 将视频数据保存到本地缓存
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0
import UIKit
import AVFoundation
import AVKit class ViewController: UIViewController { var player: AVPlayer!
var playerLayer: AVPlayerLayer! override func viewDidLoad() {
super.viewDidLoad() // 创建AVPlayer
// 这个M3U8文件包含了所有视频文件的URL地址,AVPlayer会根据这些URL逐一请求视频文件并进行播放。
let url = URL(string: "http://example.com/video.m3u8")!
player = AVPlayer(url: url) // 创建AVPlayerLayer
playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = view.bounds
view.layer.addSublayer(playerLayer) // 播放视频
player.play()
} override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews() // 调整AVPlayerLayer的大小
playerLayer.frame = view.bounds
}
}
// 播放/暂停视频
if player?.rate == 0 {
player?.play()
} else {
player?.pause()
} //快进/快退视频:
let seekTime = CMTimeMakeWithSeconds(10.0, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
let currentTime = player?.currentTime()
let targetTime = CMTimeAdd(currentTime!, seekTime) player?.seek(to: targetTime) //播放状态发生变化时的回调函数
player?.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, preferredTimescale: CMTimeScale(NSEC_PER_SEC)), queue: DispatchQueue.main, using: { [weak self] (time) in
// 更新播放进度
}) //播放器状态发生变化时的回调函数
player?.addObserver(self, forKeyPath: "status", options: [.old, .new], context: nil) override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if keyPath == "status" {
if player?.status == .failed {
// 播放失败
} else if player?.status == .readyToPlay {
// 准备播放
}
}
}
iOS视频播放常用重点知识的更多相关文章
- 【转载】STL"源码"剖析-重点知识总结
原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...
- JavaScript重点知识(二)
三.JS的API 3.1知识点(DOM) 1)DOM本质 将html结构化成浏览器和JS可识别可操作的东西 2)变量计算---强制类型转换 获取DOM节点 Attribute(对html标签属性的修改 ...
- iOS开发-常用第三方开源框架介绍
iOS开发-常用第三方开源框架介绍 图像: 1.图片浏览控件MWPhotoBrowser 实现了一个照片浏览器类似 iOS 自带的相册应用,可显示来自手机的图片或者是网络图片,可自动从网 ...
- AJAX重点知识的心得体会
下面就为大家带来一篇 AJAX重点知识的心得体会.学习还是有点帮助的,给大家做个参考吧. AJAX是什么? 是Asynchronous Javascript And XML的首字母的缩写, 它不是一门 ...
- IOS开发常用设计模式
IOS开发常用设计模式 说起设计模式,感觉自己把握不了笔头,所以单拿出iOS开发中的几种常用设计模式谈一下. 单例模式(Singleton) 概念:整个应用或系统只能有该类的一个实例 在iOS开发我们 ...
- iOS网络相关零散知识总结
iOS网络相关零散知识总结 1. URL和HTTP知识 (1) URL的全称是Uniform Resource Locator(统一资源定位符). URL的基本格式 = 协议://主机地址/路径 ...
- ios中常用数据类型相互转换
ios中常用数据类型相互转换 //1. NSMutableArray和NSArray互转 // NSArray转为NSMutableArray NSMutableArray *arrM = [arr ...
- 关于ios导航控制器的知识总结
关于ios导航控制器的知识总结 添加了导航控制器后: 1.一个导航控制器会有一个顶部导航栏navigationbar和一个底部工具栏toolbar,它们是导航控制器navC的属性.且导航栏默认是不隐藏 ...
- iOS中常用的四种数据持久化方法简介
iOS中常用的四种数据持久化方法简介 iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 ...
- Word常用实用知识1
Word常用实用知识1 纯手打,可能有错别字,使用的版本是office Word 2013 转载请注明出处,谢谢. 快速输入日期(含格式) [插入]--[日期] 快速输入日期和时间(快捷键) 快速 ...
随机推荐
- Java 设计模式课堂作业记录
第二章 P25,有人将面向对象设计原则简单归类为 3 条:①封装变化点: ②对接口进行编程: ③多使用组合,而不是继承.请查阅相关资料谈谈理解 3.7 : 该三大原则 应该算 是OO的基础,很多OO设 ...
- InnoDB 事务加锁分析
本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/S7MhlsZveBHRSQhq5aTIJA作者:何志创 一般大家对数据库事务的了解可能停留在事 ...
- 【营】在开局,提升【豹】发力 - vivo活动插件管理平台
一.背景 随着vivo悟空活动中台活动组件越来越多,活动中台开发的小伙伴们愈发的感知到我们缺少一个可以沉淀通用能力,提升代码复用性的组件库.在这个目标基础之上诞生了acitivity-componen ...
- go语言-Go环境搭建
go语言-Go环境搭建 下载 https://golang.org/dl/ 切换root权限 su root 进入用户列表 cd /usr/local/ 解压缩 tar -zxvf go1.13.li ...
- mysql 使用 trim去不掉空格 解决
使用mysql8.0时 发现 有几个空字符串怎么也过滤不掉,使用 is not null.trim()<>''.length()>=1都不行,最后查了一些资料说 trim只能去除半角 ...
- 大数据(3)---HDFS客户端命令及java连接
一.参数设置 之前有说到HDFS的备份数量和切块大小都是可以配置的,默认是备份3,切块大小默认128M 文件的切块大小和存储的副本数量,都是由客户端决定! 所谓的由客户端决定,是通过客户端机器上面的配 ...
- C#对字符串进行加密解密
首先上效果图 加解密接口 internal string ToEncrypt(string encryptKey, string str) { try { byte[] P_byte_key = // ...
- C# 序列化器
理论知识: 序列化是指将对象转换成字节流,从而存储对象或将对象传输到内存.数据库或文件的过程. 它的主要用途是保存对象的状态,以便能够在需要时重新创建对象. 反向过程称为"反序列化" ...
- channel 是怎么走上死锁这条路的
本篇文章接着 hello world 的并发实现一文介绍 Go 的 channel 类型,同时进一步介绍 channel 的几种死锁情况,这些都是代码中很容易遇到的,要重点摘出来讲,防止一不留神程序就 ...
- cout对象在全局只能拥有一个
1.问题 在学习符号重载的过程中,有一个想法 std::ostream& operator<<(std::ostream &cout, Person &p); 中s ...