录制裁剪,录制压缩转码上传到服务器

2019-09-11 作者:yzc216.com官网   |   浏览(92)

最近比较项目中有一个视频上传的需求,可以支持多选的。找了一些资料都是比较乱。后来就是通过一个好友的帮助。自己总结了一下,实现了这个需求,但是还是有点小问题有待解决。这里就给大家分享一下。

1,首先要获取到本地的视频

2,开始选取视频,可以定一个Model这样用起来比较方便

伪代码如下:

#import@interface GCMAssetModel : NSObject

@property (nonatomic,strong) UIImage *thumbnail;//缩略图

@property (nonatomic,copy) NSURL *imageURL;//原图url

@property (nonatomic,assign) BOOL isSelected;//是否被选中

@property (nonatomic,assign) BOOL isImage;//是否是图片

- originalImage:(UIImage *image))returnImage;//获取原图

@end

3,选取视频展示到Collectionview上面,我项目中做的是类似于图片的这种格式

///////////////////////////////

图片 1由于模拟机上没有视频,就拿图片上传展示一下,效果是一样的

//视频转码方法 传相册或者相机得到的url和给视频命名

4,步骤如下:点击加好按钮进行选择,之后返回选择的视频的数组,下边有一步重要的压缩转码操作接下来会贴出方法

-collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath

{NSLog(@"您点击了添加");

if (indexPath.row == _ImageArr.count) {

GCMImagePickerController *picker = [[GCMImagePickerController alloc] init];

//返回选中的原图

[picker setDidFinishSelectImageModels:^(NSMutableArray *models) {

// NSLog(@"原图%@",models);

for (GCMAssetModel *model in models) {

FileModel *fileModell = [[FileModel alloc] init];

fileModell.filename = [NSString stringWithFormat:@"%ld.mp4",RandomNum];

fileModell.fileAssetURL = model.imageURL;

//压缩转码操作

[self convertVideoToData:fileModell];

[fileModelArray addObject:fileModell];

[_ImageArr addObject:model.thumbnail];

NSLog(@"111%@",_ImageArr);

[_collectionview reloadData];}

}];

[self presentViewController:picker animated:YES completion:nil];}

}

5,压缩转码操作

//压缩转码

- convertVideoToData:(FileModel *)model

{//保存至沙盒路径

NSString *pathDocuments =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

NSLog(@"%@",pathDocuments);

NSString *videoPath = [NSString stringWithFormat:@"%@/Video",pathDocuments];

model.sandBoxPath = [videoPath stringByAppendingPathComponent:model.filename];

//转码配置

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:model.fileAssetURL options:nil];

AVAssetExportSession *exportSession= [[AVAssetExportSession alloc]

initWithAsset:asset presetName:AVAssetExportPresetLowQuality];

exportSession.shouldOptimizeForNetworkUse = YES;

exportSession.outputURL = [NSURL fileURLWithPath:model.sandBoxPath];

exportSession.outputFileType = AVFileTypeMPEG4;

NSArray *compatiblePresets = [AVAssetExportSession

exportPresetsCompatibleWithAsset:asset];

NSLog(@"%@",compatiblePresets);

[exportSession exportAsynchronouslyWithCompletionHandler:^{

int exportStatus = exportSession.status;

NSLog(@"%d",exportStatus);

switch (exportStatus)

{

case AVAssetExportSessionStatusFailed:{

_hud1.labelText = @"不能创建文件";

[_hud1 hide:YES afterDelay:0.5];

break;}

case AVAssetExportSessionStatusCompleted:{

NSLog(@"视频转码成功");

//视频的NSData数据在模型fileData属性里

NSError *error;

NSData * data = [NSData dataWithContentsOfFile:model.sandBoxPath options:

(NSDataReadingMappedIfSafe) error:&error];

model.fileData = data;

[_VoideData addObject:data];

NSLog(@"%@",model.sandBoxPath);

//判断多选的情况下,什么时候视频全部转码成功

if (_VoideData.count==fileModelArray.count) {

dispatch_async(dispatch_get_main_queue(), ^{

NSLog;

[_hud1 hide:YES];});

}

break;}

}

}];

}

6,将视频文件保存至本地 此方法要先调用,因为首先要开辟储存空间,写在ViewDidLoad里面调用

- creatSandBoxFilePathIfNoExist{

//沙盒路径

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);

NSString *documentDirectory = [paths objectAtIndex:0];

NSLog(@"databse--->%@",documentDirectory);

NSFileManager *fileManager = [[NSFileManager alloc] init];

NSString *pathDocuments =

[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

//创建目录

_createPath = [NSString stringWithFormat:@"%@/Video",pathDocuments];

// 判断文件夹是否存在,如果不存在,则创建

if (![[NSFileManager defaultManager] fileExistsAtPath:_createPath]) {

[fileManager createDirectoryAtPath:_createPath withIntermediateDirectories:YES attributes:nil error:nil];} else {

NSLog(@"FileImage is exists.");}}

7,上传的话每个人都有每个人的方法,可以用AFN进行上传,注意上传的时候是上传的NsData数据。这里我就不贴代码了。

-shipinZhuanma:url withName:(NSString *)name{

[SVProgressHUD setDefaultMaskType:SVProgressHUDMaskTypeClear];

[SVProgressHUD showWithStatus:@"处理中..."];

[self creatSandBoxFilePathIfNoExist];

//保存至沙盒路径

NSString *pathDocuments = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

NSString *videoPath = [NSString stringWithFormat:@"%@/zhuanMaVideo", pathDocuments];

NSString *sandboxPath = [videoPath stringByAppendingPathComponent:name];

//转码配置

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];

//AVAssetExportPresetMediumQuality可以更改,是枚举类型,官方有提供,更改该值可以改变视频的压缩比例

AVAssetExportSession *exportSession= [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];

exportSession.shouldOptimizeForNetworkUse = YES;

exportSession.outputURL = [NSURL fileURLWithPath:sandboxPath];

//AVFileTypeMPEG4 文件输出类型,可以更改,是枚举类型,官方有提供,更改该值也可以改变视频的压缩比例

exportSession.outputFileType = AVFileTypeMPEG4;

[exportSession exportAsynchronouslyWithCompletionHandler:^{

int exportStatus = exportSession.status;

NSLog(@"%d",exportStatus);

switch (exportStatus)

{

case AVAssetExportSessionStatusFailed:

{

// log error to text view

NSError *exportError = exportSession.error;

NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError);

//转码失败

break;

}

case AVAssetExportSessionStatusCompleted:

{

[SVProgressHUD dismiss];

NSData *data = [NSData dataWithContentsOfFile:sandboxPath];

if {

NSString *videoDataString = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

//把视频二进制流 写入沙盒

NSString*docPath =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;

//字典写文件--> ~/Documents/字典

NSDictionary*dic = @{@"shipinName":name,@"shipinDate":videoDataString};

//拼出文件地址

NSString*dicPath = [docPath stringByAppendingPathComponent:@"飞行圈视频字典"];

//写入文件

[dic writeToFile:dicPath atomically:YES];

}

}

}

}];

}

- creatSandBoxFilePathIfNoExist

{

//沙盒路径

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentDirectory = [paths objectAtIndex:0];

NSLog(@"databse--->%@",documentDirectory);

NSFileManager *fileManager = [[NSFileManager alloc] init];

NSString *pathDocuments = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

//创建目录

NSString *createPath = [NSString stringWithFormat:@"%@/zhuanMaVideo", pathDocuments];

// 判断文件夹是否存在,如果不存在,则创建

if (![[NSFileManager defaultManager] fileExistsAtPath:createPath]) {

[fileManager createDirectoryAtPath:createPath withIntermediateDirectories:YES attributes:nil error:nil];

} else {

NSLog(@"FileImage is exists.");

}

}

//上传视频数据方法

- videoGO_FuwuQI{

[SVProgressHUD setDefaultMaskType:SVProgressHUDMaskTypeClear];

[SVProgressHUD showWithStatus:@" "];

// __weak typeof weakSelf = self;

NSString*docPath =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;

NSString*dicPath = [docPath stringByAppendingPathComponent:@"飞行圈视频字典"];

//读出文件内容

NSDictionary*readDic = [NSDictionary dictionaryWithContentsOfFile:dicPath];

//////这是视频上传服务器的地址

// NSString *svr = [NSString stringWithFormat:@"%@JieKou/Shipinku_Jiekou/shipingupload.aspx",glaFly_upIMG];

NSString *svr = [NSString stringWithFormat:@"%@%@",glaFly_upIMG,self.shangURL];

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

manager.requestSerializer = [AFJSONRequestSerializer serializer];

manager.responseSerializer = [AFHTTPResponseSerializer serializer];

[manager.requestSerializer setValue:@"text/html" forHTTPHeaderField:@"Content-Type"];

manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"image/png",nil];

//////这是视频上传服务器的约好的键值

NSDictionary *parameters =@{@"videoname":readDic[@"shipinName"],@"videodata":readDic[@"shipinDate"]};

// NSURLSessionDataTask *abc =

[manager POST:svr parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {

// dispatch_async(dispatch_get_main_queue(), ^{

// [weakSelf.jinDuTiao setProgress:1.0 *uploadProgress.completedUnitCount / uploadProgress.totalUnitCount animated:YES];

// weakSelf.jiduLab.text = [NSString stringWithFormat:@"%.2f%",1.0 *uploadProgress.completedUnitCount / uploadProgress.totalUnitCount * 100];

// });

} success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary *responseObject) {

// NSLog;

[SVProgressHUD dismiss];

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

[SVProgressHUD dismiss];

NSLog(@"视频上传出错:%@",error);

}];

}

-shipinCaiJian:url withName:(NSString *)name start:startTime end:endTime{

[self cropWithVideoUrlStr:url withName:name start:startTime end:endTime completion:^(NSURL *outputURL, Float64 videoDuration, BOOL isSuccess) {

}];

}

///////////////////////////////视频截取

- cropWithVideoUrlStr:videoUrl withName:(NSString *)name start:startTime end:endTime completion:(NSURL *outputURL, Float64 videoDuration, BOOL isSuccess))completionHandle

{

[self creatSandBoxFilePathIfNoExist];

//保存至沙盒路径

NSString *pathDocuments = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

NSString *videoPath = [NSString stringWithFormat:@"%@/zhuanMaVideo", pathDocuments];

NSString *sandboxPath = [videoPath stringByAppendingPathComponent:name];

//转码配置

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:videoUrl options:nil];

//AVAssetExportPresetMediumQuality可以更改,是枚举类型,官方有提供,更改该值可以改变视频的压缩比例

AVAssetExportSession *exportSession= [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];

exportSession.shouldOptimizeForNetworkUse = YES;

exportSession.outputURL = [NSURL fileURLWithPath:sandboxPath];

//AVFileTypeMPEG4 文件输出类型,可以更改,是枚举类型,官方有提供,更改该值也可以改变视频的压缩比例

exportSession.outputFileType = AVFileTypeMPEG4;

/////////////////////////////////////////////////

///////////////////////////////-------华丽的分割线-------////////////////////////////////////////////////

/////////////////////////////////////////////////

CMTime start = CMTimeMakeWithSeconds(startTime, asset.duration.timescale);

CMTime duration = CMTimeMakeWithSeconds(endTime - startTime,asset.duration.timescale);

CMTimeRange range = CMTimeRangeMake(start, duration);

exportSession.timeRange = range;

[exportSession exportAsynchronouslyWithCompletionHandler:^{

[SVProgressHUD dismiss];

switch ([exportSession status]) {

case AVAssetExportSessionStatusFailed:

{

NSLog(@"合成失败:%@", [[exportSession error] description]);

completionHandle(exportSession.outputURL, endTime, NO);

}

break;

case AVAssetExportSessionStatusCancelled:

{

completionHandle(exportSession.outputURL, endTime, NO);

}

break;

case AVAssetExportSessionStatusCompleted:

{

completionHandle(exportSession.outputURL, endTime, YES);

NSData *data = [NSData dataWithContentsOfFile:sandboxPath];

if {

NSString *videoDataString = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

//把视频二进制流 写入沙盒

NSString*docPath =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).firstObject;

//字典写文件--> ~/Documents/字典

NSDictionary*dic = @{@"shipinName":name,@"shipinDate":videoDataString};

//拼出文件地址

NSString*dicPath = [docPath stringByAppendingPathComponent:@"飞行圈视频字典"];

//写入文件

[dic writeToFile:dicPath atomically:YES];

}

}

break;

default:

{

completionHandle(exportSession.outputURL, endTime, NO);

} break;

}

}];

}

@end

本文由yzc216亚洲城发布于yzc216.com官网,转载请注明出处:录制裁剪,录制压缩转码上传到服务器

关键词: yzc216亚洲城 yzc216.com官网