美摄SDK For iOS
3.14.0
|
美摄SDK致力于解决移动端视频开发的技术门槛,使仅有ios界面开发经验的程序员,都可以开发出性能优异、渲染效果丰富的的视频录制、编辑功能。我们的优势体现在:
美摄SDK的所有接口必须在UI线程调用,否则可能出现无法预料的错误。只有NvsVideoFrameRetriever类的getFrameAtTime()方法除外。
运行环境如下:ios 9.0以上
如果没有SDK,请从美摄官网:https://www.meishesdk.com/downloads下载最新ios开发版本。Xcode编辑器开发流程详见:https://www.meishesdk.com/ios/doc_ch/html/content/PortingGuide_8md.html。
录制的相关接口是在NvsStreamingContext类里,包括采集预览(startCapturePreview:videoResGrade:flags:aspectRatio:),录制(startRecording:),添加视频采集特效(appendBuiltinCaptureVideoFx:)等。强调:美摄SDK所有的类都是以“Nvs”开头。
视频录制时需要注意以下两点:
如果查看视频录制的具体功能实现,建议参考SdkDemo的视频拍摄模块。注意: 视频录制和视频生成时只支持输出.mov和.mp4格式的文件
NvsStreamingContext是美摄SDK的流媒体上下文类,可视作整个SDK框架的入口。在开始使用美摄SDK的时候,需要先初始化NvsStreamingContext类,然后在其它地方使用时 获取NvsStreamingContext的对象,NvsStreamingContext是单例类。在不再使用美摄SDK或者程序退出前销毁NvsStreamingContext类的对象,请务必保证不要中途销毁NvsStreamingContext类的对象!!!
NvsStreamingContext初始化代码如下:
_context = [NvsStreamingContext sharedInstance];
NvsStreamingContext销毁代码如下:
_context = nil; [NvsStreamingContext destroyInstance];
注意:NvsStreamingContext初始化前,需要调用verifySdkLicenseFile()验证授权文件。参数sdkLicenseFilePath为授权文件路径,没有授权文件时置为空字符串。
NvsLiveWindow类是用来录制时预览或者编辑时预览的。NvsLiveWindow的宽高比应该是1:1,4:3,16:9,9:16等,最好与采集预览startCapturePreview:videoResGrade:flags:aspectRatio:的参数aspectRatio值保持一致。否则,预览的图像是录制完的视频被裁剪后的图像。
NvsLiveWindow的填充模式:
typedef enum { //图像按比例均匀填充,必要时进行裁剪(默认模式) NvsLiveWindowFillModePreserveAspectCrop = 0, //图像均匀地缩放来适合窗口,没有裁剪 NvsLiveWindowFillModePreserveAspectFit, //图像被缩放来适合窗口 NvsLiveWindowFillModeStretch } NvsLiveWindowFillMode;
对于三种填充模式,图片展示如下:
// 可用采集设备的数量 if ([_context captureDeviceCount] == 0) { NSLog(@"没有可用于采集的设备"); return; } // 将采集预览输出连接到NvsLiveWindow控件 if (![_context connectCapturePreviewWithLiveWindow:self.liveWindow]) { NSLog(@"连接预览窗口失败"); return; } // 给NvsStreamingContext设置代理(必须要设置!!!) _context.delegate = self;
在启动视频录制之前,要进行视频采集预览。
//启动采集预览 _aspectRatio.den = 1; _aspectRatio.num = 1; if (![_context startCapturePreview:0 videoResGrade:NvsVideoCaptureResolutionGradeHigh flags:0 aspectRatio:&m_aspectRatio]) { ...... }
有两种录制视频的方式:不带特效录制与带特效录制。更多请参考:https://www.meishesdk.com/ios/doc_ch/html/content/videoRecorderMode_8md.html
[_context startRecording:outputFilePath];
[_context startRecordingWithFx:outputFilePath];
录制startRecording()和startRecordingWithFx()的参数outputFilePath是录制视频文件的路径。
停止视频录制:
[_context stopRecording];
设置闪光灯是否开启:
[_context toggleFlash:YES];
自动聚焦:
CGPoint point = CGPointMake(100, 200); [_context startAutoFocus:point];
设置曝光补偿:
[_context setExposureBias:1];
设置缩放:
[_context setZoomFactor:0.8];
添加美颜特效后,在预览窗口就可以看到美颜效果。录制视频时,用户需要根据手机性能任意选择带美颜录制或者不带美颜录制。 美颜特效可设置磨皮、美白,红润,基础美颜效果,基础美颜效果的程度,锐化。具体美颜效果可以参考SdkDemo的“视频拍摄”模块。
代码如下:
NvsCaptureVideoFx* beautyFx = [_context appendBeautyCaptureVideoFx];//添加美颜特效 [beautyFx setFloatVal:@"Strength" val:0.5];//设置美颜磨皮值 [beautyFx setFloatVal:@"Whitening" val:0.5];//设置美白强度值 [beautyFx setFloatVal:@"Reddening" val:0.5];//设置红润强度值 [beautyFx setBooleanVal:@"Default Beauty Enabled" val:YES];//设置基础美颜的开关 [beautyFx setBooleanVal:@"Default Sharpen Enabled" val:YES];//设置锐化的开关 [beautyFx setFloatVal:@"Default Intensity" val:0.5];//设置基础美颜的强度
采集特效分为两种,内建采集特效和扩展采集特效,扩展采集特效即通过资源包安装而得到的采集特效。
获取内建采集特效名称可以参考列表:https://www.meishesdk.com/ios/doc_ch/html/content/FxNameList_8md.html。
添加与移除特效:
[_context appendBuiltinCaptureVideoFx:fxName]; [_context removeAllCaptureVideoFx];
使用扩展采集特效,首先安装资源包,获取资源包ID值,然后添加扩展采集特效。例如,此处采用同步方式安装资源包,如果资源包尺寸太大或者根据需要可使用异步安装方式。
_fxPackageId = [[NSMutableString alloc] initWithString:@""]; NSString *appPath =[[NSBundle mainBundle] bundlePath]; NSString *packagePath = [appPath stringByAppendingPathComponent:@"7FFCF99A-5336-4464-BACD-9D32D5D2DC5E.videofx"]; NvsAssetPackageManagerError error = [_context.assetPackageManager installAssetPackage:packagePath license:nil type:NvsAssetPackageType_VideoFx sync:YES assetPackageId:_fxPackageId]; if (error != NvsAssetPackageManagerError_NoError && error != NvsAssetPackageManagerError_AlreadyInstalled) { NSLog(@"Failed to install"); } //添加扩展采集特效 [_context appendPackagedCaptureVideoFx:_fxPackageId];
实现视频编辑的一般步骤:
//NvsStreamingContext初始化 NvsStreamingContext *_context = [NvsStreamingContext sharedInstance];
创建timeline对于编辑是非常关键的,timeline的分辨率决定了生成视频文件的最大分辨率(尺寸)。请将timeline的分辨率和NvsLiveWindow的宽高比适配一致。
NvsVideoResolution videoEditRes; videoEditRes.imageWidth = 1280;//视频分辨率的宽*/ videoEditRes.imageHeight = 720;//视频分辨率的高 videoEditRes.imagePAR = (NvsRational){1, 1};//像素比,设为1:1 NvsRational videoFps = {25, 1};//帧速率,25或者30都可以,一般25。 NvsAudioResolution audioEditRes; audioEditRes.sampleRate = 48000;//音频采样率,48000或44100均可 audioEditRes.channelCount = 2;//音频通道数 audioEditRes.sampleFormat = NvsAudSmpFmt_S16;//音频采样格式 //创建时间线 NvsTimeline *_timeline = [_context createTimeline:&videoEditRes videoFps:&videoFps audioEditRes:&audioEditRes]; // 将时间线连接到NvsLiveWindow控件,用于预览时间线上的图像 if (![_context connectTimeline:_timeline withLiveWindow:self.liveWindow]) { NSLog(@"Failed to connect timeline to liveWindow!"); return; }
一般情况下创建一条视频轨道,然后往轨道上添加图片或者视频素材。添加到轨道上的素材,我们称它为片段(clip)。图片和视频素材都是通过文件路径添加到轨道上。 请注意:如果图片素材尺寸过大,需要降低图片尺寸,降低尺寸后的图片和创建timeline的分辨率的尺寸大小匹配最好。
添加视频轨道:
NvsVideoTrack *_videoTrack = [_timeline appendVideoTrack];
添加音频轨道:
NvsAudioTrack *_audioTrack = [_timeline appendAudioTrack];
添加片段:
NSString* videoUrl = @"file:///var/mobile/Media/DCIM/102APPLE/IMG_2625.MOV"; [_videoTrack appendClip:videoUrl];
对于播放与定位预览接口,其参数videoSizeMode建议设置为NvsVideoPreviewSizeModeLiveWindowSize。若无特殊需求,设为NvsVideoPreviewSizeModeFullSize的模式会影响性能。 preload是预加载,设为YES。注意:美摄SDK的时间单位是微秒,1/1000000秒。
视频播放,playbackTimeline:startTime:endTime:videoSizeMode:preload:flags:的参数endTime,值可以是_timeline.duration或者-1。
[_context playbackTimeline:_timeline startTime:startTime endTime:_timeline.duration videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize preload:YES flags:0];
视频定位预览:
[_context seekTimeline:_timeline timestamp:0 videoSizeMode:NvsVideoPreviewSizeModeLiveWindowSize flags:NvsStreamingEngineSeekFlag_ShowCaptionPoster | NvsStreamingEngineSeekFlag_ShowAnimatedStickerPoster]
改变片段的入出点,裁剪片段。
NvsVideoClip *clip = [_videoTrack getClipWithIndex:0]; [clip changeTrimInPoint:1000000 affectSibling:YES]; [clip changeTrimOutPoint:5000000 affectSibling:YES];
删除片段:
[_videoTrack removeClip:0 keepSpace:NO];
轨道上的片段可以互换位置,moveClip:destClipIndex:的参数clipIndex和destClipIndex分别代表互换的两个素材的位置索引。
[_videoTrack moveClip:0 destClipIndex:1];
NvsVideoTrack类提供appendClip:trimIn:trimOut:可以根据需要来设定图片时长。 filePath是图片素材的路径,trimIn设置0,trimOut设置为8000000,则图片显示为8秒。
[_videoTrack appendClip:asset.localIdentifier trimIn:0 trimOut:8000000];
如果通过appendClip:添加图片,则图片默认显示时长是4秒。
创建的时间线,添加的视频轨道和音频轨道,如果当前不再需要,则要进行移除。操作如下:
移除时间线:
[_context removeTimeline:_timeline];
移除视频轨道:
[_timeline removeVideoTrack:0];
移除音频轨道:
[_timeline removeAudioTrack:0];
给视频添加音乐是通过音频轨道添加音频片段实现的。创建时间线后,通过appendAudioTrack添加音频轨道,然后把音乐文件以音频片段的形式添加到音频轨道上即可。可以添加多段音乐,音乐会连续播放。
//添加音频轨道 NvsAudioTrack *_audioTrack = [_timeline appendAudioTrack]; [_audioTrack appendClip:asset.localIdentifier];
音乐裁剪与视频裁剪是一样的,也是通过设置入出点的方式进行裁剪。
//获取音频片段对象 NvsAudioClip *clip = [_audioTrack getClipWithIndex:0]; [clip changeTrimInPoint:1000000 affectSibling:YES]; [clip changeTrimOutPoint:5000000 affectSibling:YES];
添加,删除以及获取字幕都是在时间线(timeline)上进行执行的,可以参考SdkDemo示例的字幕编辑模块。
添加字幕,可设置字幕显示的时长。
[_timeline addCaption:@"Meishe SDK" inPoint:1000000 duration:5000000 captionStylePackageId:_captionStylePackageId];
移除字幕,返回下一个时间线字幕对象。如果没有下一个字幕,则返回nil。
NvsTimelineCaption *caption = [_timeline getFirstCaption]; while (caption) { caption = [_timeline removeCaption:caption]; }
有多种方式获取字幕:
//获得时间线上的第一个字幕 NvsTimelineCaption *firstCaption = [_timeline getFirstCaption]; //获得时间线上的最后一个字幕 NvsTimelineCaption *lastCaption = [_timeline getLastCaption]; //获得时间线上的当前字幕的前一个字幕 NvsTimelineCaption *prevCaption = [_timeline getPrevCaption:currentCaption]; //获得时间线上的当前字幕的后一个字幕 NvsTimelineCaption *nextCaption = [_timeline getNextCaption:currentCaption];
根据时间线上的位置获得字幕,返回保存当前位置字幕的List集合。获取的字幕列表排序规则如下:
1.添加时字幕入点不同,按入点的先后顺序排列;
2.添加时字幕入点相同,按添加字幕的先后顺序排列。
NSArray *captionArray = [_timeline getCaptionsByTimelinePosition:1000000];
修改字幕属性可通过NvsTimelineCaption类的方法实现。获取字幕后,可设置字幕文本,颜色,加粗,斜体,描边等。
以修改字幕文本为例:
[currentCaption setText:@"Meishe SDK"];
如果是全景图字幕,还可以设置字幕中心点的极角,字幕中心点的方位角等。以设置字幕中心点的极角为例:
[currentCaption setCenterPolarAngle:1.2];
获取字幕后,可以修改字幕在时间线上的入点,出点以及偏移值。
//改变入点 [currentCaption changeInPoint:1000000]; //改变出点 [currentCaption changeOutPoint:5000000]; //改变显示位置(入点和出点同时偏移offset值) [currentCaption movePosition:1000000];
添加,删除以及获取动画贴纸也是在时间线(timeline)上进行执行的,可以参考SdkDemo示例的贴纸模块。
添加动画贴纸:
[_timeline addAnimatedSticker:1000000 duration:5000000 animatedStickerPackageId:_stickerPackageId];
移除动画贴纸,返回当前贴纸的下一个贴纸。如果没有下一下贴纸,则返回nil。
NvsTimelineAnimatedSticker *nextSticker = [_timeline removeAnimatedSticker:currentSticker];
有多种方式获取时间线上添加的动画贴纸。
//获取时间线上第一个动画贴纸 NvsTimelineAnimatedSticker *firstSticker = [_timeline getFirstAnimatedSticker]; //获取时间线上最后一个动画贴纸 NvsTimelineAnimatedSticker *lastSticker = [_timeline getLastAnimatedSticker]; //获取时间线当前动画贴纸的前一个动画贴纸 NvsTimelineAnimatedSticker *prevSticker = [_timeline getPrevAnimatedSticker:currentSticker]; //获取时间线当前动画贴纸的后一个动画贴纸 NvsTimelineAnimatedSticker *nextSticker = [_timeline getNextAnimatedSticker:currentSticker];
根据时间线上的位置获得动画贴纸,返回保存当前位置动画贴纸对象的List集合 获取的动画贴纸列表排序规则如下:
1.添加时入点不同,按入点的先后顺序排列;
2.添加时入点相同,按添加动画贴纸的先后顺序排列。
NSArray *stickerArray = [_timeline getAnimatedStickersByTimelinePosition:5000000];
修改贴纸属性可通过NvsTimelineAnimatedSticker类的方法实现。获取贴纸后,可设置缩放值,水平翻转,旋转角度,平移等。
以修改贴纸缩放为例:
[currentSticker setScale:1.2];
如果是全景图动画贴纸,则还可以设置贴纸中心点的极角,中心点的方位角等。以设置中心点的极角为例:
[currentSticker setCenterPolarAngle:0.8];
获取贴纸后,可以修改动画贴纸在时间线上的入点,出点以及偏移值。
//改变入点 [currentSticker changeInPoint:1000000]; //改变出点 [currentSticker changeOutPoint:5000000]; //改变显示位置(入点和出点同时偏移offset值) [currentSticker movePosition:1000000];
编辑视频时,如果需要运用主题,则可通过时间线(timeline)实现添加,移除。
运用主题:
[_timeline applyTheme:_themePackageId];
移除主题: [_timeline removeCurrentTheme];
获取当前主题包Id:
[_timeline getCurrentThemeId];
运用主题后,可以设置主题片头,片尾,主题音乐音量等,以设置主题片头为例:
[_timeline setThemeTitleCaptionText:@"Meishe SDK"];
转场包括视频转场和音频转场。视频转场是在视频轨道上设置的,音频转场是在音频轨道上设置的。
视频转场包括内嵌式转场和包裹式转场。设置视频内嵌转场:
[_videoTrack setBuiltinTransition:0 withName:transName];
视频包裹式转场:
[_videoTrack setPackagedTransition:1 withPackageId:m_transiPackageId];
同样地,音频转场同视频转场是相同用法,用户可参照使用。
在视频后续编辑中,经常会使用到几种特效,分别是视频特效(NvsVideoFx),音频特效(NvsAudioFx),时间线视频特效(NvsTimelineVideoFx)。
视频特效是使用在视频片段上的,每个视频片段可以添加若干个视频特效。视频特效包括内嵌视频特效,包裹视频特效,美颜特效。
添加内嵌视频特效:
[videoClip appendBuiltinFx:fxName];
添加包裹视频特效:
[videoClip appendPackagedFx:_videoFxPackageId];
添加美颜特效:
[videoClip appendBeautyFx];
移除视频特效包括移除指定索引值特效和移除所有视频特。
移除指定索引值的特效:
[videoClip removeFx:0];
移除所有视频特效:
[videoClip removeAllFx];
音频特效是使用在音频片段上的,每个音频片段可以添加若干个音频特效。
添加音频特效:
[audioClip appendFx:fxName];
移除指定索引的音频特效:
[audioClip removeFx:0];
时间线视频特效是使用在时间线上的一种特效,包含内嵌特效和包裹特效。时间线上可以添加若干个时间线视频特效。
添加时间线特效:
[_timeline addBuiltinTimelineVideoFx:1000000 duration:5000000 videoFxName:_fxName]; [_timeline addPackagedTimelineVideoFx:1000000 duration:5000000 videoFxPackageId:_fxPackageId];
有多种方法获取时间线特效。
//获取时间线上第一个时间线视频特效 NvsTimelineVideoFx *firstTimelineFx = [_timeline getFirstTimelineVideoFx]; //获取时间线上最后一个时间线视频特效 NvsTimelineVideoFx *lastTimelineFx = [_timeline getLastTimelineVideoFx]; //获取时间线上某个时间线视频特效的前一个时间线视频特效 NvsTimelineVideoFx *prevTimelineFx = [_timeline getPrevTimelineVideoFx:currentTimelineFx]; //获取时间线上某个时间线视频特效的下一个时间线视频特效 NvsTimelineVideoFx *nextTimelineFx = [_timeline getNextTimelineVideoFx:currentTimelineFx];
根据时间线上的位置获得时间线视频特效,返回当前位置时间线视频特效对象的数组。 获取的时间线视频特效数组排序规则如下:
1.添加时入点不同,按入点的先后顺序排列;
2.添加时入点相同,按添加时间线视频特效的先后顺序排列。
NSArray *timelineFxArray = [_timeline getTimelineVideoFxByTimelinePosition:5000000];
获取时间线特效后,可以修改时间线特效在时间线上的入点,出点以及偏移值。
//改变入点 [currentTimelineFx changeInPoint:1000000]; //改变出点 [currentTimelineFx changeOutPoint:5000000]; //改变显示位置(入点和出点同时偏移offset值) [currentTimelineFx movePosition:1000000];
美摄SDK使用compileTimeline()用于将时间线上的片段生成输出一个新的视频。
生成视频:
[_context compileTimeline:_timeline startTime:0 endTime:_timeline.duration outputFilePath:_outputFilePath videoResolutionGrade:NvsCompileVideoResolutionGrade720 videoBitrateGrade:NvsCompileBitrateGradeHigh flags:0]
美摄SDK提供了丰富的素材库,包括动画贴纸,主题,字幕样式,转场等。素材包可以从网络上下载,或者由美摄SDK项目组提供,用户可以根据需要选择使用这些素材包。美摄SDK通过NvsAssetPackageManager类对这些素材包进行管理,可以安装,升级,卸载,获取素材包的状态,版本号等。
素材包安装:
//此处采用同步安装方式,如果包裹过大可采用异步方式 NvsAssetPackageManagerError error = [_context.assetPackageManager installAssetPackage:package1Path license:nil type:NvsAssetPackageType_VideoFx sync:YES assetPackageId:_fxPackageId];
素材包升级:
//此处采用同步升级方式,如果包裹过大可采用异步方式 NvsAssetPackageManagerError error = [_context.assetPackageManager upgradeAssetPackage:package1Path license:nil type:NvsAssetPackageType_VideoFx sync:YES assetPackageId:_fxPackageId];
素材包卸载:
NvsAssetPackageManagerError error = [_context.assetPackageManager uninstallAssetPackage:_fxPackageId type:NvsAssetPackageType_VideoFx];
美摄SDK提供了很多代理接口,如果要查询采集设备状态,采集录制状态,视频播放状态,文件生成状态,资源包安装状态等,则必须在创建NvsStreamingContext对象后设置代理并实现对应的代理接口。
设置代理:
//必须设置代理 _context.delegate = self;
美摄SDK版本包括极速版,标准功能版,全功能PRO版,对于每个版本产品的功能点,请参考:https://www.meishesdk.com/editsdk,会有详细介绍。每个用户可根据个人需要选择使用,具体请联系美摄商务。