123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- //
- // PQStuckPointMaterialDetailController.swift
- // PQSpeed
- //
- // Created by SanW on 2021/4/27.
- // Copyright © 2021 BytesFlow. All rights reserved.
- //
- import Kingfisher
- import KingfisherWebP
- import UIKit
- class PQStuckPointMaterialDetailController: PQBaseViewController {
- var materialData: PQEditVisionTrackMaterialsModel?
- // 点击的回调
- var materialDetailClickHandle: ((_ isMaterialSelected: Bool?, _ materialData: PQEditVisionTrackMaterialsModel?) -> Void)?
- var isMaterialSelected: Bool?
- var margin: CGFloat = 35 // 左右间距
- // 最大的宽度
- var maxWidth: CGFloat = cScreenWidth
- // 最大的高度
- var maxHeight: CGFloat = cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei - cDevice_iPhoneStatusBarHei
- // 预览区域宽度
- var preViewWidth: CGFloat = cScreenWidth
- // 预览区域高度
- var preViewHeight: CGFloat = cScreenHeigth - cDevice_iPhoneNavBarAndStatusBarHei - cDevice_iPhoneStatusBarHei
- lazy var preImageView: UIImageView = {
- let preImageView = UIImageView(frame: CGRect(x: (maxWidth - preViewWidth) / 2, y: cDevice_iPhoneNavBarAndStatusBarHei + (maxHeight - preViewHeight) / 2, width: preViewWidth, height: preViewHeight))
- preImageView.center.x = view.center.x
- preImageView.backgroundColor = PQBFConfig.shared.styleBackGroundColor
- preImageView.contentMode = .scaleAspectFit
- preImageView.isUserInteractionEnabled = true
- preImageView.clipsToBounds = true
- // preImageView.image = UIImage.init(named: "cut_place")
- return preImageView
- }()
- lazy var choseTitleBtn: UIButton = {
- let choseTitleBtn = UIButton(type: .custom)
- choseTitleBtn.frame = CGRect(x: cScreenWidth - cDefaultMargin * 6, y: 0, width: cDefaultMargin * 5, height: cDefaultMargin * 3)
- choseTitleBtn.setTitleColor(UIColor.white, for: .normal)
- choseTitleBtn.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .medium)
- choseTitleBtn.setTitle("取消", for: .selected)
- choseTitleBtn.setTitle("选择", for: .normal)
- choseTitleBtn.tag = 2
- choseTitleBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
- return choseTitleBtn
- }()
- lazy var choseBtn: UIButton = {
- let choseBtn = UIButton(type: .custom)
- choseBtn.frame = CGRect(x: choseTitleBtn.frame.minX - cDefaultMargin * 3, y: 0, width: cDefaultMargin * 3, height: cDefaultMargin * 3)
- choseBtn.setBackgroundImage(UIImage().BF_Image(named: "videomk_chose_nomal"), for: .normal)
- choseBtn.setTitleColor(UIColor.white, for: .normal)
- choseBtn.titleLabel?.font = UIFont.systemFont(ofSize: 12)
- choseBtn.tag = 1
- choseBtn.addCorner(corner: 15)
- choseBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
- return choseBtn
- }()
- lazy var changeModeBtn: UIButton = {
- let changeModeBtn = UIButton(type: .custom)
- changeModeBtn.setImage(UIImage().BF_Image(named: "videomk_changeMode"), for: .normal)
- changeModeBtn.frame = CGRect(x: 15, y: preImageView.frame.height - cDefaultMargin * 4 - 15, width: cDefaultMargin * 4, height: cDefaultMargin * 4)
- changeModeBtn.tag = 3
- changeModeBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
- return changeModeBtn
- }()
- lazy var gifRemindLab: UILabel = {
- let gifRemindLab = UILabel(frame: CGRect(x: (preImageView.frame.width - cDefaultMargin * 4) / 2, y: preImageView.frame.height - cDefaultMargin * 3 - 15, width: cDefaultMargin * 4, height: cDefaultMargin * 3))
- gifRemindLab.textAlignment = .center
- gifRemindLab.font = UIFont.systemFont(ofSize: 18)
- gifRemindLab.textColor = UIColor.white
- gifRemindLab.text = "GIF"
- return gifRemindLab
- }()
- lazy var playBtn: UIButton = {
- let playBtn = UIButton(type: .custom)
- playBtn.frame = CGRect(x: (preImageView.frame.width - cDefaultMargin * 5) / 2, y: (preImageView.frame.height - cDefaultMargin * 5) / 2, width: cDefaultMargin * 5, height: cDefaultMargin * 5)
- playBtn.setImage(UIImage().BF_Image(named: "icon_video_play"), for: .normal)
- playBtn.isUserInteractionEnabled = false
- playBtn.isHidden = true
- // playBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
- return playBtn
- }()
- lazy var avPlayer: AVPlayer = {
- let avPlayer = AVPlayer()
- NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: avPlayer.currentItem, queue: .main) { [weak self] notify in
- BFLog(message: "AVPlayerItemDidPlayToEndTime = \(notify)")
- avPlayer.seek(to: CMTime(value: CMTimeValue((self?.materialData?.model_in ?? 0) * playerTimescale), timescale: CMTimeScale(playerTimescale)))
- self?.playBtn.isHidden = false
- }
- NotificationCenter.default.addObserver(forName: .AVPlayerItemNewErrorLogEntry, object: avPlayer.currentItem, queue: .main) { notify in
- BFLog(message: "AVPlayerItemNewErrorLogEntry = \(notify)")
- }
- NotificationCenter.default.addObserver(forName: .AVPlayerItemFailedToPlayToEndTime, object: avPlayer.currentItem, queue: .main) { notify in
- BFLog(message: "AVPlayerItemFailedToPlayToEndTime = \(notify)")
- }
- NotificationCenter.default.addObserver(forName: .AVPlayerItemPlaybackStalled, object: avPlayer.currentItem, queue: .main) { notify in
- BFLog(message: "AVPlayerItemPlaybackStalled = \(notify)")
- }
- avPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: CMTimeScale(playerTimescale)), queue: .main) { [weak self] cmTime in
- // let progress = CMTimeGetSeconds(avPlayer.currentItem?.currentTime() ?? CMTime.zero) / CMTimeGetSeconds(avPlayer.currentItem?.duration ?? CMTime.zero)
- let delta = CMTimeGetSeconds(cmTime)
- let start = CGFloat(delta - (self?.materialData?.model_in ?? 0.0))
- var endTime: Float64 = self?.materialData?.out ?? 0
- if endTime <= 0 {
- endTime = self?.materialData?.duration ?? 0
- }
- let total = CGFloat(endTime - (self?.materialData?.model_in ?? 0.0))
- let progress = start / total
- if progress >= 1 {
- self?.playBtn.isHidden = false
- }
- BFLog(message: "progress = \(progress)")
- }
- return avPlayer
- }()
- lazy var playerLayer: AVPlayerLayer = {
- let playerLayer = AVPlayerLayer(player: avPlayer)
- playerLayer.frame = CGRect(origin: CGPoint.zero, size: preImageView.frame.size)
- return playerLayer
- }()
- override func viewDidLoad() {
- super.viewDidLoad()
- leftButton(image: "icon_detail_back", tintColor: PQBFConfig.shared.styleTitleColor)
- navHeadImageView?.backgroundColor = UIColor.clear
- let width = CGFloat(materialData?.width ?? Float(preViewWidth))
- let height = CGFloat(materialData?.height ?? Float(preViewHeight))
- if width >= height {
- preViewWidth = maxWidth
- preViewHeight = preViewWidth * height / width
- } else {
- preViewHeight = maxHeight
- preViewWidth = preViewHeight * width / height
- }
- lineView?.removeFromSuperview()
- view.addSubview(preImageView)
- // preImageView.addSubview(changeModeBtn)
- if materialData?.type == StickerType.GIF.rawValue {
- preImageView.addSubview(gifRemindLab)
- setImageToPreImageView()
- } else if materialData?.type == StickerType.IMAGE.rawValue {
- setImageToPreImageView()
- } else if materialData?.type == StickerType.VIDEO.rawValue {
- preImageView.addSubview(playBtn)
- preImageView.layer.insertSublayer(playerLayer, at: 0)
- let ges = UITapGestureRecognizer(target: self, action: #selector(playPreVideo))
- preImageView.addGestureRecognizer(ges)
- // 设置播放内容
- setPlayerItem()
- }
- // updateSelectedState()
- isMaterialSelected = materialData?.isSelected
- }
- deinit {
- if materialData?.type == StickerType.VIDEO.rawValue {
- avPlayer.replaceCurrentItem(with: nil)
- PQNotification.removeObserver(self)
- }
- }
- /// 设置图片
- /// - Returns: <#description#>
- func setImageToPreImageView() {
- if materialData?.asset != nil {
- if materialData?.originalData == nil {
- PQPHAssetVideoParaseUtil.requestAssetOringinImage(asset: (materialData?.asset)!) { [weak self] _, data, image, _ in
- if image == nil {
- BFLog(message: "图片数据为空!!!!!")
- }
- // 1,图片,gif的原文件数据,和视频的封面
- var newImage: UIImage?
- if image != nil {
- newImage = UIImage.nx_fixOrientation(image, isFront: false).nx_scaleWithMaxLength(maxLength: 1920)
- }
- self?.materialData?.coverImageUI = newImage
- self?.materialData?.originalData = data
- // if isGIF {
- // self?.materialData?.type = StickerType.GIF.rawValue
- // if self?.gifRemindLab.superview == nil {
- // self?.preImageView.addSubview(self!.gifRemindLab)
- // }
- // self?.preImageView.displayGIF(data: data)
- // } else {
- self?.preImageView.image = newImage
- // }
- }
- } else {
- setNomarlImageToPreImageView()
- }
- } else {
- setNomarlImageToPreImageView()
- }
- }
- func setNomarlImageToPreImageView() {
- if materialData?.type == StickerType.VIDEO.rawValue {
- return
- }
- if materialData?.type == StickerType.GIF.rawValue && materialData?.originalData != nil {
- preImageView.displayGIF(data: materialData?.originalData)
- } else if preImageView.image != nil {
- preImageView.image = preImageView.image
- } else if preImageView.image == nil && materialData?.coverImageUI != nil {
- if materialData?.type == StickerType.GIF.rawValue {
- preImageView.displayGIF(data: kf_imageCacheData(originUrl: materialData?.netResCoverImageURL ?? ""))
- } else {
- preImageView.image = materialData?.coverImageUI
- }
- } else if materialData?.coverImageUI != nil {
- preImageView.image = materialData?.coverImageUI
- } else if materialData?.locationPath.count ?? 0 > 0 {
- if materialData?.type == StickerType.GIF.rawValue {
- let fileData: Data = try! Data(contentsOf: URL(fileURLWithPath: documensDirectory + (materialData?.locationPath)!))
- materialData?.originalData = fileData
- preImageView.displayGIF(data: materialData?.originalData)
- } else {
- var coverImage = UIImage(contentsOfFile: documensDirectory + (materialData?.locationPath)!)
- if coverImage == nil {
- // 有可能是 WEBP
- let fileData: Data = try! Data(contentsOf: URL(fileURLWithPath: documensDirectory + (materialData?.locationPath)!))
- if fileData.count != 0, fileData.isWebPFormat {
- coverImage = WebPProcessor.default.process(item: ImageProcessItem.data(fileData), options: KingfisherParsedOptionsInfo([.onlyLoadFirstFrame, .scaleFactor(1)]))
- }
- }
- preImageView.image = coverImage
- materialData?.coverImageUI = coverImage
- }
- } else if (materialData?.netResCoverImageURL != nil && ((materialData?.netResCoverImageURL?.count ?? 0) > 0)) || (materialData?.materialUrl != nil && ((materialData?.materialUrl.count ?? 0) > 0)) {
- var url = materialData?.materialUrl
- if url == nil || (url?.count ?? 0) <= 0 {
- url = materialData?.netResCoverImageURL
- }
- ImageDownloader.default.downloadImage(with: URL(string: url ?? "")!, options: nil) { [weak self] result in
- switch result {
- case let .success(imageLoading):
- self?.materialData?.originalData = imageLoading.originalData
- self?.materialData?.coverImageUI = imageLoading.image
- if self?.materialData?.type == StickerType.GIF.rawValue {
- self?.preImageView.displayGIF(data: imageLoading.originalData)
- } else {
- self?.preImageView.image = imageLoading.image
- }
- let imageOrientation = UIImage.nx_fixOrientation(imageLoading.image, isFront: false).nx_scaleWithMaxLength(maxLength: 1024)
- // 下载器的原地址
- let diskCachePath = ImageCache.default.cachePath(forKey: url!)
- let imageCacheName = url!.md5
- let imageCachePath = downloadImagesDirectory + imageCacheName
- if !directoryIsExists(dicPath: downloadImagesDirectory) {
- BFLog(message: "文件夹不存在 \(downloadImagesDirectory)")
- createDirectory(path: downloadImagesDirectory)
- }
- if self?.materialData?.type != StickerType.GIF.rawValue {
- try! imageOrientation.pngData()?.write(to: URL(fileURLWithPath: imageCachePath))
- } else {
- try! imageLoading.originalData.write(to: URL(fileURLWithPath: imageCachePath))
- }
- if !FileManager.default.fileExists(atPath: imageCachePath) {
- try! FileManager.default.copyItem(atPath: diskCachePath, toPath: downloadImagesDirectory + imageCacheName)
- }
- if self?.materialData?.type != StickerType.VIDEO.rawValue {
- self?.materialData?.locationPath = imageCachePath.replacingOccurrences(of: documensDirectory, with: "")
- }
- case let .failure(error):
- BFLog(message: "下载图片失败:\(error.localizedDescription)")
- }
- }
- }
- }
- /// 预览视频
- @objc func playPreVideo() {
- playBtn.isHidden = !playBtn.isHidden
- if avPlayer.currentItem == nil {
- setPlayerItem()
- }
- if playBtn.isHidden {
- if playerLayer.superlayer == nil {
- preImageView.layer.insertSublayer(playerLayer, at: 0)
- }
- avPlayer.play()
- } else {
- avPlayer.pause()
- }
- }
- /// 设置播放item
- /// - Returns: <#description#>
- func setPlayerItem() {
- if materialData?.locationPath.count ?? 0 > 0 {
- if materialData?.locationPath.contains("mobile/Media/DCIM") ?? false {
- addPlayItem(playerItem: AVPlayerItem(url: URL(fileURLWithPath: materialData!.locationPath)))
- } else {
- addPlayItem(playerItem: AVPlayerItem(url: URL(fileURLWithPath: documensDirectory + materialData!.locationPath)))
- }
- } else if materialData?.locationPath.count == 0 && materialData?.asset != nil {
- PQLoadingHUB.shared.showHUB()
- PQPHAssetVideoParaseUtil.parasToAVPlayerItem(phAsset: (materialData?.asset)!) { [weak self] playerItem, _, _ in
- PQLoadingHUB.shared.dismissHUB()
- // self?.materialData?.locationPath = (playerItem?.asset as? AVURLAsset)?.url.absoluteString.replacingOccurrences(of: "file:///", with: "") ?? ""
- self?.addPlayItem(playerItem: playerItem)
- }
- } else if isValidURL(url: materialData?.netResUrl) {
- addPlayItem(playerItem: AVPlayerItem(url: URL(string: materialData?.netResUrl ?? "")!))
- }
- }
- /// 添加播放
- /// - Parameter playerItem: <#playerItem description#>
- func addPlayItem(playerItem: AVPlayerItem?) {
- avPlayer.replaceCurrentItem(with: playerItem)
- avPlayer.play()
- let startTime = materialData?.model_in ?? 0
- var endTime = materialData?.out ?? 0
- if endTime <= 0 {
- endTime = Float64(materialData?.duration ?? 0.0)
- }
- avPlayer.seek(to: CMTime(value: CMTimeValue(startTime * playerTimescale), timescale: CMTimeScale(playerTimescale)))
- avPlayer.currentItem?.forwardPlaybackEndTime = CMTime(value: CMTimeValue(endTime * playerTimescale), timescale: CMTimeScale(playerTimescale))
- }
- /// 按钮点击事件
- /// - Parameter sender: <#sender description#>
- @objc func btnClick(sender: UIButton) {
- switch sender.tag {
- case 1, 2:
- let ratio = (materialData?.width ?? 0) / (materialData?.height ?? 1)
- if ratio < 0.4 || ratio > 4.2 {
- cShowHUB(superView: nil, msg: "暂不支持该比例的素材")
- return
- }
- materialData?.isSelected = !(materialData?.isSelected ?? false)
- // updateSelectedState()
- default:
- break
- }
- }
- /// 更新选中状态
- func updateSelectedState() {
- if materialData?.isSelected ?? false {
- choseBtn.setBackgroundImage(nil, for: .normal)
- choseBtn.backgroundColor = UIColor.hexColor(hexadecimal: "#EE0051")
- if materialData?.selectedIndex == 0 {
- choseBtn.setTitle("1", for: .normal)
- } else {
- choseBtn.setTitle("\(materialData?.selectedIndex ?? 1)", for: .normal)
- }
- choseTitleBtn.isSelected = true
- } else {
- choseBtn.setBackgroundImage(UIImage().BF_Image(named: "videomk_chose_nomal"), for: .normal)
- choseBtn.backgroundColor = UIColor.clear
- choseBtn.setTitle(nil, for: .normal)
- choseTitleBtn.isSelected = false
- }
- if materialData?.originalData == nil {
- materialData?.originalData = kf_imageCacheData(originUrl: materialData?.netResCoverImageURL ?? "")
- if materialData?.originalData != nil {
- if materialData?.type == StickerType.GIF.rawValue && materialData?.originalData != nil && (materialData?.duration ?? 0.0) <= 0 {
- PQPHAssetVideoParaseUtil.parasGIFImage(data: (materialData?.originalData)!) { [weak self] _, _, duration in
- self?.materialData?.duration = duration ?? 0.0
- }
- }
- }
- }
- }
- override func backBtnClick() {
- if materialDetailClickHandle != nil {
- materialDetailClickHandle!(isMaterialSelected, materialData)
- }
- super.backBtnClick()
- }
- }
|