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("\n") {
        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 轉載就注明來源

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM