jsonwang 3 лет назад
Родитель
Сommit
1329b9a5bb

+ 282 - 0
BFFramework/Classes/Stuckpoint/Controller/PQEditMusicSearchController.swift

@@ -0,0 +1,282 @@
+//
+//  PQEditMusicSearchController.swift
+//  BFFramework
+//
+//  Created by ak on 2021/8/7.
+//
+
+import Foundation
+ 
+class PQEditMusicSearchController: PQBaseViewController {
+    // 当前播放的音乐
+    var currentPlayData: PQVoiceModel?
+    // 当前播放的视频
+    var playerItem: AVPlayerItem?
+    // 左边距离
+    let leftMargin: CGFloat = 47
+    // 搜索拦高度
+    let searchTFH: CGFloat = 37
+    // 热搜数据
+    var hotList: [Any] = Array<Any>.init()
+    lazy var avPlayer: AVPlayer = {
+        let avPlayer = AVPlayer()
+        PQNotification.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: avPlayer.currentItem, queue: .main) { [weak self] notify in
+            BFLog(message: "AVPlayerItemDidPlayToEndTime = \(notify)")
+            avPlayer.seek(to: CMTime(value: CMTimeValue((self?.currentPlayData?.startTime ?? 0) * 1000), timescale: CMTimeScale(playerTimescale)))
+//            avPlayer.play()
+            self?.playStuckPointMusic(itemData: nil)
+        }
+        PQNotification.addObserver(forName: .AVPlayerItemNewErrorLogEntry, object: avPlayer.currentItem, queue: .main) { notify in
+            BFLog(message: "AVPlayerItemNewErrorLogEntry = \(notify)")
+        }
+        PQNotification.addObserver(forName: .AVPlayerItemFailedToPlayToEndTime, object: avPlayer.currentItem, queue: .main) { notify in
+            BFLog(message: "AVPlayerItemFailedToPlayToEndTime = \(notify)")
+        }
+        PQNotification.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
+            BFLog(message: "addPeriodicTimeObserver = \(cmTime)")
+        }
+        return avPlayer
+    }()
+    // 输入框清空按钮
+    lazy var clearBtn: UIButton = {
+        let clearBtn = UIButton(type: .custom)
+        clearBtn.setImage(UIImage().BF_Image(named: "icon_search_delete"), for: .normal)
+        clearBtn.frame = CGRect(x: 0, y: 0, width: 28, height: 32)
+        clearBtn.tag = 1
+        clearBtn.addTarget(self, action: #selector(btnClick(sender:)), for: .touchUpInside)
+        clearBtn.isHidden = true
+        return clearBtn
+    }()
+    // 搜索框
+    lazy var searchTF: UITextField = {
+        let searchTF = UITextField(frame: CGRect(x: leftMargin, y: cDevice_iPhoneStatusBarHei, width: cScreenWidth - leftMargin * 2, height: searchTFH))
+        searchTF.font = UIFont.systemFont(ofSize: 17)
+        searchTF.backgroundColor = PQBFConfig.shared.otherTintColor
+        searchTF.attributedPlaceholder = NSAttributedString(string: "搜索歌曲名称/歌手", attributes: [.foregroundColor: UIColor.hexColor(hexadecimal: "#BDBDBD"), .font: UIFont.systemFont(ofSize: 14)])
+        searchTF.textColor = PQBFConfig.shared.styleTitleColor
+        searchTF.addCorner(corner: searchTFH / 2)
+
+        searchTF.leftViewMode = .always
+        let leftView = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 32))
+        let imageView = UIImageView(image: UIImage().BF_Image(named: "icon_search_s"))
+        imageView.frame = CGRect(x: 15, y: 8, width: 16, height: 16)
+        leftView.addSubview(imageView)
+        searchTF.leftView = leftView
+        searchTF.delegate = self
+
+        searchTF.rightViewMode = .always
+        let rightView = UIView(frame: CGRect(x: 0, y: 0, width: 40, height: 32))
+        rightView.addSubview(clearBtn)
+        searchTF.rightView = rightView
+        searchTF.delegate = self
+        searchTF.returnKeyType = .search
+        searchTF.addTarget(self, action: #selector(editingChanged), for: .editingChanged)
+        return searchTF
+    }()
+
+    /// 搜索控制器
+    lazy var searchController: PQStuckPointMusicSearchController = {
+        let searchController = PQStuckPointMusicSearchController()
+        searchController.cellHight = cDefaultMargin * 8
+ 
+        searchController.updateViewFrame(newFrame: CGRect(x: 0, y: cDevice_iPhoneNavBarAndStatusBarHei + cDefaultMargin * 2, width: view.frame.width, height: view.frame.height - (cDevice_iPhoneNavBarAndStatusBarHei + cDefaultMargin * 2)))
+        searchController.didSelectedHandle = { [weak self] isTagsClick, _, _, itemData in
+            if !isTagsClick {
+                self?.view.endEditing(true)
+                if !(itemData is PQEmptyModel) {
+                    self?.playStuckPointMusic(itemData: itemData as? PQVoiceModel)
+                }
+            }
+        }
+        searchController.btnClickHandle = { [weak self] _, bgmData in
+            // 使用音乐
+//            self?.userstuckPointMusic(musicData: bgmData as? PQVoiceModel)
+        }
+        searchController.scroDidScroHandle = { [weak self] in
+            self?.view.endEditing(true)
+        }
+        searchController.contentType = .serach
+        return searchController
+    }()
+    override func viewDidLoad() {
+        super.viewDidLoad()
+        view.addSubview(searchTF)
+        
+        addChild(searchController)
+        view.addSubview(searchController.view)
+        
+        leftButton(image: "upload_delete", tintColor: PQBFConfig.shared.styleTitleColor)
+        PQStuckPointViewModel.stuckPointMusicPageList(tagId: 999, parentTagId: 0, pageNum: 1, videoCount: 0, imageCount: 0, totalDuration: 0) { [weak self] musicInfo, _ in
+
+            if musicInfo.count > 0 {
+                self?.searchController.hotList = musicInfo
+            }
+       
+        }
+    }
+    
+    
+    /// 按钮点击事件
+    /// - Parameter sender: <#sender description#>
+    /// - Returns: <#description#>
+    @objc func btnClick(sender: UIButton) {
+        switch sender.tag {
+        case 1: // 清除
+            searchTF.text = nil
+//            emptyRemindView.isHidden = true
+            clearBtn.isHidden = true
+        default:
+            break
+        }
+    }
+    
+    /// 播放音乐
+    /// - Parameter itemData: <#itemData description#>
+    func playStuckPointMusic(itemData: PQVoiceModel?, isClearCurrentMusic: Bool = false) {
+        if itemData != nil, currentPlayData != itemData {
+            if !isValidURL(url: itemData?.musicPath ?? "") {
+                cShowHUB(superView: nil, msg: "本歌曲暂无伴奏版本哦~")
+                return
+            }
+            avPlayer.pause()
+            playerItem?.removeObserver(self, forKeyPath: "status")
+            playerItem?.removeObserver(self, forKeyPath: "error")
+            playerItem = AVPlayerItem(url: URL(string: itemData?.musicPath ?? "")!)
+            if (itemData?.endTime ?? 0) > 0, (itemData?.endTime ?? 0) > (itemData?.startTime ?? 0) {
+                playerItem?.forwardPlaybackEndTime = CMTime(value: CMTimeValue((itemData?.endTime ?? 0) * playerTimescale), timescale: CMTimeScale(playerTimescale))
+            }
+            avPlayer.replaceCurrentItem(with: playerItem)
+            playerItem?.addObserver(self, forKeyPath: "status", options: .new, context: nil)
+            playerItem?.addObserver(self, forKeyPath: "error", options: .new, context: nil)
+            avPlayer.seek(to: CMTime(value: CMTimeValue((itemData?.startTime ?? 0) * playerTimescale), timescale: CMTimeScale(playerTimescale)))
+            avPlayer.play()
+//            let player = TXVodPlayer()
+//            let config = TXVodPlayConfig()
+//            config.cacheFolderPath = videoCacheDirectory
+//            config.maxCacheItems = 0
+//            player.config = config
+            ////            player.vodDelegate = self
+//            player.setRenderMode(.RENDER_MODE_FILL_EDGE)
+//            player.startPlay("https://clipres.yishihui.com/longvideo/material/voice/prod/20210512/MUSIC_QQ_000T1Ws32MWrUj")
+            currentPlayData = itemData
+        } else if itemData != nil, avPlayer.rate == 0.0 {
+            avPlayer.play()
+        } else {
+            avPlayer.pause()
+ 
+        }
+        if isClearCurrentMusic {
+            avPlayer.pause()
+            currentPlayData = nil
+        }
+    }
+}
+
+/// 音乐搜索相关
+extension PQEditMusicSearchController: UITextFieldDelegate {
+    /// 点击输入框
+    @objc func editingChanged() {
+        if searchTF.text != nil, (searchTF.text?.count ?? 0) > 0, searchTF.markedTextRange == nil {
+            if searchTF.text?.isSpace ?? false {
+                return
+            }
+//            loadSearchData()
+            clearBtn.isHidden = false
+        }
+    }
+
+    /// 搜索
+    @objc func loadSearchData() {
+        if searchTF.text != nil, (searchTF.text?.count ?? 0) > 0, searchTF.text?.isSpace ?? false {
+            cShowHUB(superView: nil, msg: "搜索内容不能为空")
+            return
+        }
+        if searchTF.text != nil, (searchTF.text?.count ?? 0) > 0 {
+            BFLog(message: "背景音乐--开始搜索背景音乐-1")
+            searchController.loadSearchData(keyword: searchTF.text)
+        }
+    }
+
+    /// 添加键盘监听
+    /// - Returns: <#description#>
+    func addKeyboardObserver() {
+        // 监听键盘的显示和隐藏
+        PQNotification.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
+        PQNotification.addObserver(self, selector: #selector(keyboardWillHidden), name: UIResponder.keyboardWillHideNotification, object: nil)
+    }
+
+    /// 键盘显示
+    /// - Parameter notification: <#notification description#>
+    @objc func keyboardWillShow(notification: Notification) {
+        let duration: TimeInterval = TimeInterval("\(notification.userInfo?["UIKeyboardAnimationDurationUserInfoKey"] ?? "1")") ?? 1
+        UIView.animate(withDuration: duration) { [weak self] in
+            self?.navTitleLabel?.alpha = 0
+            self?.searchTF.frame = CGRect(x: cDefaultMargin * 5, y: (cDevice_iPhoneNavBarHei - (self?.searchTFH ?? 37.0)) / 2 + cDevice_iPhoneStatusBarHei, width: cScreenWidth - cDefaultMargin * 7, height: self?.searchTFH ?? 37.0)
+        } completion: { _ in
+        }
+        searchController.view.isHidden = false
+        hotList.forEach { item in
+            if item is PQVoiceModel {
+                (item as? PQVoiceModel)?.isSelected = false
+                (item as? PQVoiceModel)?.isPlaying = false
+            }
+        }
+
+        searchController.hotList = hotList
+        playStuckPointMusic(itemData: nil)
+    
+    }
+
+    /// 键盘将要隐藏
+    @objc func keyboardWillHidden() {}
+
+    /// 隐藏搜索界面
+    /// - Returns: <#description#>
+    func hiddenSearchController() {
+        view.endEditing(true)
+        UIView.animate(withDuration: 0.3) { [weak self] in
+            self?.navTitleLabel?.alpha = 1
+            self?.searchTF.frame = CGRect(x: self?.leftMargin ?? 0, y: cDevice_iPhoneNavBarAndStatusBarHei, width: cScreenWidth - (self?.leftMargin ?? 0) * 2, height: self?.searchTFH ?? 0)
+        } completion: { _ in
+        }
+        clearBtn.isHidden = true
+        searchController.view.isHidden = true
+        playStuckPointMusic(itemData: nil)
+    }
+
+    override func touchesBegan(_: Set<UITouch>, with _: UIEvent?) {
+        view.endEditing(true)
+    }
+
+    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
+        loadSearchData()
+        view.endEditing(true)
+        if textField.text == nil || (textField.text?.count ?? 0) <= 0 {
+            cShowHUB(superView: nil, msg: "请先输入搜索内容")
+        }
+        return true
+    }
+}
+extension PQEditMusicSearchController {
+    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change _: [NSKeyValueChangeKey: Any]?, context _: UnsafeMutableRawPointer?) {
+        if object is AVPlayerItem, keyPath == "status" {
+            BFLog(message: "AVPlayerItem - status = \((object as! AVPlayerItem).status.rawValue)")
+            switch (object as! AVPlayerItem).status {
+            case .unknown:
+                break
+            case .readyToPlay:
+                break
+            case .failed:
+                break
+            default:
+                break
+            }
+        } else if object is AVPlayerItem, keyPath == "error" {
+            BFLog(message: "AVPlayerItem - error = \(String(describing: (object as! AVPlayerItem).error))")
+        }
+    }
+}
+