|
|
|
# 1.概述
|
|
|
|
iOS短视频SDK是适用于iOS平台的短视频SDK。使用此SDK可以实现短视频相关功能。
|
|
|
|
## 1.1 功能特性
|
|
|
|
| 功能 | 描述 |
|
|
|
|
| :--------------------------------------- | :------- |
|
|
|
|
| 拍摄 | 支持短视频拍摄 |
|
|
|
|
| 摄像头切换 | 支持拍摄过程中切换摄像头 |
|
|
|
|
| 断点拍摄 | 支持拍摄过程中可暂停 |
|
|
|
|
| 美颜滤镜 | 支持拍摄加入美颜滤镜 |
|
|
|
|
|
|
|
|
## 1.2阅读对象
|
|
|
|
本文档为技术文档,需要阅读者:
|
|
|
|
|
|
|
|
* 具备基本的iOS开发能力
|
|
|
|
|
|
|
|
* 准备接入CC视频的短视频SDK
|
|
|
|
|
|
|
|
# 2.开发准备
|
|
|
|
|
|
|
|
## 2.1开发环境
|
|
|
|
|
|
|
|
* Xcode:苹果官方IDE
|
|
|
|
|
|
|
|
* iOS8+
|
|
|
|
|
|
|
|
## 2.2SDK使用说明
|
|
|
|
|
|
|
|
首先,需要下载最新版本的SDK,下载地址为:[VOD_iOS_ShortVideo_SDK](https://github.com/CCVideo/VOD_iOS_ShortVideo_SDK),然后导入SDK包到工程,在相应地方引入头文件`#import "DWShortSDK"`
|
|
|
|
|
|
|
|
| 名称 | 描述 |
|
|
|
|
| :--------------------------------------- | :------- |
|
|
|
|
| Demo | 使用SDK的示例源码 |
|
|
|
|
| doc | 存放的是iOS短视频SDK开发指南html文档 |
|
|
|
|
| include | SDK开放的头文件及静态库 |
|
|
|
|
|
|
|
|
# 3.快速集成
|
|
|
|
注:快速集成主要提供的是拍摄功能
|
|
|
|
## 3.1拍摄快速集成
|
|
|
|
|
|
|
|
### 3.1.1SDK添加到项目后,在info.plist文件设置麦克风 相机 相册 图片权限
|
|
|
|
```
|
|
|
|
<!-- 相册 -->
|
|
|
|
<key>NSPhotoLibraryUsageDescription</key>
|
|
|
|
<string>App需要您的同意,才能访问相册</string>
|
|
|
|
<!-- 相机 -->
|
|
|
|
<key>NSCameraUsageDescription</key>
|
|
|
|
<string>App需要您的同意,才能访问相机</string>
|
|
|
|
<!-- 麦克风 -->
|
|
|
|
<key>NSMicrophoneUsageDescription</key>
|
|
|
|
<string>App需要您的同意,才能访问麦克风</string>
|
|
|
|
<!-- 图片 -->
|
|
|
|
<key>NSPhotoLibraryAddUsageDescription</key>
|
|
|
|
<string>App需要您的同意,才能保存图片到您的相册</string>
|
|
|
|
```
|
|
|
|
|
|
|
|
### 3.1.2基于GPUImage 建议用cocoapods导入 也可手动导入 确保工程中只导入一次GPUImage
|
|
|
|
### 3.1.3GPUImage引入后 修改以下部分:
|
|
|
|
```
|
|
|
|
1.GPUImageMovieWriter.h文件中添加isNeedBreakAudioWhiter属性
|
|
|
|
|
|
|
|
@property (nonatomic, assign) BOOL isNeedBreakAudioWhiter;
|
|
|
|
|
|
|
|
2.GPUImageMovieWriter.m文件中第377行代码修改如下:
|
|
|
|
if (CMTIME_IS_INVALID(startTime))
|
|
|
|
{
|
|
|
|
if (_isNeedBreakAudioWhiter) {
|
|
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
runSynchronouslyOnContextQueue(_movieWriterContext, ^{
|
|
|
|
if ((audioInputReadyCallback == NULL) && (assetWriter.status != AVAssetWriterStatusWriting))
|
|
|
|
{
|
|
|
|
[assetWriter startWriting];
|
|
|
|
}
|
|
|
|
[assetWriter startSessionAtSourceTime:currentSampleTime];
|
|
|
|
startTime = currentSampleTime;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
3.GPUImageMovieWriter初始化时设置 isNeedBreakAudioWhiter =YES;
|
|
|
|
具体详情参见demo
|
|
|
|
```
|
|
|
|
|
|
|
|
### 3.1.3初始化相机及filterView
|
|
|
|
```
|
|
|
|
//录制相关
|
|
|
|
videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset1280x720
|
|
|
|
cameraPosition:AVCaptureDevicePositionBack];
|
|
|
|
|
|
|
|
if ([videoCamera.inputCamera lockForConfiguration:nil]) {
|
|
|
|
//自动对焦
|
|
|
|
if ([videoCamera.inputCamera isFocusModeSupported:AVCaptureFocusModeContinuousAutoFocus]) {
|
|
|
|
[videoCamera.inputCamera setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
|
|
|
|
}
|
|
|
|
//自动曝光
|
|
|
|
if ([videoCamera.inputCamera isExposureModeSupported:AVCaptureExposureModeContinuousAutoExposure]) {
|
|
|
|
[videoCamera.inputCamera setExposureMode:AVCaptureExposureModeContinuousAutoExposure];
|
|
|
|
}
|
|
|
|
//自动白平衡
|
|
|
|
if ([videoCamera.inputCamera isWhiteBalanceModeSupported:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance]) {
|
|
|
|
[videoCamera.inputCamera setWhiteBalanceMode:AVCaptureWhiteBalanceModeContinuousAutoWhiteBalance];
|
|
|
|
}
|
|
|
|
|
|
|
|
[videoCamera.inputCamera unlockForConfiguration];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//输出方向为竖屏
|
|
|
|
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
|
|
|
|
//防止允许声音通过的情况下,避免录制第一帧黑屏闪屏
|
|
|
|
[videoCamera addAudioInputsAndOutputs];
|
|
|
|
videoCamera.horizontallyMirrorFrontFacingCamera = YES;
|
|
|
|
videoCamera.horizontallyMirrorRearFacingCamera = NO;
|
|
|
|
|
|
|
|
|
|
|
|
//显示view
|
|
|
|
filterView =[[GPUImageView alloc]initWithFrame:[UIScreen mainScreen].bounds];
|
|
|
|
[self.view addSubview:filterView];
|
|
|
|
//组合
|
|
|
|
// filter = [[GPUImageBilateralFilter alloc] init];
|
|
|
|
// [videoCamera addTarget:filter];
|
|
|
|
// [filter addTarget:filterView];
|
|
|
|
|
|
|
|
|
|
|
|
[videoCamera addTarget:filterView];
|
|
|
|
//相机开始运行
|
|
|
|
[videoCamera startCameraCapture];
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
### 3.1.4初始化moviewriter
|
|
|
|
```
|
|
|
|
//写入
|
|
|
|
movieWriter = [[GPUImageMovieWriter alloc] initWithMovieURL:videoURL size:CGSizeMake(720.0, 1280.0)];
|
|
|
|
|
|
|
|
//设置为liveVideo
|
|
|
|
movieWriter.isNeedBreakAudioWhiter =YES;
|
|
|
|
movieWriter.encodingLiveVideo = YES;
|
|
|
|
movieWriter.shouldPassthroughAudio =YES;
|
|
|
|
|
|
|
|
// [filter addTarget:movieWriter];
|
|
|
|
[videoCamera addTarget:movieWriter];
|
|
|
|
|
|
|
|
//设置声音
|
|
|
|
videoCamera.audioEncodingTarget = movieWriter;
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
# 4.功能使用
|
|
|
|
|
|
|
|
## 4.1删除功能具体使用
|
|
|
|
```
|
|
|
|
//删除前要停止录制
|
|
|
|
if (isRecording) {
|
|
|
|
|
|
|
|
[self stopWrite];
|
|
|
|
}
|
|
|
|
//读取文件 做个比对
|
|
|
|
[self readShortVideoFiles];
|
|
|
|
|
|
|
|
NSString *filePath =[self.pathArray lastObject];
|
|
|
|
BOOL isSuccess = [DWShortTool dw_deleteFileWithFilePath:filePath];
|
|
|
|
if (isSuccess) {
|
|
|
|
|
|
|
|
|
|
|
|
self.videoArray =[[[NSUserDefaults standardUserDefaults] objectForKey:@"videoArray"] mutableCopy];
|
|
|
|
[self.videoArray removeLastObject];
|
|
|
|
[[NSUserDefaults standardUserDefaults] setObject:self.videoArray forKey:@"videoArray"];
|
|
|
|
[[NSUserDefaults standardUserDefaults] synchronize];
|
|
|
|
|
|
|
|
[self.pathArray removeLastObject];
|
|
|
|
deleteBtn.hidden =self.pathArray.count>0?NO:YES;
|
|
|
|
|
|
|
|
UIView *view =[self.viewArray lastObject];
|
|
|
|
[view removeFromSuperview];
|
|
|
|
[self.viewArray removeLastObject];
|
|
|
|
|
|
|
|
logdebug(@"数组__%@__%@",self.pathArray,self.viewArray);
|
|
|
|
//注意要减去相应的录制时间
|
|
|
|
double recordTime =[[self.secondsArray lastObject] doubleValue];
|
|
|
|
totalTime -=recordTime;
|
|
|
|
[self.secondsArray removeLastObject];
|
|
|
|
```
|
|
|
|
|
|
|
|
## 4.2切换功能具体使用
|
|
|
|
```
|
|
|
|
//前置摄像头不打开闪光灯
|
|
|
|
if (videoCamera.inputCamera.position == AVCaptureDevicePositionFront) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (videoCamera.inputCamera.position == AVCaptureDevicePositionBack) {
|
|
|
|
|
|
|
|
if (videoCamera.inputCamera.torchMode ==AVCaptureTorchModeOn) {
|
|
|
|
|
|
|
|
[videoCamera.inputCamera lockForConfiguration:nil];
|
|
|
|
[videoCamera.inputCamera setTorchMode:AVCaptureTorchModeOff];
|
|
|
|
[videoCamera.inputCamera setFlashMode:AVCaptureFlashModeOff];
|
|
|
|
[videoCamera.inputCamera unlockForConfiguration];
|
|
|
|
//改变按钮状态
|
|
|
|
lightBtn.selected =NO;
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
[videoCamera.inputCamera lockForConfiguration:nil];
|
|
|
|
[videoCamera.inputCamera setTorchMode:AVCaptureTorchModeOn];
|
|
|
|
[videoCamera.inputCamera setFlashMode:AVCaptureFlashModeOn];
|
|
|
|
[videoCamera.inputCamera unlockForConfiguration];
|
|
|
|
//改变按钮状态
|
|
|
|
lightBtn.selected =YES;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
## 4.3美颜滤镜功能具体使用
|
|
|
|
```
|
|
|
|
beautyBtn.selected =!beautyBtn.selected;
|
|
|
|
if (beautyBtn.selected) {
|
|
|
|
|
|
|
|
// 移除之前所有的处理链
|
|
|
|
[videoCamera removeAllTargets];
|
|
|
|
|
|
|
|
// 创建美颜滤镜
|
|
|
|
filter = [[GPUImageBilateralFilter alloc] init];
|
|
|
|
|
|
|
|
// 设置GPUImage处理链,从数据->滤镜->界面展示
|
|
|
|
[videoCamera addTarget:filter];
|
|
|
|
[filter addTarget:filterView];
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
|
|
// 移除之前所有的处理链
|
|
|
|
[videoCamera removeAllTargets];
|
|
|
|
[videoCamera addTarget:filterView];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
## 4.4暂停功能具体使用
|
|
|
|
```
|
|
|
|
//因为GCDtimer较为精准 务必先调用移除定时器的方法 再调用停止录制的方法
|
|
|
|
[self removeTimer];
|
|
|
|
dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
//注意顺序
|
|
|
|
[movieWriter finishRecording];
|
|
|
|
[filter removeTarget:movieWriter];
|
|
|
|
videoCamera.audioEncodingTarget = nil;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
beautyBtn.hidden =NO;
|
|
|
|
[self.secondsArray addObject:[NSString stringWithFormat:@"%f",seconds]];
|
|
|
|
// [self saveModelToVideoArray];
|
|
|
|
|
|
|
|
recordBtn.selected =NO;
|
|
|
|
isRecording =NO;
|
|
|
|
[self savePhotosAlbum:videoURL];
|
|
|
|
logdebug(@"录制时间为%f 当前时间为%f",seconds,totalTime);
|
|
|
|
```
|
|
|
|
## 4.5断点拍摄功能具体使用
|
|
|
|
断点拍摄后的几个小视频可以合成为一个视频, DWShortTool提供了如下接口用于合成视频:
|
|
|
|
```
|
|
|
|
/* 合成视频|转换视频格式
|
|
|
|
@param videosPathArray:合成视频的路径数组
|
|
|
|
@param outpath:输出路径
|
|
|
|
@param outputFileType:视频格式 如:AVFileTypeQuickTimeMovie AVFileTypeMPEG4等
|
|
|
|
@param presetName:分辨率 如:AVAssetExportPresetMediumQuality AVAssetExportPreset640x480等
|
|
|
|
@param completeBlock mergeFileURL:合成后新的视频URL
|
|
|
|
*/
|
|
|
|
+ (void)dw_mergeAndExportVideos:(NSArray *)videosPathArray withOutPath:(NSString *)outpath outputFileType:(NSString *)outputFileType presetName:(NSString *)presetName didComplete:(void(^)(NSError *error,NSURL *mergeFileURL) )completeBlock;
|
|
|
|
|
|
|
|
使用详情参见demo。
|
|
|
|
```
|
|
|
|
## 4.6Demo具体使用
|
|
|
|
Demo是示例源码,可直接用Xcode运行。Demo的设计旨在展示SDK各项功能的使用方法,如果希望应用获得更好的使用体验,要根据需求自行更改。
|
|
|
|
如果在使用SDK过程中遇到其他问题请联系CC客服进行反馈。
|
|
|
|
|
|
|
|
# 5.API查询
|
|
|
|
[https://github.com/CCVideo/VOD_iOS_ShortVideo_SDK/tree/master/doc/api](https://github.com/CCVideo/VOD_iOS_ShortVideo_SDK/blob/master/doc/api)
|
|
|
|
|
|
|
|
# 6.Q&A
|
|
|
|
|