|
@@ -47,6 +47,9 @@ public class PQCompositionExporter {
|
|
|
|
|
|
//导出时是否添加水印
|
|
|
var isAddWatermark:Bool = false
|
|
|
+
|
|
|
+ //是否合成片尾模式
|
|
|
+ var isEndMovie:Bool = false
|
|
|
|
|
|
public init(asset: AVAsset, videoComposition: AVVideoComposition? = nil, audioMix: AVAudioMix? = nil, filters: [ImageProcessingOperation]? = nil,stickers:[PQEditVisionTrackMaterialsModel]? = nil, animationTool: AVVideoCompositionCoreAnimationTool? = nil, exportURL: URL) {
|
|
|
self.asset = asset
|
|
@@ -195,83 +198,97 @@ public class PQCompositionExporter {
|
|
|
input!.removeAllTargets()
|
|
|
let currentTarget: ImageSource = input!
|
|
|
|
|
|
- //是否添加水印
|
|
|
- var weatMaskFilter:PQBaseFilter?
|
|
|
- if(isAddWatermark){
|
|
|
- //创建水印filter
|
|
|
- let weatMaskSticker:PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel.init()
|
|
|
- weatMaskSticker.locationPath = "watermark"
|
|
|
- weatMaskSticker.timelineIn = mStickers?.first?.timelineIn ?? 0.0
|
|
|
- weatMaskSticker.timelineOut = mStickers?.last?.timelineOut ?? 0.0
|
|
|
- /*
|
|
|
- 1080P 最短的一边 ≥1080 100% 距右40,距下30
|
|
|
- 720P 最短的一边 ≥720,<1080 66.60% 距右27,距下20
|
|
|
- 480P及以下 最短的一边<720 44.40% 距右18,距下14
|
|
|
- */
|
|
|
- let postion:PQEditMaterialPositionModel = PQEditMaterialPositionModel.init()
|
|
|
- let minSlider = min(input?.mShowVidoSize.width ?? 0, input?.mShowVidoSize.height ?? 0)
|
|
|
- postion.width = 350
|
|
|
- postion.height = 100
|
|
|
- if(minSlider >= 1080){
|
|
|
- postion.x = Int(input?.mShowVidoSize.width ?? 0) - 40 - postion.width
|
|
|
- postion.y = Int(input?.mShowVidoSize.height ?? 0) - 30 - postion.height
|
|
|
- }else if(minSlider >= 720 && minSlider < 1080){
|
|
|
- postion.width = Int(Float(postion.width) * 0.666)
|
|
|
- postion.height = Int(Float(postion.height) * 0.666)
|
|
|
- postion.x = Int(input?.mShowVidoSize.width ?? 0) - 27 - postion.width
|
|
|
- postion.y = Int(input?.mShowVidoSize.height ?? 0) - 20 - postion.height
|
|
|
+ //XXXXX TODO 这里不是最好的方案,应该使用group filter 目前能确保mStickers每一位: 0是背景视频,1,用户头像,2,用户名
|
|
|
+ if isEndMovie {
|
|
|
+ //头像
|
|
|
+ let avatarFilter = PQImageFilter(sticker: mStickers![1], isExport: true)
|
|
|
+ //用户名
|
|
|
+ let userNameFitler = PQTextFilter(sticker: mStickers![2])
|
|
|
+ currentTarget.addTarget(showFitler!, atTargetIndex: 0)
|
|
|
+ showFitler?.addTarget(avatarFilter,atTargetIndex: 0)
|
|
|
+ avatarFilter.addTarget(userNameFitler,atTargetIndex: 0)
|
|
|
+ userNameFitler.addTarget(output!, atTargetIndex: 0)
|
|
|
+ }else{
|
|
|
|
|
|
- }else if(minSlider < 720){
|
|
|
- postion.width = Int(Float(postion.width) * 0.444)
|
|
|
- postion.height = Int(Float(postion.height) * 0.444)
|
|
|
- postion.x = Int(input?.mShowVidoSize.width ?? 0) - 18 - postion.width
|
|
|
- postion.y = Int(input?.mShowVidoSize.height ?? 0) - 14 - postion.height
|
|
|
+ //是否添加水印
|
|
|
+ var weatMaskFilter:PQBaseFilter?
|
|
|
+ if(isAddWatermark){
|
|
|
+ //创建水印filter
|
|
|
+ let weatMaskSticker:PQEditVisionTrackMaterialsModel = PQEditVisionTrackMaterialsModel.init()
|
|
|
+ weatMaskSticker.locationPath = "watermark"
|
|
|
+ weatMaskSticker.timelineIn = mStickers?.first?.timelineIn ?? 0.0
|
|
|
+ weatMaskSticker.timelineOut = mStickers?.last?.timelineOut ?? 0.0
|
|
|
+ /*
|
|
|
+ 1080P 最短的一边 ≥1080 100% 距右40,距下30
|
|
|
+ 720P 最短的一边 ≥720,<1080 66.60% 距右27,距下20
|
|
|
+ 480P及以下 最短的一边<720 44.40% 距右18,距下14
|
|
|
+ */
|
|
|
+ let postion:PQEditMaterialPositionModel = PQEditMaterialPositionModel.init()
|
|
|
+ let minSlider = min(input?.mShowVidoSize.width ?? 0, input?.mShowVidoSize.height ?? 0)
|
|
|
+ postion.width = 350
|
|
|
+ postion.height = 100
|
|
|
+ if(minSlider >= 1080){
|
|
|
+ postion.x = Int(input?.mShowVidoSize.width ?? 0) - 40 - postion.width
|
|
|
+ postion.y = Int(input?.mShowVidoSize.height ?? 0) - 30 - postion.height
|
|
|
+ }else if(minSlider >= 720 && minSlider < 1080){
|
|
|
+ postion.width = Int(Float(postion.width) * 0.666)
|
|
|
+ postion.height = Int(Float(postion.height) * 0.666)
|
|
|
+ postion.x = Int(input?.mShowVidoSize.width ?? 0) - 27 - postion.width
|
|
|
+ postion.y = Int(input?.mShowVidoSize.height ?? 0) - 20 - postion.height
|
|
|
+
|
|
|
+ }else if(minSlider < 720){
|
|
|
+ postion.width = Int(Float(postion.width) * 0.444)
|
|
|
+ postion.height = Int(Float(postion.height) * 0.444)
|
|
|
+ postion.x = Int(input?.mShowVidoSize.width ?? 0) - 18 - postion.width
|
|
|
+ postion.y = Int(input?.mShowVidoSize.height ?? 0) - 14 - postion.height
|
|
|
+
|
|
|
+ }
|
|
|
+ weatMaskSticker.materialPosition = postion
|
|
|
+
|
|
|
+ weatMaskFilter = PQImageFilter(sticker: weatMaskSticker, isExport: true)
|
|
|
|
|
|
}
|
|
|
- weatMaskSticker.materialPosition = postion
|
|
|
-
|
|
|
- weatMaskFilter = PQImageFilter(sticker: weatMaskSticker, isExport: true)
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if(currentSticker?.type == StickerType.IMAGE.rawValue && showGaussianBlur){
|
|
|
- //高斯层
|
|
|
- let json = currentSticker?.toJSONString(prettyPrint: false)
|
|
|
- if json == nil {
|
|
|
- BFLog(message: "数据转换有问题 跳转")
|
|
|
- return
|
|
|
- }
|
|
|
- let blurStickerModel: PQEditVisionTrackMaterialsModel? = Mapper<PQEditVisionTrackMaterialsModel>().map(JSONString: json!)
|
|
|
- blurStickerModel?.canvasFillType = stickerContentMode.aspectFillStr.rawValue
|
|
|
- let showGaussianFitler:PQBaseFilter = PQImageFilter(sticker: blurStickerModel!)
|
|
|
|
|
|
- let iosb:GaussianBlur = GaussianBlur.init()
|
|
|
- iosb.blurRadiusInPixels = 20
|
|
|
- showGaussianFitler.addTarget(iosb)
|
|
|
-
|
|
|
- currentTarget.addTarget(showGaussianFitler, atTargetIndex: 0)
|
|
|
-
|
|
|
- iosb.addTarget(showFitler!)
|
|
|
-
|
|
|
- if(weatMaskFilter != nil){
|
|
|
- showFitler?.addTarget(weatMaskFilter!, atTargetIndex: 0)
|
|
|
- weatMaskFilter?.addTarget(output!,atTargetIndex: 0)
|
|
|
- }else{
|
|
|
- showFitler?.addTarget(output!, atTargetIndex: 0)
|
|
|
- }
|
|
|
-
|
|
|
- }else{
|
|
|
- if(weatMaskFilter != nil){
|
|
|
+ if(currentSticker?.type == StickerType.IMAGE.rawValue && showGaussianBlur){
|
|
|
+ //高斯层
|
|
|
+ let json = currentSticker?.toJSONString(prettyPrint: false)
|
|
|
+ if json == nil {
|
|
|
+ BFLog(message: "数据转换有问题 跳转")
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let blurStickerModel: PQEditVisionTrackMaterialsModel? = Mapper<PQEditVisionTrackMaterialsModel>().map(JSONString: json!)
|
|
|
+ blurStickerModel?.canvasFillType = stickerContentMode.aspectFillStr.rawValue
|
|
|
+ let showGaussianFitler:PQBaseFilter = PQImageFilter(sticker: blurStickerModel!)
|
|
|
+
|
|
|
+ let iosb:GaussianBlur = GaussianBlur.init()
|
|
|
+ iosb.blurRadiusInPixels = 20
|
|
|
+ showGaussianFitler.addTarget(iosb)
|
|
|
|
|
|
- currentTarget.addTarget(showFitler!, atTargetIndex: 0)
|
|
|
- showFitler?.addTarget(weatMaskFilter!, atTargetIndex: 0)
|
|
|
- weatMaskFilter?.addTarget(output!, atTargetIndex: 0)
|
|
|
+ currentTarget.addTarget(showGaussianFitler, atTargetIndex: 0)
|
|
|
+
|
|
|
+ iosb.addTarget(showFitler!)
|
|
|
+
|
|
|
+ if(weatMaskFilter != nil){
|
|
|
+ showFitler?.addTarget(weatMaskFilter!, atTargetIndex: 0)
|
|
|
+ weatMaskFilter?.addTarget(output!,atTargetIndex: 0)
|
|
|
+ }else{
|
|
|
+ showFitler?.addTarget(output!, atTargetIndex: 0)
|
|
|
+ }
|
|
|
+
|
|
|
}else{
|
|
|
- currentTarget.addTarget(showFitler!, atTargetIndex: 0)
|
|
|
- showFitler?.addTarget(output!, atTargetIndex: 0)
|
|
|
+ if(weatMaskFilter != nil){
|
|
|
+
|
|
|
+ currentTarget.addTarget(showFitler!, atTargetIndex: 0)
|
|
|
+ showFitler?.addTarget(weatMaskFilter!, atTargetIndex: 0)
|
|
|
+ weatMaskFilter?.addTarget(output!, atTargetIndex: 0)
|
|
|
+ }else{
|
|
|
+ currentTarget.addTarget(showFitler!, atTargetIndex: 0)
|
|
|
+ showFitler?.addTarget(output!, atTargetIndex: 0)
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
+
|
|
|
|
|
|
lastshowSticker = currentSticker
|
|
|
}
|