123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- //
- // BFMusicSearchController.swift
- // BFRecordScreenKit
- //
- // Created by Harry on 2022/3/3.
- //
- import Foundation
- import BFUIKit
- import BFMediaKit
- import BFCommonKit
- import BFNetRequestKit
- import Alamofire
- import MJRefresh
- class BFMusicSearchController: BFBaseViewController {
-
- var choseAction : ((PQVoiceModel?) -> Void)?
-
- var cutActionCallback: ((PQVoiceModel) -> Void)?
-
- var loadedTimeRangesObserver : NSKeyValueObservation?
- var chosedIndexPath : IndexPath?
- var chosedCellStatu : BFMuicInfoCellState = .pause
-
- var searchResults = [PQVoiceModel]()
-
- var currPage = 1
-
- var keywork : String?
- // 试听音乐
- let player:AVPlayer = {
- let p = AVPlayer(playerItem: nil)
-
- return p
- }()
-
- lazy var searchTF : UITextField = {
- let searchTF = UITextField()
- let leftv = UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 20))
- let iv = UIImageView(frame: CGRect(x: 6, y: 0, width: 20, height: 20))
- iv.contentMode = .scaleAspectFit
- iv.image = imageInRecordScreenKit(by: "search")
- leftv.addSubview(iv)
- searchTF.leftView = leftv
- searchTF.leftViewMode = .always
- searchTF.clearButtonMode = .whileEditing
-
- let redPlaceholderText = NSAttributedString(string: "歌名/歌手名",
- attributes: [NSAttributedString.Key.foregroundColor: UIColor.hexColor(hexadecimal: "#BDBDBD"),NSAttributedString.Key.font:UIFont.systemFont(ofSize: 14,weight: .regular)])
- searchTF.attributedPlaceholder = redPlaceholderText
- searchTF.font = UIFont.systemFont(ofSize: 14,weight: .regular)
- searchTF.delegate = self
- searchTF.returnKeyType = .search
- searchTF.textColor = UIColor.white
- searchTF.backgroundColor = UIColor.hexColor(hexadecimal: "#1d1d1d")
- searchTF.layer.cornerRadius = 18
-
- return searchTF
- }()
-
- lazy var musicTb : UITableView = {
- let tb = UITableView(frame: .zero)
- tb.delegate = self
- tb.dataSource = self
- tb.separatorColor = UIColor.hexColor(hexadecimal: "#272727")
- tb.register(BFMusicInfoSearchCell.self, forCellReuseIdentifier: "BFMusicInfoSearchCell")
- tb.tableFooterView = UIView()
- tb.backgroundColor = .clear
- tb.mj_footer = MJRefreshAutoFooter.init(refreshingBlock: {[weak self] in
- guard let wself = self else { return }
- if wself.searchResults.count > 0 {
- wself.requestSearchMusic()
- }
- })
- return tb
- }()
-
- override func viewDidAppear(_ animated: Bool) {
- super.viewDidAppear(animated)
-
- searchTF.becomeFirstResponder()
- }
-
- override func viewDidLoad() {
- super.viewDidLoad()
-
- let closeBtn = UIButton()
- closeBtn.setImage(imageInRecordScreenKit(by: "search_close"), for: .normal)
- closeBtn.frame = CGRect(x: 12, y: statusBarHeight + 2, width: 40, height: 40)
- closeBtn.addTarget(self, action: #selector(closeAction), for: .touchUpInside)
- view.addSubview(closeBtn)
-
- searchTF.frame = CGRect(x: 62, y: statusBarHeight + 4, width: cScreenWidth - 62 - 18, height: 36)
- view.addSubview(searchTF)
- view.addSubview(musicTb)
- musicTb.snp.makeConstraints { make in
- make.left.right.bottom.equalToSuperview()
- make.top.equalTo(searchTF.snp.bottom).offset(4)
- }
-
- loadedTimeRangesObserver = player.observe(\AVPlayer.currentItem?.loadedTimeRanges, options: [.new, .initial]) { [weak self] (player, change) in
-
- DispatchQueue.main.async {[weak self] in
- guard let wself = self else { return }
-
- guard let ranges = change.newValue as? [CMTimeRange] else { return }
- if let indx = wself.chosedIndexPath, let cell = wself.musicTb.cellForRow(at: indx) as? BFMuicInfoCell, let totalDur = player.currentItem?.duration, totalDur.isValid, CMTimeCompare(ranges.first?.duration ?? .zero, totalDur) >= 0{
- if (player.currentItem?.asset as? AVURLAsset)?.url.absoluteString ?? "b" == cell.data?.musicPath ?? "a" {
- if cell.status == .loading{
- cell.status = .playing
- wself.chosedCellStatu = .playing
- }
- }
- }
- // BFLog(1, message: "开始播放音乐:\(ranges.first?.start.seconds ?? 0), dur:\( ranges.first?.duration.seconds ?? 0), tot:\(player.currentItem?.duration.seconds ?? 0)")
- }
- }
-
- }
-
- func choseCell() -> BFMuicInfoCell? {
- if let indpx = chosedIndexPath, let cell = musicTb.cellForRow(at: indpx) as? BFMuicInfoCell {
- return cell
- }
- return nil
- }
-
- @objc func closeAction(){
- self.dismiss(animated: true, completion: nil)
- }
- }
- extension BFMusicSearchController : UITableViewDelegate, UITableViewDataSource {
- func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
- return searchResults.count
- }
-
- func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
- let cell = tableView.dequeueReusableCell(withIdentifier: "BFMusicInfoSearchCell")
-
- if let cell = cell as? BFMusicInfoSearchCell{
- cell.data = searchResults[indexPath.row]
- cell.useCallback = {[weak self, weak cell] in
- guard let wself = self else { return }
- wself.player.pause()
- cell?.status = .pause
- wself.choseAction?(cell?.data)
- wself.dismiss(animated: true, completion: nil)
- }
- cell.cutCallBack = {[weak self, weak cell] in
- guard let wself = self else { return }
- wself.player.pause()
- cell?.status = .pause
-
- if let data = cell?.data {
- wself.dismiss(animated: true) {[weak self] in
- guard let wself = self else { return }
- wself.cutActionCallback?(data)
- }
- }
- }
- if cell.data?.isSelected ?? false {
- chosedIndexPath = indexPath
- cell.status = chosedCellStatu
- }else{
- cell.status = .normal
- }
- }
-
- cell?.selectionStyle = .none
-
- return cell!
- }
-
- func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
- return 64
- }
-
- func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
-
- if let cell = tableView.cellForRow(at: indexPath) as? BFMusicInfoSearchCell {
- if chosedIndexPath == indexPath {
- if cell.status != .pause{
- cell.status = .pause
- player.pause()
- }else{
- cell.status = .loading
- player.play()
- }
- return
- }
- cell.changeSelected(true)
-
- chosedIndexPath = indexPath
-
- if cell.status == .normal {
- if let urlStr = cell.data?.musicPath, let url = URL(string: urlStr){
- BFLog(1, message: "歌曲地址: \(url)")
- if url.absoluteString != (player.currentItem?.asset as? AVURLAsset)?.url.absoluteString ?? "b" {
- if player.currentItem != nil {
- NotificationCenter.default.removeObserver(self, name: .AVPlayerItemDidPlayToEndTime, object: player.currentItem)
- }
- player.replaceCurrentItem(with: AVPlayerItem(url: url))
- NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: .main) {[weak self] notice in
- guard let wself = self else { return }
- wself.player.currentItem?.seek(to: .zero, completionHandler: nil)
- // wself.choseCell()?.status = .pause
- // wself.chosedCellStatu = .pause
- wself.player.play()
- }
-
- cell.status = .loading
- }else {
- cell.status = .playing
- }
- player.play()
- }
- }else if cell.status == .pause{
- player.play()
- } else{
- player.pause()
- cell.status = .pause
- }
- chosedCellStatu = cell.status
- }
- }
-
- func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
- let cell = tableView.cellForRow(at: indexPath) as? BFMusicInfoSearchCell
- cell?.status = .normal
- cell?.changeSelected(false)
-
- chosedIndexPath = nil
- player.pause()
- }
-
- // MARK: - 搜素接口
- func requestSearchMusic() {
- if keywork?.count ?? 0 < 1 {
- cShowHUB(superView: nil, msg: "搜索不能为空")
- return
- }
-
- BFNetRequestAdaptor.postRequestData(url: PQENVUtil.shared.materialSearchApi + searchBGMMaterialUrl, parames: ["keyWord": keywork, "pageNo": currPage, "pageSize": 20], commonParams: commonParams(), encoding: JSONEncoding.default, isJsonEncodingNormal: true) { [weak self] response, _, error, _ in
- DispatchQueue.global().async {[weak self] in
- guard let wself = self else { return }
-
- var bgmList = [PQVoiceModel]()
- if response is NSNull || response == nil {
- DispatchQueue.main.async {
- cShowHUB(superView: nil, msg: "网络连接失败,请检查网络后重试")
- }
- return
- }
- let tempArr = (response as? [String: Any])?["entityList"] as? [[String: Any]]
- if tempArr != nil {
- for item in tempArr! {
- let tempModel = PQVoiceModel(jsonDict: item)
- tempModel.volume = 30
- tempModel.voiceType = VOICETYPT.BGM.rawValue
- bgmList.append(tempModel)
- }
- }
- if wself.currPage == 1 {
- wself.searchResults.removeAll()
- }
- wself.searchResults.append(contentsOf: bgmList)
- wself.currPage += 1
- DispatchQueue.main.async {[weak self] in
- guard let wself = self else { return }
-
- if wself.searchResults.count > 0 {
- // wself.musicTb.tableFooterView = UIView()
- }else{
- wself.musicTb.tableFooterView = wself.createNoDataView()
- }
- wself.musicTb.reloadData()
- }
- }
- }
- }
-
- func createNoDataView() -> UIView {
- let back = UIView(frame: CGRect(x: 0, y: 0, width: cScreenWidth, height: 200))
-
- let l = UILabel(frame: CGRect(x: 40, y: 60, width: cScreenWidth - 80, height: 80))
- l.text = "没有搜索到相关音乐\n换个词再试试吧"
- l.textColor = UIColor.hexColor(hexadecimal: "#787878")
- l.textAlignment = .center
- l.numberOfLines = 2
- l.font = UIFont.systemFont(ofSize: 17)
- back.addSubview(l)
-
- return back
- }
-
- func resetRearch() {
- player.pause()
- chosedCellStatu = .normal
- chosedIndexPath = nil
- currPage = 1
- }
- }
- extension BFMusicSearchController : UITextFieldDelegate {
-
- func textFieldShouldReturn(_ textField: UITextField) -> Bool {
- if let keyword = textField.text, keyword.replacingOccurrences(of: " ", with: "", options: .literal, range: nil).count > 0 {
- resetRearch()
- keywork = keyword
- requestSearchMusic()
- }else{
- cShowHUB(superView: nil, msg: "搜索不能为空")
- }
-
- textField.resignFirstResponder()
-
-
- return true
- }
-
-
- }
|