[教程]如何使用ABVideoRangeSlider在iOS中修剪视频-第1部分,共2部分
本教程由Swift 3使用ABVideoRangeSlider库制作。 在此示例中,我们包括了一个简单的视频播放器。
此示例托管在我们的Github存储库中!
创建项目
让我们使用Single View Application模板创建新项目:
我们称之为视频编辑器
准备用户界面
首先,让我们创建视频播放器。 转到您的Main.Storyboard
并添加一个UIView
并设置约束
并添加两个按钮:播放和暂停
将这些按钮连接到您的ViewController.swift:
@IBOutlet var btnPlay:UIButton!
@IBOutlet var btnPause:UIButton!
与包含我们视频的UIView
相同
@IBOutlet var videoContainer:UIView!
将视频添加到我们的项目
将视频拖放到项目导航器中,在这种情况下,我正在使用mp4视频。 并确保检查是否需要复制项目以及项目的目标 。
转到您的ViewController.swift并在ViewDidLoad方法中添加以下行:
let path = Bundle.main.path(forResource:“ test”,ofType:“ mp4”)
现在,为了播放该视频,我们需要将AVFoundation导入到我们的控制器中:
导入AVFoundation
并将这两个属性添加到我们的控制器中:
让avPlayer = AVPlayer()
var avPlayerLayer:AVPlayerLayer!
初始化AVPlayer和AVPlayerLayer
取得视频的路径后,我们需要创建一个AVPlayerItem
使用该路径,并初始化avPlayer
:
让playerItem = AVPlayerItem(URL:URL(fileURLWithPath:path))
avPlayer.replaceCurrentItem(with:playerItem)
并设置我们的avPlayerLayer
:
avPlayerLayer = AVPlayerLayer(玩家:avPlayer)
videoContainer.layer.insertSublayer(avPlayerLayer,at:0)
videoContainer.layer.masksToBounds = true
最后两行,我们将该层添加到videoContainer
。 为了确保我们的视频播放器适合我们的容器,我们必须将此行添加到viewWillLayoutSubviews
方法中:
覆盖func viewDidLayoutSubviews(){
super.viewWillLayoutSubviews()
avPlayerLayer.frame = videoContainer.bounds
}
现在将相应的动作添加到我们的按钮“播放”和“暂停”中,并通过Interface Builder将它们连接起来:
@IBAction func playTapped(_ sender:Any){
avPlayer.play()
btnPlay.isEnabled = false
btnPause.isEnabled = true
}
@IBAction func pauseTapped(_ sender:Any){
avPlayer.pause()
btnPlay.isEnabled = true
btnPause.isEnabled =假
}
我们的ViewController.swift应该看起来像这样:
现在我们可以停止播放视频了,但是我们无法搜索到特定时间(尚未!)。 因此,让我们添加我们的ABVideoRangeSlider,它集成了进度指示器,可以为我们提供帮助。
添加ABVideoRangeSlider窗格
打开终端并转到项目的根文件夹,并使用以下命令创建Podfile
:
荚初始化
打开Podfile
并添加:
目标“视频编辑”
use_frameworks!
pod'ABVideoRangeSlider'
结束
并运行pod install
。 安装后,请记住关闭当前项目并打开新的.xcworkspace
文件。
现在已经安装了ABVideoRangelSlider ,让我们将其添加到Main.storyboard
:
将UIView
拖到视图中,并设置约束。 我将高度值设置为40,并将背景颜色更改为深灰色。 然后将其类更改为ABVideoRangeSlider:
并将此新视图连接到我们的ViewController.swift:
@IBOutlet var rangeSlider:ABVideoRangeSlider!
然后在viewDidLoad
,为我们的rangeSlider
设置视频网址:
rangeSlider.setVideoURL(videoURL:URL(fileURLWithPath:path))
运行项目,视频预览将出现在我们的范围滑块中。 但是我们的进度指示器根本没有动。 让我们添加我们的代码以使其工作!
我们需要先向控制器添加一些新属性:
var startTime = 0.0;
var endTime = 0.0;
var progressTime = 0.0;
var shouldUpdateProgressIndicator = true
var isSeeking = false
这些值将存储视频的开始和结束时间(以秒为单位),用于告知应用程序进度指示器是否应该更新的标志,以及用于告知玩家是否正在寻找的标志。
在我们的viewDidLoad
,将endTime设置为视频的总时长。
self.endTime = CMTimeGetSeconds((avPlayer.currentItem?.duration)!)
我们已经设置了rangeSlider,但尚未实现委托。 添加ABVideoRangeSliderDelegate
并在设置视频网址后添加以下行:
rangeSlider.delegate =自我
并添加委托方法:
func didChangeValue(videoRangeSlider:ABVideoRangeSlider,startTime:Float64,endTime:Float64){
}
func indicatorDidChangePosition(videoRangeSlider:ABVideoRangeSlider,位置:Float64){
}
第一种方法是跟踪开始和结束指示器,以秒为单位返回当前位置的时间。
第二种方法以秒为单位返回进度指示器的时间。 当拖动该指标时调用它。
添加时间观察者
向控制器添加另一个属性
var timeObserver:AnyObject!
并在viewDidLoad
内部初始化它:
let timeInterval:CMTime = CMTimeMakeWithSeconds(0.01,100)
timeObserver = avPlayer.addPeriodicTimeObserver(forInterval:timeInterval,
队列:DispatchQueue.main){(elapsedTime:CMTime)->在
self.observeTime(elapsedTime:elapsedTime)}作为AnyObject!
该观察者将每0.01秒调用一次observeTime
,并将更新进度指示器。
现在在下面添加此方法:
私人功能watchTime(elapsedTime:CMTime){
让elapsedTime = CMTimeGetSeconds(elapsedTime)
如果(avPlayer.currentTime()。seconds> self.endTime){
avPlayer.pause()
btnPlay.isEnabled = true
btnPause.isEnabled =假
}
如果self.shouldUpdateProgressIndicator {
rangeSlider.updateProgressIndicator(秒:elapsedTime)
}
}
在这里,我们检查当前时间是否未达到应暂停的时间。 现在, self.endTime
等于视频的总时长。 而且,我们告诉rangeSlider
更新进度指示器的位置
运行应用程序,查看播放视频时指示器如何移动。 最后!
更新startTime和endTime
如果我们只想播放选定的范围,则需要更新startTime
和endTime
。 将这些行添加到我们之前实现的委托中:
func didChangeValue(videoRangeSlider:ABVideoRangeSlider,startTime:Float64,endTime:Float64){
self.endTime =结束时间
如果startTime!= self.startTime {
self.startTime =开始时间
让timescale = self.avPlayer.currentItem?.asset.duration.timescale
let time = CMTimeMakeWithSeconds(self.startTime,timescale!)
如果!self.isSeeking {
self.isSeeking = true
avPlayer.seek(至:时间,公差之前:kCMTimeZero,公差之后:kCMTimeZero){_在
self.isSeeking =假
}
}
}
}
在这里,每次rangeSlider移动时我们都会更新值,并寻找到startTime
寻求进度指示器
为了在视频中移动,每次拖动进度指示器时,我们都必须跟踪其位置。 将这些行添加到我们的委托方法中:
func indicatorDidChangePosition(videoRangeSlider:ABVideoRangeSlider,位置:Float64){
self.shouldUpdateProgressIndicator = false
avPlayer.pause()
btnPlay.isEnabled = true
btnPause.isEnabled =假
如果self.progressPosition!=位置{
self.progressPosition =位置
让timescale = self.avPlayer.currentItem?.asset.duration.timescale
let time = CMTimeMakeWithSeconds(self.progressPosition,timescale!)
如果!self.isSeeking {
self.isSeeking = true
avPlayer.seek(至:时间,公差之前:kCMTimeZero,公差之后:kCMTimeZero){_在
self.isSeeking =假
}
}
}
}
并将此行添加到我们按钮的playTapped
方法内:
self.shouldUpdateProgressIndicator = true
到目前为止,我们已经能够指示视频的开始和结束位置,并使用进度指示器来寻找特定的时间。
我们的控制器应如下所示:
运行项目并进行测试!
此处使用的示例项目在我们的Github中,请随时下载并使用。
在本教程的第2部分中,我们将使用startTime
和endTime
修剪视频,并将其导出为新视频!