ViewController
import UIKit
import AVFoundation
class ViewController: UIViewController, AVAudioPlayerDelegate {
@IBOutlet weak var channelLabel: UILabel!
@IBOutlet weak var artistLabel: UILabel!
@IBOutlet weak var musicLabel: UILabel!
@IBOutlet weak var playButton: UIButton!
@IBOutlet weak var progressView: UIProgressView!
var channelList: Array<ChannelModel>?
var musicList: Array<MusicModel>?
var currentIndex: Int = 0 //当前歌曲的位置
var player: AVAudioPlayer?
var timer: NSTimer?
//下载数据
func fetchData(url: NSURL?, completion: (NSData?) -> Void) {
if let u = url {
let task = NSURLSession.sharedSession().dataTaskWithURL(u, completionHandler: { (data, response, error) in
if error == nil {
if let httpResponse = response as? NSHTTPURLResponse {
if httpResponse.statusCode == 200 {
//切换到主线程
dispatch_async(dispatch_get_main_queue()) {
completion(data)
}
}
}
}
})
task.resume()
}
}
override func viewDidLoad() {
super.viewDidLoad()
//频道列表
let url = NSURL(string: "https://gitshell.com/wcrane/FM-Res/raw/blob/master/channels.json")
//下载频道列表
fetchData(url) { (data) in
if let d = data {
let array = try! NSJSONSerialization.JSONObjectWithData(d, options: .AllowFragments) as? Array<NSDictionary>
self.channelList = array!.map({ (dict: NSDictionary) -> ChannelModel in
return ChannelModel(dict: dict)
})
//频道列表下载完毕
let c = self.channelList?.first
self.loadChannelDetail(c!.channel_id)
}
}
}
//代码重构
func loadChannelDetail(channelId: String) {
let encodeId = channelId.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
let path = "http://fm.baidu.com/dev/api/?tn=playlist&format=json&id=" + encodeId!
let url = NSURL(string: path)
fetchData(url) { (data) in
if let d = data {
let dict = try! NSJSONSerialization.JSONObjectWithData(d, options: .AllowFragments) as? NSDictionary
let array = dict!["list"] as? Array<NSDictionary>
self.musicList = array!.map({ (dict: NSDictionary) -> MusicModel in
return MusicModel(dict: dict)
})
//歌曲列表下载完成
let m = self.musicList?.first
print("歌曲Id:\(m?.songId)")
self.loadMusicDetail(0)
}
}
}
//下载歌曲详情
func loadMusicDetail(index: Int) {
guard index >= 0 && index < musicList?.count else {
return
}
currentIndex = index
let music = self.musicList![index]
let path = "http://music.baidu.com/data/music/fmlink?type=mp3&rate=320&songIds=\(music.songId)"
let url = NSURL(string: path)
fetchData(url) { (data) in
if let d = data {
let dict = try! NSJSONSerialization.JSONObjectWithData(d, options: .AllowFragments)
let errorCode = dict["errorCode"] as? NSNumber
if errorCode!.integerValue == 22000 {
let songData = dict["data"]
let songList = songData!!["songList"] as? NSArray
let songDict = songList?.firstObject as? NSDictionary
music.addInfo(songDict!)
self.showMusicInfo(music)
self.downloadMusicFile(music)
}
else {
print("没有歌曲")
self.loadMusicDetail(index + 1)
}
}
}
}
//下载歌曲文件
func downloadMusicFile(music: MusicModel) {
guard music.songLink != nil else {
print("没有歌曲链接")
return
}
fetchData(music.songLink) { (data) in
if let d = data {
self.playMusic(d)
}
}
}
//显示歌曲信息
func showMusicInfo(music: MusicModel) {
channelLabel.text = music.albumnName
artistLabel.text = music.artistName
musicLabel.text = music.songName
}
//播放
func playMusic(music: NSData) {
if player != nil && player!.playing {
timer?.invalidate()
player?.stop()
}
player = try! AVAudioPlayer(data: music)
player?.delegate = self
player?.prepareToPlay()
player?.play()
//在主线程中执行
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: #selector(didTime(_:)), userInfo: nil, repeats: true)
playButton.selected = true
}
func didTime(timer: NSTimer) {
progressView.progress = Float(player!.currentTime / player!.duration)
print(progressView.progress)
}
//切换频道
@IBAction func didChannelClicked(sender: UIButton) {
}
//播放控制
@IBAction func didPlayClicked(sender: UIButton) {
if let p = player {
if p.playing {
p.pause()
}
else {
p.play()
}
sender.selected = p.playing
}
}
@IBAction func didBackClicked(sender: UIButton) {
if currentIndex == 0 {
currentIndex = musicList!.count - 1
}
loadMusicDetail(currentIndex - 1)
}
@IBAction func didForwardClicked(sender: UIButton) {
if currentIndex == musicList!.count - 1 {
currentIndex = 0
}
loadMusicDetail(currentIndex + 1)
}
func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) {
timer?.invalidate()
playButton.selected = false
didForwardClicked(UIButton())
}
}
ChannelModel
class ChannelModel {
var channel_id: String!
var channel_name: String!
init(dict: NSDictionary) {
if let id = dict["channel_id"] {
channel_id = id as! String
}
if let chName = dict["channel_name"] {
channel_name = chName as! String
}
}
}
MusicModel
class MusicModel: NSObject{
var artistName: String!
var songName: String!
var albumnName: String!
var songLink: NSURL!
var songId: Int!
init(dict: NSDictionary){
if let id = dict["id"] as? NSNumber{
songId = id.integerValue
}
}
func addinfo(dict: NSDictionary){
if let aName = dict["artistName"]{
artistName = aName as! String
}
if let sName = dict["songName"]{
songName = sName as! String
}
if let aName = dict["albumName"] as? String {
albumnName = aName
}
if let sLink = dict["songLink"]{
songLink = NSURL(string: sLink as! String)
}
}
}