功能:从相册选取视频(不支持录制),添加滤镜,上传七牛服务器
Xcode Version 11.2
SDK Version
- PLShortVideoKit (2.2.0)
1.相册选择视频
TZImagePickerController (3.2.4)
相册选择视频 得到 PHAsset *asset
2.预览 + 编辑
// 编辑工具类 短视频SDK中的类
@property (strong, nonatomic) PLShortVideoEditor *shortVideoEditor;
// 所有滤镜 短视频Demo中的获取滤镜管理类
@property (strong, nonatomic) PLSFilterGroup *filterGroup;
// 输出配置,必传参数
@property (nonatomic, strong) NSMutableDictionary *outputSettings;
@property (nonatomic, strong) NSMutableDictionary *movieSettings;
/// PHAsset 转 AVAsset
// 核心方法
- (PHImageRequestID)requestAVAssetForVideo:(PHAsset *)asset options:(nullable PHVideoRequestOptions *)options resultHandler:(void (^)(AVAsset *__nullable asset, AVAudioMix *__nullable audioMix, NSDictionary *__nullable info))resultHandler API_AVAILABLE(macos(10.15));
// 依赖
#import <Photos/Photos.h>
// 项目代码
- (void)test {
__weak typeof(self) wself = self;
PHVideoRequestOptions *option = [[PHVideoRequestOptions alloc] init];
option.version = PHVideoRequestOptionsVersionOriginal;
option.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
option.networkAccessAllowed = YES;
[[PHImageManager defaultManager] requestAVAssetForVideo:self.videoAsset options:option resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(self) self = wself;
if (asset) {
self.asset = asset; // 存储asset,导出是需要
self.shortVideoEditor = [[PLShortVideoEditor alloc] initWithAsset:asset videoSize:CGSizeZero];
self.shortVideoEditor.loopEnabled = YES;
self.shortVideoEditor.previewView.frame = self.view.bounds;
[self.view insertSubview:self.shortVideoEditor.previewView atIndex:0];
[self.shortVideoEditor startEditing]; // 开始编辑
if (self.videoAsset.pixelHeight > self.videoAsset.pixelWidth) {
self.shortVideoEditor.fillMode = PLSVideoFillModePreserveAspectRatioAndFill;
}
// 总的导出参数字典对象
self.outputSettings = [[NSMutableDictionary alloc] init];
// 原视频参数字典对象
self.movieSettings = [[NSMutableDictionary alloc] init];
self.movieSettings[PLSAssetKey] = asset;
self.movieSettings[PLSVolumeKey] = [NSNumber numberWithFloat:1.0];
self.movieSettings[PLSStartTimeKey] = [NSNumber numberWithFloat:0.f];
self.movieSettings[PLSDurationKey] = [NSNumber numberWithFloat:CMTimeGetSeconds(asset.duration)];
self.outputSettings[PLSMovieSettingsKey] = self.movieSettings;
}
});
}];
}
// 获取所有滤镜数据
self.filterGroup = [[PLSFilterGroup alloc] initWithImage:nil];
// 添加滤镜
self.filterGroup.filterIndex = indexPath.row; // 设置你选中的对应下标
[self.shortVideoEditor addFilter:self.filterGroup.colorImagePath];
// 存储选中的滤镜,导出时需要
self.colorImagePath = self.filterGroup.colorImagePath;
3.导出
// 导出成功后会回调一个 本地路径 url
- (void)export {
__weak typeof(self) wself = self;
PLSAVAssetExportSession *exportSession = [[PLSAVAssetExportSession alloc] initWithAsset:self.asset];
// exportSession.outputFileType = PLSFileTypeMPEG4;
exportSession.audioChannel = 2;
exportSession.delegate = self;
exportSession.audioBitrate = PLSAudioBitRate_128Kbps;
exportSession.outputVideoFrameRate = MIN(60, self.asset.pls_normalFrameRate);
exportSession.outputVideoSize = self.asset.pls_videoSize;
[exportSession addFilter:self.colorImagePath]; // 你存储的滤镜
exportSession.outputSettings = self.outputSettings; // 输出设置 必须设置
[exportSession setCompletionBlock:^(NSURL *url) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Asset Export Completed");
// 这里应该成功了,必须回到主线程来操作
});
}];
[exportSession setFailureBlock:^(NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
// 失败也要在主线程处理
NSLog(@"error - %@", error);
});
}];
[exportSession exportAsynchronously];
}
4.上传
// token 为校验字符串 一般通过自己后台接口获取
- (void)shortVideoUploadVideo:(NSString *)token { // 短视频上传功能
__weak typeof(self) wself = self;
PLSUploaderConfiguration *config = [PLSUploaderConfiguration defaultWithToken:token];
PLShortVideoUploader *uploader = [PLShortVideoUploader sharedUploader:config];
[uploader uploadVideoFile:self.url.absoluteString];
uploader.delegate = wself;
}
// 进度回调
- (void)shortVideoUploader:(PLShortVideoUploader * _Nonnull)uploader uploadKey:(NSString * _Nullable)uploadKey uploadPercent:(float)uploadPercent {
__weak typeof(self) wself = self;
dispatch_async(dispatch_get_main_queue(), ^{
});
}
// 结束回调
- (void)shortVideoUploader:(PLShortVideoUploader * _Nonnull)uploader completeInfo:(PLSUploaderResponseInfo * _Nonnull)info uploadKey:(NSString * _Nonnull)uploadKey resp:(NSDictionary * _Nullable)resp {
__weak typeof(self) wself = self;
if (info.statusCode == 200) { // 成功
} else {
}
NSLog(@"resp - %@", resp);
}