ios开发学习- 简易音乐播放器2 (基于iPhone4s屏幕尺寸)-- 歌词解析--plist文件应用--imageNamed图片加载耗内存
声明:(部分图片来自网络,如果侵犯了您的权益请联系我,会尽快删除!)
又是音乐播放器,不过这次和上次不一样了,准确说这次更像播放器了,初学者不建议看这个,可以先看前面一个音乐播放器(1),当然 我没加1,写了这个,就把前面的默认当1吧
先上图:

接下来源码:(一样:大量的三元式,多看看就习惯了,主要是习惯一行能干的事绝不用两行);
//
// ViewController.m
// C_MusicPlayer
//
// Created by Ibokan on 15/8/22.
// Copyright (c) 2015年 Crazy凡. All rights reserved.
// #import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "LyricsAnalysis.h" @interface ViewController () <AVAudioPlayerDelegate>
@property (nonatomic,strong)UIImageView *imageview;//bgimg
@property (nonatomic,strong)UISlider *slider;//播放进度条
@property (nonatomic,strong)UILabel *tlableall;//音乐总时长
@property (nonatomic,strong)UILabel *tlablecur;//音乐当前播放时长
@property (nonatomic,strong)UILabel *labellrc;//歌词显示label @property (nonatomic,strong)UIButton *buttonPlayandPause;
@property (nonatomic,strong)UIButton *buttonPrevious;
@property (nonatomic,strong)UIButton *buttonNext;
@property (nonatomic,strong)AVAudioPlayer *player;
@property (nonatomic,strong)LyricsAnalysis *lrc;
@property (nonatomic,strong)UIImageView *musicImg;
@property (nonatomic,strong)NSTimer *timer;//计时器
@property (nonatomic,strong)NSMutableArray *musicListArray;//歌曲列表 @property int indexLrc;//歌词播放指向
@property int indexMusicList;//歌曲播放指向 //@property (nonatomic,strong)UIScrollView * scrollview;
@end @implementation ViewController - (NSArray *)musicListArray//初始化歌曲列表 : 懒加载
{
if(!_musicListArray)
{
_musicListArray = [NSMutableArray arrayWithArray:[NSArray arrayWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"Music.plist" ofType:nil]]];
for(NSDictionary *temp in _musicListArray)//屏蔽无效路径
{
[[NSBundle mainBundle]pathForResource:[temp valueForKey:@"music"] ofType:nil] ? nil:[_musicListArray removeObject:temp];
}
}
return _musicListArray;
} - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib. self.indexLrc = ;
self.indexMusicList = ; self.musicImg = [[UIImageView alloc]initWithFrame:CGRectMake(, , , )];//初始化歌曲图片
self.musicImg.backgroundColor = [UIColor groupTableViewBackgroundColor];
self.musicImg.contentMode = UIViewContentModeScaleAspectFill;
[self.view addSubview:self.musicImg]; self.imageview = [[UIImageView alloc]initWithFrame:CGRectMake(, , , )];//初始化背景
[self.imageview setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"bgimg.png" ofType:nil]]];
self.imageview.backgroundColor = [UIColor colorWithRed: green: blue: alpha:];
self.imageview.contentMode = UIViewContentModeScaleAspectFill;
self.imageview.userInteractionEnabled = true;
[self.view addSubview:self.imageview]; self.slider = [[UISlider alloc]initWithFrame:CGRectMake(, , , )];//初始化进度条
self.slider.value = 0.0;
[self.view addSubview:self.slider];
[self.slider addTarget:self action:@selector(updateValue) forControlEvents:UIControlEventValueChanged]; self.labellrc = [[UILabel alloc]initWithFrame:CGRectMake(, , , )];//初始化歌词显示label
self.labellrc.textColor = [UIColor whiteColor];
self.labellrc.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.2];
self.labellrc.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.labellrc]; self.tlablecur = [[UILabel alloc]initWithFrame:CGRectMake(, , , )];//初始化当前播放时间显示label
self.tlablecur.textColor = [UIColor whiteColor];
self.tlablecur.text = @"00:00";
self.tlablecur.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.tlablecur]; self.tlableall = [[UILabel alloc]initWithFrame:CGRectMake(, , , )];//初始化音乐总时间显示label
self.tlableall.textColor = [UIColor whiteColor];
self.tlableall.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.tlableall]; self.buttonPlayandPause = [[UIButton alloc]initWithFrame:CGRectMake(, ,, )];//初始化并插入开始and暂停按钮
[self.view addSubview:self.buttonPlayandPause];
[self.buttonPlayandPause setBackgroundImage:[UIImage imageNamed:@"start.png"] forState:UIControlStateNormal];
[self.buttonPlayandPause addTarget:self action:@selector(startandpause) forControlEvents:UIControlEventTouchUpInside]; self.buttonPrevious = [[UIButton alloc]initWithFrame:CGRectMake(, , , )];//初始化并插入上一曲按钮
[self.view addSubview:self.buttonPrevious];
[self.buttonPrevious setBackgroundImage:[UIImage imageNamed:@"previous.png"] forState:UIControlStateNormal];
[self.buttonPrevious addTarget:self action:@selector(previous) forControlEvents:UIControlEventTouchUpInside]; self.buttonNext = [[UIButton alloc]initWithFrame:CGRectMake(, , , )];//初始化并插入下一曲按钮
[self.view addSubview:self.buttonNext];
[self.buttonNext setBackgroundImage:[UIImage imageNamed:@"next.png"] forState:UIControlStateNormal];
[self.buttonNext addTarget:self action:@selector(next) forControlEvents:UIControlEventTouchUpInside]; [self addSource];//歌词 歌曲 图片 初始化
}
- (void)startandpause//设置按钮选项
{
if([self.player isPlaying])
{
[self.timer invalidate];
[self.player pause];
[self.buttonPlayandPause setBackgroundImage:[UIImage imageNamed:@"start.png"] forState:UIControlStateNormal];
}
else
{
[self.player play];
[self.buttonPlayandPause setBackgroundImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(timeadd) userInfo:nil repeats:YES];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(rotate) userInfo:nil repeats:YES];
}
}
- (void)playerclear//停止 管理所有的清零事件
{
self.indexLrc = ;//歌词指示变0
[self.player stop];//播放器停止
self.player.currentTime = ;//当前播放时间停止
[self.timer invalidate];//timer 停止
self.slider.value = ;//进度条清零
self.tlablecur.text = @"00:00";
self.labellrc.text = [NSString stringWithFormat:@"%@ : %@",self.lrc.ar,self.lrc.ti]; //歌词显示成标题+作者
}
- (void)addSource//更改歌曲资源
{
self.player= [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath: [[NSBundle mainBundle]pathForResource:[[self.musicListArray objectAtIndex:self.indexMusicList]valueForKey:@"music"] ofType:nil]]error:nil];//歌曲初始化
if(self.player == nil) //防止加载不到音乐文件
{
[self next] ;
return;
}
self.player.delegate = self;//设置委托回调
self.lrc = [[LyricsAnalysis alloc]initWithFileName:[[self.musicListArray objectAtIndex:self.indexMusicList]valueForKey:@"lyrics"] ofType:nil];//歌词初始化
NSString *imgUrlTemp = [[NSBundle mainBundle]pathForResource:[[self.musicListArray objectAtIndex:self.indexMusicList]valueForKey:@"picture"]ofType:nil];//检查图片路径
[self.musicImg setImage:[UIImage imageWithContentsOfFile:(imgUrlTemp ? imgUrlTemp : [[NSBundle mainBundle]pathForResource:@"noImg.png" ofType:nil])]];//设置图片
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];//设置总时间
[formatter setDateFormat:@"mm:ss"];
self.tlableall.text = [formatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:self.player.duration]];
self.labellrc.text = [NSString stringWithFormat:@"%@ - %@", self.lrc.ti , self.lrc.ar];//设置第一句歌词
}
- (void)previous//上一首
{
self.indexMusicList == ? self.indexMusicList = self.musicListArray.count - : self.indexMusicList-- ;//第一首自动切换到最后一首
[self playerclear];
[self addSource];
[self startandpause];
}
- (void)next//下一首
{
self.indexMusicList == (self.musicListArray.count - ) ? (self.indexMusicList = ) : self.indexMusicList++;//最后一首自动切换到第一首
[self playerclear];
[self addSource];
[self startandpause];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag//播放结束后 播放下一首
{
flag ? [self next]:nil;
}
- (void)timeadd//更新滚动条
{
self.slider.value = self.player.currentTime/self.player.duration;//进度条工作
[self setTLableCur];
self.indexLrc == self.lrc.lrcArrayTime.count ? self.labellrc.text = self.lrc.lrcArrayStr[self.indexLrc - ]:fabs([self.lrc.lrcArrayTime[self.indexLrc] doubleValue] - self.player.currentTime) < 0.06?self.labellrc.text = self.lrc.lrcArrayStr[self.indexLrc++]:nil; //判断歌词是不是全部播放完了,是就显示:最后一句歌词 不是 就判断是不是有哪句歌词是当前应该播放的(时间差小于0.05s)有就设置播放,没有就不做任何处理
}
-(void)rotate//图片旋转
{
CGAffineTransform t=CGAffineTransformRotate(self.musicImg.transform, 0.01);
self.musicImg.transform=t;
}
- (void)updateValue//拖动进度条动作
{
self.player.currentTime = self.player.duration * self.slider.value;
[self setTLableCur];
self.indexLrc = ;//歌词数组遍历完成了 或者 当前指向的歌词的播放时间 比 当前歌曲播放时间大;就跳出循环
while(self.indexLrc != self.lrc.lrcArrayTime.count && [self.lrc.lrcArrayTime[self.indexLrc] doubleValue] < self.player.currentTime)
{
self.indexLrc++;
}
self.labellrc.text = self.lrc.lrcArrayStr[self.indexLrc->-?self.indexLrc-:];//跳出循环的 就播放当前指向的前一句歌词
}
- (void)setTLableCur//设置当前播放时间
{
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"mm:ss"]; //格式化时间配置
self.tlablecur.text = [formatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:self.player.currentTime]]; //设置显示时间
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
知识点解析:
1、
#import "LyricsAnalysis.h"
自己手写的歌词解析类,可以查看我的上一篇博客去看看实现,记得按照下面的更新更新类里面的修改部分;
2、懒加载,用了下,感觉还行,具体的不会细讲,反正就是一种不用你管的自动运行的机制,想详细了解的同学,自己看,我只是声明下,以免有没见过的看见不认识,
3、
CGAffineTransform t=CGAffineTransformRotate(self.musicImg.transform, 0.01);
self.musicImg.transform=t;
实现图片旋转,系统提供的类,
4、图片遮盖实现免切图的圆形;
音乐播放的时候的图片,切图太麻烦,巧妙地利用背景图,将背景图置于歌曲专辑图的上方,留下一块圆形空白,于是看到的就是圆形图片了,很容易理解的逻辑
5、歌词匹配的基本原理,是歌词应该播放的时间与当前歌曲播放的时间的差的绝对值足够小
6、拖动进度条歌词从第一句开始匹配,一直找到适当的位置为止,
7、plist 文件应用。
由于博客园上传文件大小限制,此处连接为百度云盘连接 不保证持续有效
ios开发学习- 简易音乐播放器2 (基于iPhone4s屏幕尺寸)-- 歌词解析--plist文件应用--imageNamed图片加载耗内存的更多相关文章
- iso 开发学习--简易音乐播放器(基于iPhone4s屏幕尺寸)
三个按钮 一个进度条 贴图(软件中部分图片,来自网络,如果侵犯了您的权益,请联系我,会立刻撤下) 核心代码 // // ViewController.m // 08-10-MusicPlayer / ...
- ios开发:一个音乐播放器的设计与实现
github地址:https://github.com/wzpziyi1/MusicPlauer 这个Demo,关于歌曲播放的主要功能都实现了的.下一曲.上一曲,暂停,根据歌曲的播放进度动态滚动歌词, ...
- 简易音乐播放器主界面设计 - .NET CORE(C#) WPF开发
微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. 简易音乐播放器主界面设计 - .NET CORE(C#) WPF开发 阅读导航 本文背景 代码 ...
- 微信小程序(有始有终,全部代码)开发---跑步App+音乐播放器 Bug修复
开篇语 昨晚发了一篇: <简年15: 微信小程序(有始有终,全部代码)开发---跑步App+音乐播放器 > 然后上午起来吃完午饭之后,我就准备继续开工的,但是突然的,想要看B站.然后在一股 ...
- iOS图片加载到内存中占用内存情况
我的测试结果: 图片占用内存 图片尺寸 .png文件大小 1MB 512*512 316KB 4MB 10 ...
- IOS开发之简单音频播放器
今天第一次接触IOS开发的UI部分,之前学OC的时候一直在模拟的使用Target-Action回调模式,今天算是真正的用了一次.为了熟悉一下基本控件的使用方法,和UI部分的回调,下面开发了一个特别简易 ...
- 记一次酷狗音乐API的获取,感兴趣的可以自己封装开发自己的音乐播放器
1.本教程仅供个人学习用,禁止用于任何的商业和非法用途,如涉及版权问题请联系笔者删除. 2.随笔系作者原创文档,转载请注明文档来源:http://www.cnblogs.com/apresunday/ ...
- android全功能音乐播放器、基于MVP-Clean + Weex + RxJava2 + Retrofit + Dagger2 + MTRVA的综合应用、图片滤镜处理等源码
Android仿微信朋友圈查看图片下拽返回. Android图片滤镜处理,相机滤镜处理效果源码 Android自定义View源码:一个水平的进度条 基于MVP-Clean + Weex + RxJav ...
- iOS开发图片加载的内存问题及优化方案
原创作者:Magic-Unique 原文地址:https://github.com/Magic-Unique/HXImage猿吧 - 资源共享论坛: http://www.coderbar.cn 做最 ...
随机推荐
- const char*, char const* and char *const 分类: C/C++ OpenCV 2014-11-08 18:10 114人阅读 评论(0) 收藏
const char*, char const*, char*const的区别问题几乎是C++面试中每次都会有的题目. 事实上这个概念谁都有只是三种声明方式非常相似很容易记混. Bjarne在他的 ...
- android生成验证码bitmap
不多说了,直接上代码,项目中用到的,未做优化,还有很多参数未设置. [java] view plaincopy 1.import java.util.Random; 2. 3.import andro ...
- 四种数据持久化方式(下) :SQLite3 和 Core Data
在上文,我们介绍了iOS开发中的其中2种数据持久化方式:属性列表.归档解档. 本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运用: 在本节,将通过对4个文 ...
- TCP/IP协议原理与应用笔记01:OSI网络参考模型
1.OSI参考模型 第7层应用层:直接对应用程序提供服务,应用程序可以变化,但要包括电子消息传输 第6层表示层:格式化数据,以便为应用程序提供通用接口.这可以包括加密服务 第5层会话层:在两个 ...
- RHEL7安装配置TigerVNC
TigerVNC使用非加密的链接,默认会被firewalld blocked 掉,想要 vnc正常工作就需要让firewalld开放相应的端口才行. vnc默认的端口号为5900,而每个vnc win ...
- git 指令汇总
学习git过程中整理的笔记: git add 添加文件到暂存区: git commit -m "更改说明" 提交文件更改: git status 查看当前文件状态: git dif ...
- js 高阶函数 filter
filter用于过滤array中的一些值,通过带入的函数返回的ture 或false 保留或去除,返回一个新的array filter 使用演示:判断筛选出array中的素数: //判断素数自定义函数 ...
- ASP.NET 微信支付
一.在支付前期,我们需要获取用户的OpenId,此块内容只针对于JSAPI(微信中直接支付)才需要,如果生成二维码(NATIVE)扫描支付,请跳过此步骤 思路大致是:获取用户的code值 > 根 ...
- JAVA学习笔记--二
一.抽象类: 访问修饰符 abstract class 类名{ } 抽象类和普通类的区别: 1. 抽象类不能被实例化 2. 抽象类一般含有抽象方法 抽象方法:在抽象类中只有方法签名(方法声明),没有方 ...
- 14、SQL Server 存储过程
SQL Server 存储过程 存储过程类似函数,可以重复使用.相对于函数,存储过程拥有更强大的功能和更高的灵活性. 存储过程中可以包含逻辑控制语句和数据操作语句,可以接受参数,输出参数,返回单个值或 ...