123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- //
- // 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()
- // 按钮点击的回调
- var btnClickHandle: ((_ sender: UIButton, _ bgmData: Any?) -> Void)?
- 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) {
- PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_musicVideoPreview_musicSearchAudition, pageSource: .sp_shanyinApp_main, extParams: ["musicName":(itemData as? PQVoiceModel)?.musicName ?? "" ,"musicId":(itemData as? PQVoiceModel)?.musicId ?? ""], remindmsg: "")
-
- self?.playStuckPointMusic(itemData: itemData as? PQVoiceModel)
- }
- }
- }
- searchController.btnClickHandle = { [weak self] btn, bgmData in
-
- PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_musicVideoPreview_musicSearchSelect, pageSource: .sp_shanyinApp_main, extParams: ["musicName":(bgmData as? PQVoiceModel)?.musicName ?? "" ,"musicId":(bgmData as? PQVoiceModel)?.musicId ?? ""], remindmsg: "")
-
- // 使用音乐
- self?.backBtnClick()
- if(self?.btnClickHandle != nil){
- self?.btnClickHandle!(btn,bgmData)
- }
-
- }
- searchController.scroDidScroHandle = { [weak self] in
- self?.view.endEditing(true)
- }
- searchController.contentType = .serach
- return searchController
- }()
- override func backBtnClick() {
- super.backBtnClick()
- avPlayer.pause()
- }
- deinit {
- PQNotification.removeObserver(self)
- avPlayer.currentItem?.removeObserver(self, forKeyPath: "status")
- avPlayer.currentItem?.removeObserver(self, forKeyPath: "error")
- avPlayer.pause()
- avPlayer.replaceCurrentItem(with: nil)
- playerItem = nil
- }
- override func viewWillAppear(_ animated: Bool) {
- super.viewDidAppear(animated)
- PQEventTrackViewModel.baseReportUpload(businessType: .bt_windowView, objectType: .ot_shanyinApp_musicVideoPreview_musicSearch, pageSource: .sp_shanyinApp_main, extParams: nil, remindmsg: "")
- }
- override func viewDidLoad() {
- super.viewDidLoad()
- view.addSubview(searchTF)
- searchTF.becomeFirstResponder()
-
- addChild(searchController)
- view.addSubview(searchController.view)
-
- leftButton(image: UIImage(named: "upload_delete"), tintColor: PQBFConfig.shared.styleTitleColor)
-
- //请求一下热门数据在没有搜索数据时显示
- PQStuckPointViewModel.stuckPointMusicPageList(tagId: 425, parentTagId: 0, pageNum: 1, videoCount: 0, imageCount: 0, totalDuration: 0) { [weak self] musicInfo, _ in
- if musicInfo.count > 0 {
- self?.searchController.hotList = musicInfo
- self?.searchController.configMusicListData(isRefresh: true, musicListData: 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
- }
- }
-
- var avPlayerTimeObserver:Any?
- /// 播放音乐
- /// - 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")
- if avPlayerTimeObserver != nil {
- avPlayer.removeTimeObserver(avPlayerTimeObserver as Any)
- }
-
- 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()
-
- avPlayerTimeObserver = avPlayer.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 10), queue: DispatchQueue.global()) {[weak self] time in
- if fabs(CMTimeGetSeconds(time) - (itemData?.startTime ?? 0)) > 0.1 {
- self?.avPlayer.removeTimeObserver(self?.avPlayerTimeObserver as Any)
- self?.avPlayerTimeObserver = nil
- // 停止cell loading动画
- PQNotification.post(name: NSNotification.Name(rawValue: "MusicContentCellIconLoadingAnimationStop"), object: nil)
- }
- }
- // 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()
-
- PQEventTrackViewModel.baseReportUpload(businessType: .bt_buttonClick, objectType: .ot_shanyinApp_musicVideoPreview_musicSearch, pageSource: .sp_shanyinApp_main, extParams: nil, remindmsg: "")
- 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))")
- }
- }
- }
|