[教程]如何使用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

如果我们只想播放选定的范围,则需要更新startTimeendTime 。 将这些行添加到我们之前实现的委托中:

  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部分中,我们将使用startTimeendTime修剪视频,并将其导出为新视频!

Interesting Posts