iOS 音乐


这篇博客介绍的是较长的音频播放-音乐...

有关音效的介绍可以点击下面的连接进入...

iOS 音效

首先导入框架:AVFoundation.framework

导入框架后我们在需要使用音乐的文件内引入头文件:

#import <AVFoundation/AVFoundation.h>

做好准备后开始介绍这篇博客的主要内容:

我在这里实现了一个特别小的功能(如图)

  • 可以播放,暂停与停止(分别由三个按钮实现)
  • 播放进度的slider可以显示当前播放进度,并且通过拖动实现播放进度的改变
  • 播放速度的slider可以改变音乐的播放速度
  • 播放音量的slider可以改变音乐的播放音量

下面我会根据每个内容逐个介绍,从而实现整个代码:

AVAudioPlayer

AVAudioPlayer可以说是整个音乐的操作者,通过他我们实现各个操作.

@property (nonatomic, strong) AVAudioPlayer * player;

我们在AVAudioPlayer的懒加载中做一些操作

- (AVAudioPlayer *)player{
if (!_player) { NSURL * url = [[NSBundle mainBundle]URLForResource:@"CX" withExtension:@"mp3"]; NSError * error; //实例化播放
_player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error]; //设置代理
_player.delegate = self; if (error) {
NSLog(@"初始化失败");
}else{ //准备开始播放 缓冲数据
[_player prepareToPlay]; //是否允许快播
_player.enableRate = YES; //设置播放次数 -1为无限
//0:播放一次 1:播放两次 ......
_player.numberOfLoops = 0; //slider最大值
self.timeSlider.maximumValue = _player.duration; }
}
return _player;
}

这里值得注意的是准备开始播放 (其他的就不过多说了代码里有着详细的介绍)

即:

[_player prepareToPlay];

没有这句是无法正常播放的.

播放

代码操作:

//播放
- (IBAction)play:(id)sender { if (![self.player isPlaying]) { //添加定时器到runloop中
[self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [self.player play];
} }

在播放操作中我们进行了是否在播放的判断,以避免混音.

定时器是为了对播放进度的实现,后面会介绍到.

暂停

代码操作:

//暂停
- (IBAction)pause:(id)sender { if ([self.player isPlaying]) {
[self.player pause]; //暂停link
[self.link invalidate];
self.link = nil;
}
}

在暂停操作中我们先判断是否正在播放,只有正在播放才能执行暂停.

暂停的时候为了避免资源的过多浪费我们定制定时器并把定时器清空.

停止播放

代码操作:

//停止
- (IBAction)stop:(id)sender { [self.player stop]; //清空内存
self.player = nil; //停止link
[self.link invalidate];
self.link = nil; }

在停止操作中有一点很值得注意,当我们停止后,再次点击播放会发现是继续播放,显然不符合情理.

因此我们在这里对player进行了清空操作.

定时器的操作如暂停.

播放进度slider

播放进度slider的实现是需要配合定时器的使用的("实时"监控),因此前面出现的定时器也就可以理解

了.

//定时器的属性声明

//定时器
@property (nonatomic, strong) CADisplayLink * link;

//定时器的懒加载

- (CADisplayLink *)link{

    if (!_link) {
_link = [CADisplayLink displayLinkWithTarget:self selector:@selector(change)];
}
return _link;
} //改变slider进度的方法
- (void)change{ //获取当前时间 重置播放进度
self.timeSlider.value = self.player.currentTime;
}

该功能分析:

实现的功能是拖动控件实现进度跳转

那么

  • 当我们点击的时候停止播放
  • 根据value值设置进度
  • 当我们结束拖动时继续播放

代码操作:

//按下slieder 开始拖拽
- (IBAction)timeTouchDown:(id)sender { //停止播放
[self.player pause]; } //结束拖拽
- (IBAction)timeTouchUp:(id)sender { //继续播放
[self.player play];
} //改变播放进度
- (IBAction)timeChangeSlider:(UISlider *)sender { //修改现在的播放时间
self.player.currentTime = sender.value;
}

播放速度

代码操作:

//播放速度
- (IBAction)rateChange:(UISlider *)sender { self.player.rate = sender.value;
}

播放音量

代码操作:

//播放音量
- (IBAction)voiceChange:(UISlider *)sender { self.player.volume = sender.value;
}

代理

//播放完成
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ } //error
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{ } //iOS8 开始中断
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player{ } //iOS8 结束中断
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player{ }

在上面可以到iOS8的字样

那么iOS9呢???

- (void)viewDidLoad {

    [super viewDidLoad];

    //iOS9处理中断
AVAudioSession * session = [AVAudioSession sharedInstance]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(Interruption:) name:AVAudioSessionInterruptionNotification object:session]; } //iOS9中断处理方法
- (void)Interruption:(NSNotification *)noti{
if (noti.userInfo.allKeys.count == 2) {
NSLog(@"结束中断");
}else{
NSLog(@"开始中断");
}
}

一页的代码就把代码贴上了

//
// ViewController.m
// 音乐
//
// Created by ma c on 16/5/11.
// Copyright © 2016年 xubaoaichiyu. All rights reserved.
// #import "ViewController.h"
#import <AVFoundation/AVFoundation.h> @interface ViewController ()<AVAudioPlayerDelegate>
//播放本地音乐
@property (nonatomic, strong) AVAudioPlayer * player; //播放时间的滑块
@property (weak, nonatomic) IBOutlet UISlider *timeSlider; //定时器
@property (nonatomic, strong) CADisplayLink * link; @end @implementation ViewController #pragma mark - <getters and setters> - (CADisplayLink *)link{ if (!_link) {
_link = [CADisplayLink displayLinkWithTarget:self selector:@selector(change)];
}
return _link;
} - (AVAudioPlayer *)player{
if (!_player) { NSURL * url = [[NSBundle mainBundle]URLForResource:@"CX" withExtension:@"mp3"]; NSError * error; //实例化播放
_player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error]; //设置代理
_player.delegate = self; if (error) {
NSLog(@"初始化失败");
}else{ //准备开始播放 缓冲数据
[_player prepareToPlay]; //是否允许快播
_player.enableRate = YES; //设置播放次数 -1为无限
//0:播放一次 1:播放两次 ......
_player.numberOfLoops = 0; //slider最大值
self.timeSlider.maximumValue = _player.duration; }
}
return _player;
} #pragma mark - <life cycle>
- (void)viewDidLoad { [super viewDidLoad]; //iOS9处理中断
AVAudioSession * session = [AVAudioSession sharedInstance]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(Interruption:) name:AVAudioSessionInterruptionNotification object:session]; } #pragma mark - <AVAudioPlayerDelegate> //播放完成
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{ } //error
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error{ } //iOS8 开始中断
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player{ } //iOS8 结束中断
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player{ } #pragma mark - <event handle> //改变slider进度的方法
- (void)change{ //获取当前时间 重置播放进度
self.timeSlider.value = self.player.currentTime;
} //iOS9中断处理方法
- (void)Interruption:(NSNotification *)noti{
if (noti.userInfo.allKeys.count == 2) {
NSLog(@"结束中断");
}else{
NSLog(@"开始中断");
}
} //播放
- (IBAction)play:(id)sender { if (![self.player isPlaying]) { //添加定时器到runloop中
[self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; [self.player play];
} } //暂停
- (IBAction)pause:(id)sender { if ([self.player isPlaying]) {
[self.player pause]; //暂停link
[self.link invalidate];
self.link = nil;
} } //停止
- (IBAction)stop:(id)sender { [self.player stop]; //清空内存
self.player = nil; //停止link
[self.link invalidate];
self.link = nil; } //按下slieder 开始拖拽
- (IBAction)timeTouchDown:(id)sender { //停止播放
[self.player pause]; } //结束拖拽
- (IBAction)timeTouchUp:(id)sender { //继续播放
[self.player play];
} //改变播放进度
- (IBAction)timeChangeSlider:(UISlider *)sender { //修改现在的播放时间
self.player.currentTime = sender.value;
} //播放速度
- (IBAction)rateChange:(UISlider *)sender { self.player.rate = sender.value;
} //播放音量
- (IBAction)voiceChange:(UISlider *)sender { self.player.volume = sender.value;
} @end

iOS 音乐的更多相关文章

  1. iOS音乐播放器相关

    iOS音乐播放器框架主要有两大类:AvPlayer.AvaudioPlayer AvPlayer 能播放本地及网络歌曲 AvaudioPlayer 能播放本地歌曲.有相关代理方法(其实也可以播放网络歌 ...

  2. 一个功能齐全的IOS音乐播放器应用源码

    该源码是在ios教程网拿过来的,一个不错的IOS音乐播放器应用源码,这个是我当时进公司时 我用了一晚上写的  图片都是在别的地方扒的,主要是歌词同步,及上一曲,下一曲,功能齐全了 ,大家可以学习一下吧 ...

  3. iOS 音乐播放器之锁屏效果+歌词解析

    概述 功能描述:锁屏歌曲信息.控制台远程控制音乐播放:暂停/播放.上一首/下一首.快进/快退.列表菜单弹框和拖拽控制台的进度条调节进度(结合了QQ音乐和网易云音乐在锁屏状态下的效果).歌词解析并随音乐 ...

  4. 卡拉OK效果的实现-iOS音乐播放器

    自己编写的音乐播放器偶然用到这个模块,发现没有思路,而且上网搜了搜,关于这方面的文章不是很多,没找到满意的结果,然后自己也是想了想,最终实现了这种效果,想通了发现其实很简单. 直接上原理: 第一种: ...

  5. ios 音乐播放

    #import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewCont ...

  6. ios音乐播放器demo

    闲暇时间,写了一个音乐播放器. 个人认为,基于Demo 的学习是最有效果的. 想学习的同学,欢迎下载.知识,只有在传播的时候才有价值. 不懂之处,欢迎留言询问,将热情解答. 运行图 项目结构图 Git ...

  7. iOS - 音乐播放器之怎么获取音乐列表

    方法一: 这个方法是通过获取到沙盒路径,来得到音乐的路径(使用这个方法需要把音乐放进沙盒) NSFileManager *manager = [NSFileManager defaultManager ...

  8. iOS音乐后台播放及锁屏信息显示

    实现音乐的后台播放.以及播放时,能够控制其暂停,下一首等操作,以及锁屏图片歌曲名等的显示 此实例须要真机调试.效果图例如以下: project下载:githubproject下载 实现步骤: 1.首先 ...

  9. ios 音乐播放,音乐信息显示方法

    下面的博客写的很清楚了 http://msching.github.io/blog/page/2/ 主要涉及AVAudioPlayer和下面这几个函数 MPNowPlayingInfoCenter.d ...

随机推荐

  1. 前端scss的使用及gulp发布方式

    如标题所述,这篇博文是说scss以及gulp发布方式: 如果你没用过scss和gulp或不甚了解,你可以看看这篇博文,叙说的水平有限,各位看官大神见谅: 说scss之前,先来说说sass,sass是一 ...

  2. [python IDE] 舒服的pycharm设置

    个人使用的IDE有国产的ulipad,sublime text 3 ,或者vs集成下的,不过讲到好用跨平台,还真是只有pycharm 写python最舒服,一个是因为有社区版,免费,不存在版权问题,另 ...

  3. Spring @Transactional propagation 各个属性值的含义

    REQUIRED:业务方法需要在一个容器里运行.如果方法运行时,已经处在一个事务中,那么加入到这个事务,否则自己新建一个新的事务. NOT_SUPPORTED:声明方法不需要事务.如果方法没有关联到一 ...

  4. 关于js性能

    1,声明变量要赋初值2,尽量避免声明全局变量,可以减少与系统的重名3,当编写大量js代码时,难免会遇到命名冲突,这是可以通过模拟命名空间方式     来避免冲突4,尽量避免使用全局变量,搜索全局变量是 ...

  5. WIN-CE系统架构

    WIN-CE 系统架构分为素部分:硬件层.OEM 层.操作系统层.应用层 http://hovertree.com/hvtart/bjae/oy9pqb94.htm 硬件层: 由CPU .存储器.I/ ...

  6. 使用DocX开源组件,实现动态数据的填充。

    1.先解释一下,什么叫做动态数据,动态数据指的是,一条数据的格式固定,但数据的条数不固定. 2.应用环境,在一个表格当中如果,现在表格有三行n列,如果你需要在表格第一行后添加同等规格的一行或n行,应该 ...

  7. Note: This element neither has attached source nor attached Javadoc and hence no Javadoc could be found.

    在Eclipse中开发Android项目时,鼠标停放在想要查看帮助文档的类上面,发现没有显示帮助文档,显示了下面一句话: Note: This element neither has attached ...

  8. Firemonkey 控件设定字型属性及颜色

    将控件 StyledSettings 的勾取消(如此才能自定样式及字型,如果勾选则依 Style 而定). 设定 TextSettings 里的 Font 属性. 使用代码寫法: CheckBox1. ...

  9. JWS ,JAX-WS ,JAX-RS,REST,Restlet,SOAP 相关概念

    与 WebServices 相关的 J2EE 技术称为 JWS(Java WebServices),其中含有 JAX-WS.JAX-RS.JAXB.JAXR.SAAJ.StAX 等技术 支持 SOAP ...

  10. LGLTagsView

    做项目的时候经常会用到标签,比如说现在很多项目中搜索历史用标签展示 和 选择某个产品的不同属性用标签展示....网上的有很多封装好的标签,但是作为一个上进的程序员,都希望能有一个自己写的.其实也是一种 ...