• Swift实战-QQ在线音乐(第二版)


    此版本使用百度音乐接口,原因是豆瓣接口很多歌曲没办法找到歌词。

    此版本添加了歌词的显示、上一曲、下一曲的实现、歌曲列表指明当前歌曲。

    下面来看一下实现过程》》》

     一、项目准备:

    百度音乐国语歌曲列表Api接口: 

    http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.song.getSmartSongList&page_no=1&page_size=50&scene_id=42&item_id=115&version=5.2.1&from=ios&channel=appstore

    百度音乐mp3搜索Api接口:

    http://box.zhangmen.baidu.com/x?op=12&count=1&title=歌曲名称$$歌唱者$$$$

    二、修改实体Song.swift 让其跟百度音乐 列表字段名称一致

    import Foundation
    class Song: NSObject {
        
        var artist_id:NSNumber = 0.0
        var language:NSString = ""
        var pic_big:NSString = ""
        var pic_small:NSString = ""
        var country:NSString = ""
        var area:NSNumber = 0.0
        var publishtime:NSString = ""
        var album_no:NSNumber = 0.0
        var lrclink:NSString = ""
        var versions:NSString = ""
        var copy_type:NSNumber = 0.0
        var file_duration:NSNumber = 0.0
        var hot:NSString = ""
        var all_artist_ting_uid:NSNumber = 0.0
        var pic_premium:NSString = ""
        var pic_huge:NSString = ""
        var pic_singer:NSString = ""
        var all_rate:NSString = ""
        var resource_type:NSNumber = 0.0
        var all_artist_id:NSNumber = 0.0
        var compose:NSString = ""
        var songwriting:NSString = ""
        var del_status:NSNumber = 0.0
        var has_mv_mobile:NSNumber = 0.0
        var song_id:NSNumber = 0.0
        var title:NSString = ""
        var ting_uid:NSNumber = 0.0
        var author:NSString = ""
        var album_id:NSNumber = 0.0
        var album_title:NSString = ""
        var is_first_publish:NSNumber = 0.0
        var havehigh:NSNumber = 0.0
        var charge:NSNumber = 0.0
        var has_mv:NSNumber = 0.0
        var learn:NSNumber = 0.0
        var song_source:NSString = ""
        var piao_id:NSNumber = 0.0
        var korean_bb_song:NSNumber = 0.0
        var resource_type_ext:NSNumber = 0.0
    }

    三、使用block 封装请求接口

    新建DataProvider.swift文件 代码如下:

    import Foundation
    
    
    class DataProvider:NSObject,HttpProtocol{
        
        var blockRecive:(NSDictionary) -> () = {param in }
        var eHttp:HttpController = HttpController()
        override init(){
            super.init()
            eHttp.delegate=self
        }
        
        //**
        //*获取歌曲列表
        //*
        func getSongList(reciveBlock:(NSDictionary) -> () = {param in }){
            blockRecive=reciveBlock
            eHttp.onSearch("http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.song.getSmartSongList&page_no=1&page_size=50&scene_id=42&item_id=115&version=5.2.1&from=ios&channel=appstore")
            //
            
        }
    
        //**
        //*获取歌曲mp3信息
        //*
        func getSongMp3(p:Song,reciveBlock:(NSString) -> () = {param in }){
            
            var url:NSString = "http://box.zhangmen.baidu.com/x?op=12&count=1&title=(p.title)$$(p.author)$$$$"
            var nsUrl:NSURL=NSURL(string:url.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)!
            var request:NSURLRequest=NSURLRequest(URL:nsUrl)
            NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: {(response:NSURLResponse!,data:NSData!,error:NSError!)->Void in
                if (data != nil){
                    var reciveString:NSString = NSString(data: data, encoding: NSUTF8StringEncoding)!
                    //
                    var strArr:NSArray = reciveString.componentsSeparatedByString("<![CDATA[") as NSArray
                    if strArr.count > 2{
                        var s1:NSString = strArr[1].description
                        s1 = s1.stringByReplacingOccurrencesOfString("$]]></encode><decode>", withString: "")
                        var sArr:NSArray = s1.componentsSeparatedByString("/") as NSArray
                        var lastS:NSString = sArr.lastObject as NSString
                        
                        var s2Arr:NSArray = strArr[2].description.componentsSeparatedByString("]]") as NSArray
                        
                        s1 = s1.stringByReplacingOccurrencesOfString(lastS, withString:s2Arr[0] as NSString)
                        NSLog("得到mp3文件地址为:%@", s1);                    reciveBlock(s1)
                    }
                }
            })
        }
        //**
        //*请求网络数据结果
        //*
        func didRecieveResults(results:NSDictionary){
          //  NSLog("请求到的数据:%@", results)
            blockRecive(results)
        }
    }

    三、修改第一版中调用请求的方法,因为封装到类DataProvider了,只需要从DataProvider上去调用。

      //请求列表数据
            provider.getSongList { (results) -> () in
                let errorCode:NSInteger=results["error_code"] as NSInteger
                let result:NSDictionary=results["result"] as NSDictionary
                if (errorCode==22000) {
                    let resultData:NSArray = result["songlist"] as NSArray
                    let list:NSMutableArray = NSMutableArray()
                    
                    for(var index:Int=0;index<resultData.count;index++){
                        var dic:NSDictionary = resultData[index] as NSDictionary
                        var song:Song=Song()
                        song.setValuesForKeysWithDictionary(dic as NSDictionary)
                        list.addObject(song)
                    }
                    self.tableData=list
                    self.setCurrentSong(list[0] as Song)
                }
            }

    四、在设置当前歌曲的方法里增加请求mp3文件,和请求lrc歌词的调用

    //设置当前播放的音乐
        func setCurrentSong(curSong:Song){
            currentSong=curSong
            currentIndex=tableData.indexOfObject(curSong)
            photo.image=getImageWithUrl(currentSong.pic_premium)
            backgroundImageView.image=photo.image
            titleLabel.text=currentSong.title
            artistLabel.text="— (currentSong.author) —"
            playButton.selected=false
            playTimeLabel.text="00:00"
            lrcLabel.text=""
            self.progressSlider.value=0.0
            self.rotationAnimation()
            self.audioPlayer.stop()
            timer?.invalidate()
            timer=NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: "updateTime", userInfo: nil, repeats: true)
            
            getCurrentMp3(curSong)
            getCurrentLrc(curSong.lrclink)
        }

    请求当前的mp3文件

     //获取当前mp3
        func getCurrentMp3(song:Song){
            provider.getSongMp3(song, reciveBlock: { (results) -> () in
                self.audioPlayer.contentURL=NSURL(string: results)
            })
        }

    请求当前的lrc歌词文件

     //获取歌词
        func getCurrentLrc(lrclick:NSString){
           currentLrcData=parseLyricWithUrl(lrclick)?
        }

    对歌词文件的解析-存储到NSArray<ShongLrc>变量中

    /**
    *解析歌词
    */
    func parseLyricWithUrl(urlString:NSString)->NSArray?{
        if ( urlString.length < 2 ){
            return nil
        }
        var url : NSURL = NSURL(string:urlString)!
        var lyc : NSString = NSString(contentsOfURL: url, encoding:NSUTF8StringEncoding, error: nil)!
        NSLog("获取到歌词文件内容:%@", lyc)
        var result:NSMutableArray = NSMutableArray()
        for lStr in lyc.componentsSeparatedByString("
    ") {
            var item:NSString = lStr as NSString
            if(item.length>0){
                var dic:NSDictionary = NSDictionary()
                var startrange:NSRange = item.rangeOfString("[")
                var stoprange:NSRange = item.rangeOfString("]")
                if stoprange.length == 0{
                    //歌词没时间
                    var songLrc:SongLrc = SongLrc()
                    songLrc.total=NSNumber(int: -1)//开始显示的秒数
                    songLrc.time=""//开始显示时间
                    songLrc.text=item//显示的歌词
                    result.addObject(songLrc)
                    
                }else{
                    var content:NSString = item.substringWithRange(NSMakeRange(startrange.location+1, stoprange.location-startrange.location-1))
                    //歌词有时间
                    if (content.length == 8) {
                        var minute:NSString = content.substringWithRange(NSMakeRange(0, 2))
                        var second:NSString = content.substringWithRange(NSMakeRange(3, 2))
                        var mm:NSString = content.substringWithRange(NSMakeRange(6, 2))
                        var time:NSString = NSString(format: "%@:%@.%@", minute,second,mm)
                        var total:NSNumber = NSNumber(integer: minute.integerValue * 60 + second.integerValue)
                        var lyric:NSString = item.substringFromIndex(10)
                        
                        var songLrc:SongLrc = SongLrc()
                        songLrc.total=total//开始显示的秒数
                        songLrc.time=time//开始显示时间
                        songLrc.text=lyric//显示的歌词
                        result.addObject(songLrc)
                   }
                }
                
            }
        }
        return result
    }

    五、为上一首、下一首添加事件

     //上一曲
        @IBAction func preSongClick(sender: UIButton){
            if(currentIndex>0){
                currentIndex--
            }
            currentSong=tableData.objectAtIndex(currentIndex) as Song
            setCurrentSong(currentSong)
        }
        
        //下一曲
        @IBAction func nextSongClick(sender: UIButton){
            if(currentIndex < tableData.count){
                currentIndex++
            }
            currentSong=tableData.objectAtIndex(currentIndex) as Song
            setCurrentSong(currentSong)
        }
        

    六、在歌曲列表中显示当前播放的歌曲

     //当前行数据
            let rowSong:Song=self.tableData[indexPath.row] as Song
            //行显示内容
            cell.textLabel?.text=rowSong.title
            cell.textLabel?.font=UIFont(name: "宋体", size: 14.0)
            //如果是当前歌曲显示绿色
            if indexPath.row == self.viewContorller.currentIndex{
                cell.textLabel?.textColor=UIColor.greenColor()
            }else{
                cell.textLabel?.textColor=UIColor.whiteColor()
            }
            cell.detailTextLabel?.text=rowSong.author
            cell.detailTextLabel?.font=UIFont(name:"宋体", size: 8.0)

    最终效果:

     

    源码下载地址:http://download.csdn.net/detail/fangwulongtian/8568535

    原文出自:http://www.cnblogs.com/wuxian/p/4397153.html 转载就注明来源

  • 相关阅读:
    零基础入门:实时音视频技术基础知识全面盘点
    IM开发干货分享:如何优雅的实现大量离线消息的可靠投递
    flask_apscheduler 定时任务框架
    小程序使用 editor 富文本编辑器填坑指南
    万年深坑:mpVue 中的坑
    js利用canvas绘制爱心
    【字节跳动21届提前批】面试手撕代码——电梯调度算法
    Maximum call stack size exceeded 报错
    未安装less-loder
    05 vue前端工程化
  • 原文地址:https://www.cnblogs.com/wuxian/p/4397153.html
Copyright © 2020-2023  润新知