使用来自 github 链接的 ASVideoPlayer 库的自定义 VideoPlayer:https ://github.com/Asbat/ASVideoPlayer
// --------------------------------------------------------
// MARK:- variables
// --------------------------------------------------------
var videoPlayer = ASVideoPlayerController()
var videoData : [VideoModel] = []
var allVideoData : [AllVideoModel] = []
var cellHeights = [IndexPath: CGFloat]()
let loadingCellTableViewCellCellIdentifier = "LoadingCellTableViewCell"
var pauseIndexPath : Int = 0
var pageNumber = 1
var index = 0
var id = ""
var titleVideo = ""
var isUpdate = false
var myVideo : [MyVideo] = []
var imgs = [UIImage]()
var activityViewController : UIActivityViewController!
private var activityIndicator = NVActivityIndicatorView(frame: CGRect(x: 5, y: 5, width: 5, height: 5), type: .circleStrokeSpin, color: .systemBlue, padding: 5)
private let refreshControl = UIRefreshControl()
// --------------------------------------------------------
// MARK:- Outlets
// --------------------------------------------------------
@IBOutlet private var tableVideo: UITableView!
@IBOutlet private var _btnBack: UIButton!
@IBOutlet var _btnide: UIButton!
// ---------------------------------------------------------
// MARK:- Lifecycle
// ---------------------------------------------------------
override func viewDidLoad() {
super.viewDidLoad()
self._btnide.isHidden = true
tableVideo.rowHeight = UITableView.automaticDimension
tableVideo.separatorStyle = .none
tableVideo.delegate = self
tableVideo.dataSource = self
tableVideo.register(UINib(nibName: "VideoPlayerTableCell", bundle: nil), forCellReuseIdentifier: "VideoPlayerTableCell")
let cellNib = UINib(nibName:loadingCellTableViewCellCellIdentifier, bundle: nil)
tableVideo.register(cellNib, forCellReuseIdentifier: loadingCellTableViewCellCellIdentifier)
navigationController?.navigationBar.isHidden = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
ASVideoPlayerController.sharedVideoPlayer.pausePlayeVideosFor(tableView: tableVideo)
tableVideo.scrollToRow(at: IndexPath(row: index, section: 0), at: .none, animated: true)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
tableVideo.scrollToRow(at: IndexPath(row: pauseIndexPath, section: 0), at: .none, animated: true)
puasVideoWhenPushVC(index: pauseIndexPath)
NotificationCenter.default.removeObserver(self)
if tableVideo.isHidden == true {
}
}
@IBAction func _onTapBackBtnAction(_ sender: UIButton) {
tableVideo.scrollToRow(at: IndexPath(row: pauseIndexPath, section: 0), at: .none, animated: true)
self.puasVideoWhenPushVC(index: pauseIndexPath)
navigationController?.popViewController(animated: true)
navigationController?.navigationBar.isHidden = false
}
// ---------------------------------------------------------------------
// MARK:- TableView Delegate & DataSource
// ---------------------------------------------------------------------
extension VideoPlayerVC :
UITableViewDelegate,UITableViewDataSource,UIScrollViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isUpdate{
return videoData.count
}else{
return allVideoData.count
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if tableView == tableVideo {
return view.bounds.height
}else {
return UITableView.automaticDimension
}
}
func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if tableView == tableVideo {
if let videoCell = cell as? ASAutoPlayVideoLayerContainer, let _ = videoCell.videoURL {
ASVideoPlayerController.sharedVideoPlayer.removeLayerFor(cell: videoCell)
}
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableVideo.dequeueReusableCell(withIdentifier: "VideoPlayerTableCell", for: indexPath) as! VideoPlayerTableCell
if isUpdate{
self.id = videoData[indexPath.row].id ?? ""
cell.configureCell(videoUrl: videoData[indexPath.row].videoLink )
}else{
self.id = allVideoData[indexPath.row].id ?? ""
cell.configureCell(videoUrl: allVideoData[indexPath.row].videoLink)
}
cell.btnPlayPause.isSelected = false
cell.btnPlayPause.tag = indexPath.row
cell.btnPlayPause.addTarget(self, action: #selector(didTapPlayPauseButton(_:)), for: .touchUpInside)
cell.btnPlayPause.setImage(UIImage(named: ""), for: .normal)
cell.btnPlayPause.setImage(UIImage(named: "btn_play_video"), for: .selected)
cell.btnUseNow.tag = indexPath.row
cell.btnUseNow.addTarget(self, action: #selector(btnUseNowTapped(sender:)), for: .touchUpInside)
cell.btnShare.tag = indexPath.row
cell.btnShare.addTarget(self, action: #selector(btnShareTapped(sender:)), for: .touchUpInside)
cell.btnSave.tag = indexPath.row
cell.btnSave.addTarget(self, action: #selector(btnSaveTapped(sender:)), for: .touchUpInside)
pauseIndexPath = indexPath.row
return cell
}
@objc func btnUseNowTapped(sender: UIButton){
self._btnide.isHidden = false
self.pausePlayeVideos()
let editVC = EditVideoVC()
var fileName : String = kEmptyString
if self.isUpdate{
editVC.videoString = self.videoData[sender.tag].videoLink ?? kEmptyString
editVC.id = self.videoData[sender.tag].id ?? kEmptyString
editVC.titleVideo = self.videoData[sender.tag].title ?? kEmptyString
fileName = self.videoData[sender.tag].videoZip ?? kEmptyString
guard !FileManager.isExist(id: self.videoData[sender.tag].id ?? kEmptyString) else{
print("File Downloaded")
self.puasVideoWhenPushVC(index: sender.tag)
self.navigationController?.pushViewController(editVC, animated: true)
return }
FileManager.download(id: self.videoData[sender.tag].id ?? kEmptyString, url: fileName) { (url) in
guard url != nil else {
print("not download")
return
}
self.puasVideoWhenPushVC(index: sender.tag)
self.navigationController?.pushViewController(editVC, animated: true)
}
}
else{
editVC.videoString = self.allVideoData[sender.tag].videoLink ?? kEmptyString
editVC.id = self.allVideoData[sender.tag].id ?? kEmptyString
editVC.titleVideo = self.allVideoData[sender.tag].title ?? kEmptyString
fileName = self.allVideoData[sender.tag].videoZip ?? kEmptyString
guard !FileManager.isExist(id: self.allVideoData[sender.tag].id ?? kEmptyString) else{
print("File Downloaded")
self.puasVideoWhenPushVC(index: sender.tag)
self.navigationController?.pushViewController(editVC, animated: true)
return }
FileManager.download(id: self.allVideoData[sender.tag].id ?? kEmptyString, url: fileName) { (url) in
guard url != nil else {
print("not download")
return
}
self.puasVideoWhenPushVC(index: sender.tag)
self.navigationController?.pushViewController(editVC, animated: true)
}
}
}
@objc func btnShareTapped(sender: UIButton){
if self.isUpdate{
let video = ["\(String(describing: self.videoData[sender.tag].videoLink))"]
self.activityViewController = UIActivityViewController(activityItems: video, applicationActivities: nil)
self.activityViewController.setValue("Video Share", forKey: "subject")
self.activityViewController.popoverPresentationController?.sourceView = self.view
self.activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToTwitter, UIActivity.ActivityType.addToReadingList, UIActivity.ActivityType.assignToContact,UIActivity.ActivityType.copyToPasteboard,UIActivity.ActivityType.mail,UIActivity.ActivityType.markupAsPDF,UIActivity.ActivityType.message,UIActivity.ActivityType.postToFacebook,UIActivity.ActivityType.postToFlickr,UIActivity.ActivityType.postToTencentWeibo,UIActivity.ActivityType.postToVimeo,UIActivity.ActivityType.postToWeibo,UIActivity.ActivityType.saveToCameraRoll]
self.present(self.activityViewController, animated: true, completion: nil)
}
else{
let categoryVideo = ["\(String(describing: self.allVideoData[sender.tag].videoLink))"]
self.activityViewController = UIActivityViewController(activityItems: categoryVideo, applicationActivities: nil)
self.activityViewController.setValue("Video Share", forKey: "subject")
self.activityViewController.popoverPresentationController?.sourceView = self.view
self.activityViewController.excludedActivityTypes = [ UIActivity.ActivityType.airDrop, UIActivity.ActivityType.postToTwitter]
self.present(self.activityViewController, animated: true, completion: nil)
}
}
@objc func btnSaveTapped(sender: UIButton){
if self.isUpdate{
self.downloadVideos(video: self.videoData[sender.tag].videoLink ?? kEmptyString)
}else{
self.downloadVideos(video: self.allVideoData[sender.tag].videoLink ?? kEmptyString)
}
}
private func downloadVideos(video : String){
Alamofire.request(video).downloadProgress(closure : { (progress) in
}).responseData{ (response) in
///# Create folder in documetn directory #///
if let data = response.result.value{
let path = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent("Videos")
if !FileManager.default.fileExists(atPath: path) {
try! FileManager.default.createDirectory(atPath: path, withIntermediateDirectories: true, attributes: nil)
}
let fileURL = URL(fileURLWithPath:path).appendingPathComponent("\(self.id)/\(self.titleVideo)/output.mp4")
print(fileURL)
do{
try data.write(to: fileURL, options: .atomic)
}catch{
print("could not download")
}
print(fileURL)
}
}
}
// ----------------------------------------------------------------------
// MARK:- Scrollview Method
// ----------------------------------------------------------------------
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
if scrollView == tableVideo {
pauseIndexPath = Int(scrollView.contentOffset.y / scrollView.frame.size.height)
pausePlayeVideos()
}
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if scrollView == tableVideo {
if !decelerate {
pausePlayeVideos()
}
}
}
// ----------------------------------------------------------------------
// MARK:- Function Pause & Play Button
// ----------------------------------------------------------------------
func puasVideoWhenPushVC (index : NSInteger) {
if isUpdate{
guard let cell = tableVideo.cellForRow(at: IndexPath(row: index, section: 0)) as? VideoPlayerTableCell else { return }
ASVideoPlayerController.sharedVideoPlayer.pauseVideo(forLayer: cell.videoLayer, url: videoData[index].videoLink ?? "")
}
else{
guard let cell = tableVideo.cellForRow(at: IndexPath(row: index, section: 0)) as? VideoPlayerTableCell else { return }
ASVideoPlayerController.sharedVideoPlayer.pauseVideo(forLayer: cell.videoLayer, url: allVideoData[index].videoLink ?? "")
}
}
@objc func pausePlayeVideos(){
ASVideoPlayerController.sharedVideoPlayer.pausePlayeVideosFor(tableView: tableVideo)
}
@objc func appEnteredFromBackground() {
ASVideoPlayerController.sharedVideoPlayer.pausePlayeVideosFor(tableView: tableVideo, appEnteredFromBackground: true)
}
@objc func didTapPlayPauseButton(_ sender: UIButton) {
guard let cell = tableVideo.cellForRow(at: IndexPath(row: sender.tag, section: 0)) as? VideoPlayerTableCell else { return }
if sender.isSelected {
if isUpdate{
ASVideoPlayerController.sharedVideoPlayer.playVideo(withLayer: cell.videoLayer, url: videoData[sender.tag].videoLink ?? "")
}else{
ASVideoPlayerController.sharedVideoPlayer.playVideo(withLayer: cell.videoLayer, url: allVideoData[sender.tag].videoLink ?? "")
}
} else {
if isUpdate{
ASVideoPlayerController.sharedVideoPlayer.pauseVideo(forLayer: cell.videoLayer, url: videoData[sender.tag].videoLink ?? "")
}else{
ASVideoPlayerController.sharedVideoPlayer.pauseVideo(forLayer: cell.videoLayer, url: allVideoData[sender.tag].videoLink ?? "")
}
}
sender.isSelected = !sender.isSelected
}