Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

swift 音乐播放器项目-《lxy的杰伦情歌》开发实战演练

$
0
0

最近准备将项目转化为OC与swift混合开发,试着写一个swift音乐播放器的demo,体会到了swift相对OC的优势所在,废话不多说,先上效果图:
这里写图片描述
ps:身为杰伦的铁粉,demo的主题必须跟杰伦有关,哈哈!而且自我感觉我有转型UI的天赋,有木有?

一、导入OC文件
创建好swift项目之后,导入OC工具类文件,Xcode会自动生成桥接文件
这里写图片描述

打开这个文件,在开头导入OC工具类的头文件,就可以调用OC工具类了

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//
#import "UIView+Frame.h"

二、界面绘制
这里方便起见,没有考虑性能问题,只是简单的demo,所以直接创建十个音乐按钮,加上一个播放按钮和一个暂停按钮。十个乐曲按钮放在一个UIScrollView上面。而且播放的音乐是本地音乐,首先在viewDidLoad前创建全局变量,代码如下:

    var btnIndex = 0
    let arrMusicName = ["蒲公英的约定","窃爱","退后","告白气球","阳光宅男","甜甜的","彩虹","心雨","哪里都是你","说好的幸福呢"]
    let btnPlay:UIButton = UIButton(type:.System)
    let btnPause:UIButton = UIButton(type:.System)

    override func viewDidLoad() {

界面绘制代码如下:

let SCREEN_W = UIScreen.mainScreen().bounds.size.width
        let SCREEN_H = UIScreen.mainScreen().bounds.size.height



        let ivBack:UIImageView = UIImageView(frame:CGRect(x:0, y:20, width:SCREEN_W, height:SCREEN_H))
        ivBack.image = UIImage(named:"aa.jpg")
        self.view.addSubview(ivBack)


        let lbTitle:UILabel = UILabel(frame:CGRect(x:0, y:20, width:SCREEN_W, height:44))
        lbTitle.text = "LXY的杰伦情歌"
        lbTitle.textColor = UIColor.whiteColor()
        lbTitle.textAlignment = NSTextAlignment.Center
        lbTitle.backgroundColor = UIColor.blackColor()
        lbTitle.alpha = 0.2
        self.view.addSubview(lbTitle)

        let scv:UIScrollView = UIScrollView(frame:CGRect(x:0, y:64, width:SCREEN_W, height:SCREEN_H - 74 - 44))
        scv.backgroundColor = UIColor.clearColor()
        self.view.addSubview(scv)

        var boom:Int = 0
        for st in arrMusicName {

            print(st)
            if let index = arrMusicName.indexOf(st) {

                let btn:UIButton = UIButton(type:.System)

                btn.backgroundColor = UIColor.whiteColor()
                btn.alpha = 0.5
                btn.setTitle(st, forState: UIControlState.Normal)
                btn.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
                btn.titleLabel?.font = UIFont.systemFontOfSize(16)
                btn.layer.masksToBounds = true
                btn.layer.shadowOffset = CGSizeMake(0, 10)
                btn.layer.shadowColor = UIColor.grayColor().CGColor
                btn.layer.shadowOpacity = 1
                btn.layer.shadowRadius = 10
                btn.layer.cornerRadius = 6
                btn.tag = index

                //传递触摸对象(即点击的按钮),需要在定义action参数时,方法名称后面带上冒号
                btn.addTarget(self, action:#selector(play(_:)), forControlEvents:.TouchUpInside)

                if index%2 == 0 {
                    btn.frame = CGRectMake(SCREEN_W/9,  20 + (SCREEN_W/3 + SCREEN_W/9)*CGFloat(index/2),SCREEN_W/3,SCREEN_W/3)
                }else {

                    btn.frame = CGRectMake(5*SCREEN_W/9,  20 + (SCREEN_W/3 + SCREEN_W/9)*CGFloat(index/2),SCREEN_W/3,SCREEN_W/3)

                }
                scv.addSubview(btn)
                boom = Int(btn.bottom)


            }
        }

        scv.contentSize = CGSizeMake(SCREEN_W,CGFloat(boom + 20))


        btnPlay.frame = CGRectMake(0, scv.bottom, SCREEN_W/2 - 10, 44)
        btnPlay.backgroundColor = UIColor.whiteColor()
        btnPlay.alpha = 0.5
        btnPlay.setTitle("播放", forState: UIControlState.Normal)
        btnPlay.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        btnPlay.titleLabel?.font = UIFont.systemFontOfSize(16)
        btnPlay.addTarget(self, action:#selector(MPMediaPlayback.play), forControlEvents:.TouchUpInside)
        btnPlay.hidden = true
        self.view.addSubview(btnPlay)


        btnPause.frame = CGRectMake(10 + SCREEN_W/2, scv.bottom, SCREEN_W/2 - 10, 44)
        btnPause.backgroundColor = UIColor.whiteColor()
        btnPause.alpha = 0.5
        btnPause.setTitle("暂停", forState: UIControlState.Normal)
        btnPause.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        btnPause.titleLabel?.font = UIFont.systemFontOfSize(16)
        btnPause.addTarget(self, action:#selector(MPMediaPlayback.pause), forControlEvents:.TouchUpInside)
        btnPause.hidden = true
        self.view.addSubview(btnPause)

    }


    func play(btn: UIButton){


        btnIndex = btn.tag
        let music = arrMusicName[btn.tag]

        let path = NSBundle.mainBundle().pathForResource(music, ofType: "mp3")
        let pathURL=NSURL(fileURLWithPath: path!)

        do {
            audioPlayer = try AVAudioPlayer(contentsOfURL: pathURL)
        } catch {
            audioPlayer = nil
        }

        audioPlayer?.prepareToPlay()

        audioPlayer.play()

        btnPause.hidden = false

        btnPlay.hidden = false

三、音乐播放器创建

class AudioManager: NSObject, AVAudioPlayerDelegate {
    static let sharedManager = AudioManager()  // singleton
    var audioPlayer: AVAudioPlayer!
}

然后在曲剧变量里实例化播放器

var audioPlayer = AudioManager.sharedManager.audioPlayer

四、按钮事件绑定

1、音乐按钮播放音乐事件

 func playWitnIndex(index: Int){

        let music = arrMusicName[index]
        let path = NSBundle.mainBundle().pathForResource(music, ofType: "mp3")
        let pathURL=NSURL(fileURLWithPath: path!)

        do {
            audioPlayer = try AVAudioPlayer(contentsOfURL: pathURL)
        } catch {
            audioPlayer = nil
        }

        audioPlayer?.prepareToPlay()

        audioPlayer.play()

        btnPause.hidden = false

        btnPlay.hidden = false
    }

这个方法吧button带过来,通过button的tag值判断所点击的按钮

2、播放按钮的点击事件

func play(){
        audioPlayer.play()
    }

3、暂停按钮的点击事件

 func pause(){
        audioPlayer.pause()
    }

到这里,音乐播放器的基本功能就已经实现了,点击就会有音乐播放了,并且播放暂停功能都已经实现

五、音乐后台播放的实现

要实现后台音乐播放功能,还学要对音乐播放器设置一下

在viewDidLoad方法中添加一下代码:

UIApplication.sharedApplication().beginReceivingRemoteControlEvents()
        do {

            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)
            try AVAudioSession.sharedInstance().setActive(true)
 } catch {

        }

只添加这个还不够,需要对工程进行设置
在info.plist添加Required background modes,具体如图:
这里写图片描述

这样,音乐播放器就实现了后台播放功能

六、音乐播放器锁屏音乐播放设置

添加setLockView方法,代码如下:

func setLockView(){
        MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = [
            // 歌曲名称
            MPMediaItemPropertyTitle:arrMusicName[btnIndex],
            // 演唱者
            MPMediaItemPropertyArtist:"周杰伦",
            // 锁屏图片
            MPMediaItemPropertyArtwork:MPMediaItemArtwork(image: UIImage(named: "aa.jpg")!),
            //
            MPNowPlayingInfoPropertyPlaybackRate:1.0,
            // 总时长            MPMediaItemPropertyPlaybackDuration:audioPlayer.duration,
            // 当前时间        MPNowPlayingInfoPropertyElapsedPlaybackTime:audioPlayer.currentTime
        ]
    }

在viewDidLoad方法中调用这个方法:

  self.setLockView()

这样就实现了锁屏界面了按钮设置

这里写图片描述

锁屏按钮点击事件实现需要重写remoteControlReceivedWithEvent方法,代码如下:

override func remoteControlReceivedWithEvent(event: UIEvent?) {
        switch event!.subtype {
        case .RemoteControlPlay:  // play按钮
            audioPlayer.play()
        case .RemoteControlPause:  // pause按钮
            audioPlayer.pause()
        case .RemoteControlNextTrack:  // next
            // ▶▶

            self.btnIndex = self.btnIndex + 1
            self.playWitnIndex(self.btnIndex)
            self.setLockView()

            break
        case .RemoteControlPreviousTrack:  // previous
            // ◀◀
            if self.btnIndex>0 {
                self.btnIndex = self.btnIndex - 1
                self.playWitnIndex(self.btnIndex)
                self.setLockView()
            }
            break
        default:
            break
        }
    }

七、外放问题的解决

此时,虽然功能都实现了,但是会发现音乐播放声音特别小,因为AVAudioPlayer默认是听筒播放,而不是扬声器播放
这里需要在播放器设置里添加如下设置代码

 let session = AVAudioSession.sharedInstance()
            try session.setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: AVAudioSessionCategoryOptions.DefaultToSpeaker)

其他设置如图所示:

这里写图片描述
到这里,这个swift版的lxy杰伦情歌APP就大功告成了,文章最后附上项目源码(由于音乐文件太大,只保留前两首歌曲),希望大家喜欢:

项目源码下载地址

作者:u012903898 发表于2017/3/9 11:06:56 原文链接
阅读:593 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>