161 lines
5.5 KiB
Swift
161 lines
5.5 KiB
Swift
//
|
|
// ViewController.swift
|
|
// SimpleVideoTransition
|
|
//
|
|
// Created by RenZhu Macro on 2020/7/2.
|
|
// Copyright © 2020 RenZhu Macro. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import MetalVideoProcess
|
|
import AVFoundation
|
|
|
|
class ViewController: UIViewController {
|
|
|
|
@IBOutlet weak var renderView: MetalVideoProcessRenderView!
|
|
@IBOutlet weak var progress: UISlider!
|
|
var player: MetalVideoProcessPlayer?
|
|
var beauty1: MetalVideoProcessBeautyFilter?
|
|
var beauty2: MetalVideoProcessBeautyFilter?
|
|
|
|
var blur1: MetalVideoProcessGaussianBlurFilter?
|
|
var blur2: MetalVideoProcessGaussianBlurFilter?
|
|
|
|
var grayFilter: MetalVideoProcessLuminance?
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
let asset1 = AVAsset(url: Bundle.main.url(forResource: "853", withExtension: "mp4")!)
|
|
let asset2 = AVAsset(url: Bundle.main.url(forResource: "cute", withExtension: "mp4")!)
|
|
let item1 = MetalVideoEditorItem(asset: asset1)
|
|
let item2 = MetalVideoEditorItem(asset: asset2)
|
|
|
|
//set transition before build editor
|
|
let transitionDuration = CMTime.init(seconds: 2.0, preferredTimescale: 600)
|
|
item1.videoTransition = TransitionDuration(duration: transitionDuration)
|
|
item1.audioTransition = FadeInOutAudioTransition(duration: transitionDuration)
|
|
do {
|
|
let editor = try MetalVideoEditor(videoItems: [item1, item2],
|
|
customVideoCompositorClass: MetalVideoProcessCompositor.self)
|
|
|
|
let playerItem = editor.buildPlayerItem()
|
|
self.progress.maximumValue = Float(playerItem.duration.seconds)
|
|
let player = try MetalVideoProcessPlayer(playerItem: playerItem)
|
|
|
|
let beautyFilter1 = MetalVideoProcessBeautyFilter()
|
|
beautyFilter1.saveUniformSettings(forTimelineRange: item1.timeRange, trackID: item1.trackID)
|
|
beautyFilter1.isEnable = false
|
|
|
|
let beautyFilter2 = MetalVideoProcessBeautyFilter()
|
|
beautyFilter2.saveUniformSettings(forTimelineRange: item2.timeRange, trackID: item2.trackID)
|
|
beautyFilter2.isEnable = false
|
|
|
|
let blurFilter1 = MetalVideoProcessGaussianBlurFilter()
|
|
blurFilter1.saveUniformSettings(forTimelineRange: item1.timeRange, trackID: item1.trackID)
|
|
blurFilter1.isEnable = false
|
|
|
|
let blurFilter2 = MetalVideoProcessGaussianBlurFilter()
|
|
blurFilter2.saveUniformSettings(forTimelineRange: item2.timeRange, trackID: item2.trackID)
|
|
blurFilter2.isEnable = false
|
|
|
|
let gray = MetalVideoProcessLuminance()
|
|
gray.isEnable = false
|
|
self.grayFilter = gray
|
|
|
|
self.beauty1 = beautyFilter1
|
|
self.beauty2 = beautyFilter2
|
|
|
|
self.blur1 = blurFilter1
|
|
self.blur2 = blurFilter2
|
|
|
|
let transitionTimeRange = item1.timeRange.intersection(item2.timeRange)
|
|
let fadeTransition = MetalVideoProcessFadeTransition()
|
|
|
|
//注意顺序 第一个视频在前 第二视频在后
|
|
fadeTransition.mainTrackIDs.append(item1.trackID)
|
|
fadeTransition.mainTrackIDs.append(item2.trackID)
|
|
|
|
//告知转场的时间 通过item1和item2的intersection计算
|
|
fadeTransition.saveUniformSettings(forTimelineRange: transitionTimeRange, trackID: 0)
|
|
item1.transitoin = fadeTransition
|
|
|
|
//Begin build pipeline
|
|
player.addTarget(beautyFilter1, atTargetIndex: nil, trackID: item1.trackID, targetTrackId: 0)
|
|
player.addTarget(beautyFilter2, atTargetIndex: nil, trackID: item2.trackID, targetTrackId: item2.trackID)
|
|
//mapping trackId on mainTrack 0
|
|
|
|
beautyFilter1 --> blurFilter1 --> fadeTransition
|
|
beautyFilter2 --> blurFilter2 --> fadeTransition --> gray --> renderView
|
|
//Done
|
|
|
|
self.player = player
|
|
self.player?.playerDelegate = self
|
|
|
|
} catch {
|
|
debugPrint("init error")
|
|
}
|
|
}
|
|
|
|
@IBAction func play(_ sender: Any) {
|
|
self.player?.play()
|
|
}
|
|
|
|
@IBAction func pause(_ sender: Any) {
|
|
self.player?.pause()
|
|
}
|
|
|
|
@IBAction func progressChanged(_ sender: UISlider) {
|
|
let value = sender.value
|
|
self.player?.seekTo(time: Float64(value))
|
|
}
|
|
|
|
@IBAction func filterOn(_ sender: UISwitch) {
|
|
var operation: MetalVideoProcessOperation?
|
|
switch sender.tag {
|
|
case 0:
|
|
operation = self.beauty1
|
|
break
|
|
case 1:
|
|
operation = self.blur1
|
|
|
|
break
|
|
case 2:
|
|
operation = self.beauty2
|
|
break
|
|
case 3:
|
|
operation = self.blur2
|
|
break
|
|
case 4:
|
|
operation = self.grayFilter
|
|
break
|
|
default:
|
|
break
|
|
}
|
|
operation?.isEnable = sender.isOn
|
|
}
|
|
}
|
|
|
|
extension ViewController: MetalVideoProcessPlayerDelegate {
|
|
func playbackFrameTimeChanged(frameTime time: CMTime, player: AVPlayer) {
|
|
DispatchQueue.main.async {
|
|
self.progress.value = Float(time.seconds)
|
|
}
|
|
}
|
|
|
|
func playEnded(currentPlayer player: AVPlayer) {
|
|
|
|
}
|
|
|
|
func finishExport(error: NSError?) {
|
|
|
|
}
|
|
|
|
func exportProgressChanged(_ progress: Float) {
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|