iOS开发一个制作Live Photo的工具
1.livePhoto简介
livePhoto是iOS 9.0 之后系统相机提供的拍摄动态照片的功能,但是仅在6S+,iOS 9.0+设备可用。拍摄完livePhoto之后,只需要在相册按压livePhoto相片即可动态的播放。livePhoto还可以设置为动态壁纸。如果只能用相机拍摄的livePhoto设置为动态壁纸,这不能满足我们的需求了。如果可以将视频转换为livePhoto那就完美了。如果要实现这个功能就要了解live Photo的本质了。
2.livePhoto的本质
其实livePhoto的本质是一张jpg图片+一段mov视频另外再加入一些信息一起写入到相册内即可生成livePhoto,核心的写入代码是我在github找到的,但是Swift版,我将它翻译为OC版。Swift版写入livePhotoDemo。
3.涉及到的技术
1)相册数据的读取与写入;
2)share Extension的使用;
3)视频提取某一帧图片;
4)不同进程间的通讯;
5)PHLivePhotoView展示livePhoto图片;
4.实现livePhoto制作工具
主界面UI如下图,噗。。请原谅我毫无美感的页面设计,勿喷。

顶部一个AVplayer实现本地视频的播放,AVplayer下面一个UISlider可以选择视频的哪一帧作为livePhoto的封面图。UISlider下面一个PHLivePhotoView按压可以预览livePhoto的效果图。
1)如何提取视频中的某一帧?
/**
获取视频的 某一帧
@param currentTime 某一时刻单位 s
@param path 视频路径
@return return 返回image
*/
- (UIImage *)getVideoImageWithTime:(Float64)currentTime videoPath:(NSURL *)path {
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:path options:nil];
// float fps = [[[asset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0] nominalFrameRate];
// NSLog(@"视频帧率%f",fps);
AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
gen.appliesPreferredTrackTransform = YES;
gen.requestedTimeToleranceAfter = kCMTimeZero;// 精确提取某一帧,需要这样处理
gen.requestedTimeToleranceBefore = kCMTimeZero;// 精确提取某一帧,需要这样处理
CMTime time = CMTimeMakeWithSeconds(currentTime, 600);
NSError *error = nil;
CMTime actualTime;
CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
UIImage *img = [[UIImage alloc] initWithCGImage:image];
CMTimeShow(actualTime);
CGImageRelease(image);
return img;
}
2)图片与视频分别经过特定的处理然后分别存储为JPG 与 MOV格式。
将视频转为livePhoto存入相册,iOS原生API并没有给出这样的方法。而能将视频转为livePhoto,是源于SwiftlivePhotoDemo作者对livePhoto细心观察。我这里只是借花献佛转化为OC版本。

使用上图中的两个文件可以将图片与视频分别经过特定的处理然后分别存储为JPG 与 MOV格式
3)将处理后的JPG 与 MOV一同存储生成livePhoto
首先引入#import <Photos/Photos.h>框架,调用performChanges方法存储,具体代码如下
+ (void)writeLivePhotoWithVideo:(NSURL *)videoPath image:(NSURL *)imagePath result:(void(^)(BOOL res))result {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCreationRequest * request = [PHAssetCreationRequest creationRequestForAsset];
[request addResourceWithType:PHAssetResourceTypePhoto fileURL:imagePath options:nil];
[request addResourceWithType:PHAssetResourceTypePairedVideo fileURL:videoPath options:nil];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (success) {
//保存成功
NSLog(@"保存成功");
}
if (result) {
result(success);
}
}];
}
自此一个简单的livePhoto制作工具完成。但是为了用户体验,我们还要进行素材选取途径拓宽。
4)拓宽素材选取的途径
a.从相册选取素材
从相册选取素材,这里使用了UIImagePickerController来处理,具体代码如下:
- (void)chooseVideoFromPhotoLibraryResult:(ResultBlock)result {
UIImagePickerController *imagePick = [[UIImagePickerController alloc] init];
imagePick.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
imagePick.mediaTypes = @[@"public.movie"];//只获取视频数据
imagePick.delegate = self;
self.result = result;
[[[UIApplication sharedApplication] delegate].window.rootViewController presentViewController:imagePick animated:YES completion:nil];
}
// UIImagePickerController 的选择结果的代理方法。
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
[picker dismissViewControllerAnimated:YES completion:nil];
if ([[info[@"UIImagePickerControllerMediaURL"] absoluteString] length]) {
if (self.result) {
self.result(info[@"UIImagePickerControllerMediaURL"], YES);
}
}
}
b.使用share Extension,让用户可以从其他App中获取素材
我们在项目工程下file-->New-->target-->share Extension-->Nest 创建一个share Extension如下图:


这篇文章详细解读了share Extension,如有需要可以先看一下
由于没有使用原生的share Extension UI所以这里,我们先把系统生成的.h+.m+MainInterface.storyboard这三个文件删除。然后创建一个viewController(继承UIviewController)+Xib。
在viewdidload里实现下面的代码,这些代码是为了获取用户选择的视频地址的操作。
__weak typeof (self) ws = self;
[self.extensionContext.inputItems enumerateObjectsUsingBlock:^(NSExtensionItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[obj.attachments enumerateObjectsUsingBlock:^(NSItemProvider * _Nonnull itemProvider, NSUInteger idx, BOOL * _Nonnull stop) {
if ([itemProvider hasItemConformingToTypeIdentifier:itemProvider.registeredTypeIdentifiers[0]]) {
[itemProvider loadItemForTypeIdentifier:itemProvider.registeredTypeIdentifiers[0] options:nil completionHandler:^(id<NSSecureCoding> _Nullable item, NSError * _Null_unspecified error) {
NSLog(@"%@",item);
if ([(NSObject *)item isKindOfClass:[NSURL class]]) {
NSString * lastAppending = [[[(NSURL*)item absoluteString] componentsSeparatedByString:@"/"] lastObject];
NSFileManager *fileManger = [NSFileManager defaultManager];
NSURL *groupFile = [fileManger containerURLForSecurityApplicationGroupIdentifier:@"group.com.livephoto"];
NSURL *fileUrl = [groupFile URLByAppendingPathComponent:lastAppending];
//移除旧的数据
[fileManger removeItemAtURL:fileUrl error:nil];
NSError *error = nil;
[fileManger copyItemAtURL:(NSURL *)item toURL:fileUrl error:&error];
if (!error) {
ws.lastAppending = lastAppending;
dispatch_async(dispatch_get_main_queue(), ^{
[ws initVideoWithPath:fileUrl];
});
NSLog(@"存入成功!!!");
}
}
}];
*stop = YES;
}
}];
*stop = YES;
}];
这里要注意,由于Extension 与 宿主app分别属于不同的进程,由于iOS是沙盒存储机制。所以不同的进程是不能直接相互访问数据的。但是同一个公司的App 可以通过AppGroup来设置一个公共的存储空间,从而达到 不同的进行相互访问数据。这里我们也是使用AppGroup 把素材资源存储在公共的区域。方便宿主app访问素材数据。具体AppGroup如何来实现?可以参考这篇文文章:iOS App Group实现数据共享
如何唤醒宿主App处理素材数据?
其实iOS提供的Extension当中只有today widget 可以通过url schemes的方式唤醒。其他都是不能唤醒宿主App的。但是通过下面的方法还是可以强行通过url schemes的方式唤醒宿主app的,但是不知道是否可以通过审核?我看到京东的 拍照购 是可以唤醒京东app 的。
- (IBAction)handleVideo:(UIButton *)sender {
UIResponder *responder = self;
while (responder) {
if ([responder respondsToSelector:@selector(openURL:)]) {
[responder performSelector:@selector(openURL:) withObject:[NSURL URLWithString:[NSString stringWithFormat:@"livePhoto://data=%@",_lastAppending]]];
break;
}
responder = [responder nextResponder];
}
}
5.项目文件截图

6.注意点
运行demo前请先配置好自己的环境,以及把App Group换成自己的。最后看一下项目运行效果吧。
iOS开发一个制作Live Photo的工具
注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权
iOS开发一个制作Live Photo的工具的更多相关文章
- iOS 开发人员不可缺少的75个工具
原文出处: Ben Scheirman 译文出处: Njuxjy 假设你去到一位熟练的木匠的工作室,你总是能发现他/她有一堆工具来完毕不同的任务. 软件开发相同如此. 你能够从软件开发人员怎样使用工具 ...
- iOS开发一个用户登录注册模块需要解决的坑
最近和另外一位同事负责公司登录和用户中心模块的开发工作,开发周期计划两周,减去和产品和接口的协调时间,再减去由于原型图和接口的问题,导致强迫症纠结症状高发,情绪不稳定耗费的时间,能在两周基本完成也算是 ...
- iOS开发~制作同时支持armv7,armv7s,arm64,i386,x86_64的静态库.a
一.概要 平时项目开发中,可能使用第三方提供的静态库.a,如果.a提供方技术不成熟,使用的时候就会出现问题,例如: 在真机上编译报错:No architectures to compile for ( ...
- iOS开发~制作同时支持armv7,armv7s,arm64,i386,x86_64的静态库.a以及 FrameWork 的创建
armv7,armv7s,arm64,i386,x86_64 详解 一.概要 平时项目开发中,可能使用第三方提供的静态库.a,如果.a提供方技术不成熟,使用的时候就会出现问题,例如: 在真机上编译报错 ...
- iOS开发之--制作属于自己的frameWork
开发的时候,有时候,我们会遇到协同开发,在协同开发的时候,每个开发者都会创建自己的工具类,还有就是当一个项目需要嵌套到另一个项目里面,这些时候,如果能把所需的部分打包成framework,会方便很多, ...
- IOS开发中制作属于自己的静态库.a、资源库.bundle、.framework
一.什么是库 库实际上是一种代码共享的方式,主要用于代码重用和源码隐藏,通常分为动态库和静态库. 静态库:链接时完整的拷贝至可执行文件中,被多次使用就有多份冗余拷贝. 动态库:链接时不复 ...
- 分享iOS开发常用(三方类库,工具,高仿APP,实用网站,技术干货)
一 . JSONModel (三方类库会有更新,建议大家在线下载) http://pan.baidu.com/s/1i5ybP1z 二.AFNetworkiong http://pan.baidu. ...
- IOS封装一个微信聊天的输入工具
1.实现微信的输入工具 实现了大部分功能,各模块实现的很清晰,有利于更好的二次开发(适合自己的需求),我自己总结出来的, 可以更快的让你实现输入工具,不需要扩展的也可以很方便的使用这个输入工具. 1) ...
- iOS 开发技巧-制作环形进度条
有几篇博客写到了怎么实现环形进度条,大多是使用Core Graph来实现,实现比较麻烦且效率略低,只是一个小小的进度条而已,我们当然是用最简单而且效率高的方式来实现. 先看一下这篇博客,博客地址:ht ...
随机推荐
- NOIP 2006 提高组 t1 能量项链
题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子,前一颗珠子的尾标记一定 ...
- [转]Spring 中的p标签
spring的bean配置文件中p:代表什么 <bean id="daoTemplate" abstract="true" lazy-init=" ...
- [转]spring4.x注解概述
1. 背景 注解可以减少代码的开发量,spring提供了丰富的注解功能,因项目中用到不少注解,因此下定决心,经spring4.x中涉及到的注解罗列出来,供查询使用. 2. spring注解图 ...
- [转]MySql中创建序列的方法
CREATE TABLE `my_seq` ( `seq` int(10) NOT NULL default 10000) ENGINE=MyISAM DEFAULT CHARSET=utf8 ...
- Word中正文两栏表格通栏排版
如图所示,需要在插入表格的地方插入连续分节符,这是word2013,在插入里面只有分页符 如果直接插入的话表格上下的分节符会分栏,那样表格会歪曲, 可以上面一段和下面一段设置成通栏,然后中间插入表格, ...
- exVim安装
安装 安装必备 Vim 7.3 or higher. Vundle or Pathogen 下载/更新exVim 注意事项 安装exVim将不会覆盖你已经存在的Vim环境,这个仓库所包含的文件,变化, ...
- Gulp新手入门教程
Gulp 是一个自动化工具,前端开发者可以使用它来处理常见任务: 搭建web服务器 文件保存时自动重载浏览器 使用预处理器如Sass.LESS 优化资源,比如压缩CSS.JavaScript.压缩图片 ...
- HTML5中表单验证的8种方法
HTML5中表单验证的8种方法 2012-4-21 11:00| 发布者: benben| 查看: 2765| 评论: 0 摘要: 前一篇,我们介绍了HTML5中新的表单特性和函数, 今天就继续来谈谈 ...
- window进入本地组策略编辑器和计算机管理界面
win+R 进入运行窗口 输入gpedit.msc 进入本地组策略编辑器, 右键我的电脑,点击管理 进入计算机管理界面
- NormalMap 贴图 【转】
转载: http://www.zwqxin.com/archives/shaderglsl/review-normal-map-bump-map.html 说起Normal Map(法线贴图),就 ...