前言
通过这文章你会学到:
- 如何使用AVAudioPlayer播放本地音乐
- app进入后台时,仍能播放音乐,并且能在控制台控制播放暂停
- 提供锁屏下的信息,例如图片
- 将文字和图片合成为新的图片,实现类似 网易云 锁屏下轮播歌词的原理。
播放音乐
使用AVFoundation
在文件任意地方写下下面代码,然后执行playBackgroundMusic("音乐1")
就可以播放音乐了
import AVFoundation
var backgroundMusicPlayer: AVAudioPlayer!
func playBackgroundMusic(filename: String) {
//获取播放文件的位置,通过文件名和后缀
let url = NSBundle.mainBundle().URLForResource(filename, withExtension: "mp3")
//如果找不到文件则返回错误
if (url == nil) {
println("Could not find the file \(filename)")
}
var error: NSError? = nil
//将播放文件赋值给播放器
backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
//如果建立不了播放器则,提错
if backgroundMusicPlayer == nil {
println("Could not create audio player: \(error!)")
return
}
//负值表示单曲循环
backgroundMusicPlayer.numberOfLoops = -1
backgroundMusicPlayer.prepareToPlay()
backgroundMusicPlayer.play()
}
playBackgroundMusic("大开眼界")//播放`大开眼界.mp3`
后台播放音乐并操作
按下暂停能暂停播放
首先在info.plist
添加如图标注的字符串
就是在函数playBackgroundMusic(filename: String)
加上以下代码,就可以实现后台播放:
do {
//播放器独占后台,其它音乐会停止
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
}catch{
print(error)
}
接着则是后台时控制
首先在viewDidLoad
设置app接收remote event并且将viewController成为FirstResponder.
那么添加如下代码在viewDidload
UIApplication.sharedApplication().beginReceivingRemoteControlEvents()
self.becomeFirstResponder()
并且在viewController
覆盖canBecomeFirstResponder
override func canBecomeFirstResponder() -> Bool {
return true
}
在viewWillDispper
添加代码
UIApplication.sharedApplication().resignFirstResponder()
self.resignFirstResponder()
最后通过viewController处理事件,在viewController添加如下代码。
就能在程序切换到后台时不结束音乐。并实现如图中按下播放按键暂停或者播发音乐。
override func remoteControlReceivedWithEvent(event: UIEvent?) {
if event == nil {
return
}
//播放或者暂停按钮按下时执行相应操作
if event?.type == UIEventType.RemoteControl{
switch(event!.subtype){
case .RemoteControlPlay:
backgroundMusicPlayer.play()
case .RemoteControlPause:
backgroundMusicPlayer.pause()
default:
print(event!.subtype)
}
}
}
这样就能响应事件了。
锁屏下的音乐信息
lockScreen
使用MPNowPlayingInfoCenter
import MediaPlayer
func configNowPlaying(currentTime:NSTimeInterval,fireTime:NSTimeInterval){
let mpPlayer = MPNowPlayingInfoCenter.defaultCenter()
let image25 = UIImage(named:"25image")!
//设置:歌名,封面图片,现在的所在播放时间,播放速度,音乐的时长
let tmpPlayingInfo = [ MPMediaItemPropertyTitle : "25min",
MPMediaItemPropertyArtwork : MPMediaItemArtwork(image: image25) ,
MPNowPlayingInfoPropertyElapsedPlaybackTime : NSNumber(double: currentTime),
MPNowPlayingInfoPropertyPlaybackRate : 1.0,
MPMediaItemPropertyPlaybackDuration: fireTime
]
//将设置好的dict设置到infoCenter
mpPlayer.nowPlayingInfo = tmpPlayingInfo
}
锁屏下合成图片
效果:
锁屏下轮播文字实现思路,就是通过NSTimer
不断在后台每一秒合成图片和文字。
然后将合成后的图片如上函数configNowPlaying(_::)
赋值给nowPlayingInfo
的封面图片
那么合成图片的代码
func textToImage(drawText: NSString, inImage: UIImage)->UIImage{
// 设置字体格式
let textFont: UIFont = UIFont(name: "Helvetica Bold", size: textSize)!
//用图片大小设置image context的大小
UIGraphicsBeginImageContext(inImage.size)
//将图片画进去
inImage.drawInRect(CGRectMake(0, 0, inImage.size.width, inImage.size.height))
//使用函数drawString,将文字画进去。(下面会有这个自定义函数)
drawSting(drawText, withFont: textFont, inRect: CGRectMake(0, 0, inImage.size.width, inImage.size.height))
// 然后获取描绘好的图片
let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
// 结束imageContext描绘
UIGraphicsEndImageContext()
//将合成图片传递
return newImage
}
以下是居中描绘文字的函数drawString
func drawSting(s:NSString,withFont font:UIFont,inRect contextRect: CGRect){
//设置文字显示,居中
let paragraphStyle = NSParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle
paragraphStyle.lineBreakMode = NSLineBreakMode.ByTruncatingTail
paragraphStyle.alignment = NSTextAlignment.Center
//设置文字属性,待会描绘文字时用
let attr = [
NSFontAttributeName : font,
NSForegroundColorAttributeName : UIColor.blackColor(),
NSParagraphStyleAttributeName : paragraphStyle
]
//将字符串赋予属性
let size = s.sizeWithAttributes(attr)
//设置文字局中的位置
let xOffset = contextRect.origin.x + floor((contextRect.size.width - size.width) / 2)
let yOffset = contextRect.origin.y + floor((contextRect.size.height - size.height) / 2)
let textRect = CGRectMake(xOffset, yOffset, size.width, size.height)
//描绘文字
s.drawInRect(textRect, withAttributes: attr)
}
let whiteImage = UIImage(named:"whiteImage")!
let newImage = textToImage("24:55", inImage: whiteImage)//效果如下
合成图片
我这里是用白色的图片加上字符串实现的。
同理要实现网易云的那种效果则只需将白底的图片换成封面图加上歌词就可以了。
最后
本教程基本上就实现一个播放器的基本功能。
(END and Thank U)
参考链接:
后台播放
更多remote中控制的做法
网友评论