声明:(部分图片来自网络,如果侵犯了您的权益请联系我,会尽快删除!)

又是音乐播放器,不过这次和上次不一样了,准确说这次更像播放器了,初学者不建议看这个,可以先看前面一个音乐播放器(1),当然 我没加1,写了这个,就把前面的默认当1吧

先上图:

接下来源码:(一样:大量的三元式,多看看就习惯了,主要是习惯一行能干的事绝不用两行);

  1. //
  2. // ViewController.m
  3. // C_MusicPlayer
  4. //
  5. // Created by Ibokan on 15/8/22.
  6. // Copyright (c) 2015年 Crazy凡. All rights reserved.
  7. //
  8.  
  9. #import "ViewController.h"
  10. #import <AVFoundation/AVFoundation.h>
  11. #import "LyricsAnalysis.h"
  12.  
  13. @interface ViewController () <AVAudioPlayerDelegate>
  14. @property (nonatomic,strong)UIImageView *imageview;//bgimg
  15. @property (nonatomic,strong)UISlider *slider;//播放进度条
  16. @property (nonatomic,strong)UILabel *tlableall;//音乐总时长
  17. @property (nonatomic,strong)UILabel *tlablecur;//音乐当前播放时长
  18. @property (nonatomic,strong)UILabel *labellrc;//歌词显示label
  19.  
  20. @property (nonatomic,strong)UIButton *buttonPlayandPause;
  21. @property (nonatomic,strong)UIButton *buttonPrevious;
  22. @property (nonatomic,strong)UIButton *buttonNext;
  23. @property (nonatomic,strong)AVAudioPlayer *player;
  24. @property (nonatomic,strong)LyricsAnalysis *lrc;
  25. @property (nonatomic,strong)UIImageView *musicImg;
  26. @property (nonatomic,strong)NSTimer *timer;//计时器
  27. @property (nonatomic,strong)NSMutableArray *musicListArray;//歌曲列表
  28.  
  29. @property int indexLrc;//歌词播放指向
  30. @property int indexMusicList;//歌曲播放指向
  31.  
  32. //@property (nonatomic,strong)UIScrollView * scrollview;
  33. @end
  34.  
  35. @implementation ViewController
  36.  
  37. - (NSArray *)musicListArray//初始化歌曲列表 : 懒加载
  38. {
  39. if(!_musicListArray)
  40. {
  41. _musicListArray = [NSMutableArray arrayWithArray:[NSArray arrayWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"Music.plist" ofType:nil]]];
  42. for(NSDictionary *temp in _musicListArray)//屏蔽无效路径
  43. {
  44. [[NSBundle mainBundle]pathForResource:[temp valueForKey:@"music"] ofType:nil] ? nil:[_musicListArray removeObject:temp];
  45. }
  46. }
  47. return _musicListArray;
  48. }
  49.  
  50. - (void)viewDidLoad {
  51. [super viewDidLoad];
  52. // Do any additional setup after loading the view, typically from a nib.
  53.  
  54. self.indexLrc = ;
  55. self.indexMusicList = ;
  56.  
  57. self.musicImg = [[UIImageView alloc]initWithFrame:CGRectMake(, , , )];//初始化歌曲图片
  58. self.musicImg.backgroundColor = [UIColor groupTableViewBackgroundColor];
  59. self.musicImg.contentMode = UIViewContentModeScaleAspectFill;
  60. [self.view addSubview:self.musicImg];
  61.  
  62. self.imageview = [[UIImageView alloc]initWithFrame:CGRectMake(, , , )];//初始化背景
  63. [self.imageview setImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"bgimg.png" ofType:nil]]];
  64. self.imageview.backgroundColor = [UIColor colorWithRed: green: blue: alpha:];
  65. self.imageview.contentMode = UIViewContentModeScaleAspectFill;
  66. self.imageview.userInteractionEnabled = true;
  67. [self.view addSubview:self.imageview];
  68.  
  69. self.slider = [[UISlider alloc]initWithFrame:CGRectMake(, , , )];//初始化进度条
  70. self.slider.value = 0.0;
  71. [self.view addSubview:self.slider];
  72. [self.slider addTarget:self action:@selector(updateValue) forControlEvents:UIControlEventValueChanged];
  73.  
  74. self.labellrc = [[UILabel alloc]initWithFrame:CGRectMake(, , , )];//初始化歌词显示label
  75. self.labellrc.textColor = [UIColor whiteColor];
  76. self.labellrc.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.2];
  77. self.labellrc.textAlignment = NSTextAlignmentCenter;
  78. [self.view addSubview:self.labellrc];
  79.  
  80. self.tlablecur = [[UILabel alloc]initWithFrame:CGRectMake(, , , )];//初始化当前播放时间显示label
  81. self.tlablecur.textColor = [UIColor whiteColor];
  82. self.tlablecur.text = @"00:00";
  83. self.tlablecur.textAlignment = NSTextAlignmentCenter;
  84. [self.view addSubview:self.tlablecur];
  85.  
  86. self.tlableall = [[UILabel alloc]initWithFrame:CGRectMake(, , , )];//初始化音乐总时间显示label
  87. self.tlableall.textColor = [UIColor whiteColor];
  88. self.tlableall.textAlignment = NSTextAlignmentCenter;
  89. [self.view addSubview:self.tlableall];
  90.  
  91. self.buttonPlayandPause = [[UIButton alloc]initWithFrame:CGRectMake(, ,, )];//初始化并插入开始and暂停按钮
  92. [self.view addSubview:self.buttonPlayandPause];
  93. [self.buttonPlayandPause setBackgroundImage:[UIImage imageNamed:@"start.png"] forState:UIControlStateNormal];
  94. [self.buttonPlayandPause addTarget:self action:@selector(startandpause) forControlEvents:UIControlEventTouchUpInside];
  95.  
  96. self.buttonPrevious = [[UIButton alloc]initWithFrame:CGRectMake(, , , )];//初始化并插入上一曲按钮
  97. [self.view addSubview:self.buttonPrevious];
  98. [self.buttonPrevious setBackgroundImage:[UIImage imageNamed:@"previous.png"] forState:UIControlStateNormal];
  99. [self.buttonPrevious addTarget:self action:@selector(previous) forControlEvents:UIControlEventTouchUpInside];
  100.  
  101. self.buttonNext = [[UIButton alloc]initWithFrame:CGRectMake(, , , )];//初始化并插入下一曲按钮
  102. [self.view addSubview:self.buttonNext];
  103. [self.buttonNext setBackgroundImage:[UIImage imageNamed:@"next.png"] forState:UIControlStateNormal];
  104. [self.buttonNext addTarget:self action:@selector(next) forControlEvents:UIControlEventTouchUpInside];
  105.  
  106. [self addSource];//歌词 歌曲 图片 初始化
  107. }
  108. - (void)startandpause//设置按钮选项
  109. {
  110. if([self.player isPlaying])
  111. {
  112. [self.timer invalidate];
  113. [self.player pause];
  114. [self.buttonPlayandPause setBackgroundImage:[UIImage imageNamed:@"start.png"] forState:UIControlStateNormal];
  115. }
  116. else
  117. {
  118. [self.player play];
  119. [self.buttonPlayandPause setBackgroundImage:[UIImage imageNamed:@"pause.png"] forState:UIControlStateNormal];
  120. self.timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(timeadd) userInfo:nil repeats:YES];
  121. self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(rotate) userInfo:nil repeats:YES];
  122. }
  123. }
  124. - (void)playerclear//停止 管理所有的清零事件
  125. {
  126. self.indexLrc = ;//歌词指示变0
  127. [self.player stop];//播放器停止
  128. self.player.currentTime = ;//当前播放时间停止
  129. [self.timer invalidate];//timer 停止
  130. self.slider.value = ;//进度条清零
  131. self.tlablecur.text = @"00:00";
  132. self.labellrc.text = [NSString stringWithFormat:@"%@ : %@",self.lrc.ar,self.lrc.ti]; //歌词显示成标题+作者
  133. }
  134. - (void)addSource//更改歌曲资源
  135. {
  136. self.player= [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath: [[NSBundle mainBundle]pathForResource:[[self.musicListArray objectAtIndex:self.indexMusicList]valueForKey:@"music"] ofType:nil]]error:nil];//歌曲初始化
  137. if(self.player == nil) //防止加载不到音乐文件
  138. {
  139. [self next] ;
  140. return;
  141. }
  142. self.player.delegate = self;//设置委托回调
  143. self.lrc = [[LyricsAnalysis alloc]initWithFileName:[[self.musicListArray objectAtIndex:self.indexMusicList]valueForKey:@"lyrics"] ofType:nil];//歌词初始化
  144. NSString *imgUrlTemp = [[NSBundle mainBundle]pathForResource:[[self.musicListArray objectAtIndex:self.indexMusicList]valueForKey:@"picture"]ofType:nil];//检查图片路径
  145. [self.musicImg setImage:[UIImage imageWithContentsOfFile:(imgUrlTemp ? imgUrlTemp : [[NSBundle mainBundle]pathForResource:@"noImg.png" ofType:nil])]];//设置图片
  146. NSDateFormatter *formatter = [[NSDateFormatter alloc]init];//设置总时间
  147. [formatter setDateFormat:@"mm:ss"];
  148. self.tlableall.text = [formatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:self.player.duration]];
  149. self.labellrc.text = [NSString stringWithFormat:@"%@ - %@", self.lrc.ti , self.lrc.ar];//设置第一句歌词
  150. }
  151. - (void)previous//上一首
  152. {
  153. self.indexMusicList == ? self.indexMusicList = self.musicListArray.count - : self.indexMusicList-- ;//第一首自动切换到最后一首
  154. [self playerclear];
  155. [self addSource];
  156. [self startandpause];
  157. }
  158. - (void)next//下一首
  159. {
  160. self.indexMusicList == (self.musicListArray.count - ) ? (self.indexMusicList = ) : self.indexMusicList++;//最后一首自动切换到第一首
  161. [self playerclear];
  162. [self addSource];
  163. [self startandpause];
  164. }
  165. - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag//播放结束后 播放下一首
  166. {
  167. flag ? [self next]:nil;
  168. }
  169. - (void)timeadd//更新滚动条
  170. {
  171. self.slider.value = self.player.currentTime/self.player.duration;//进度条工作
  172. [self setTLableCur];
  173. 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)有就设置播放,没有就不做任何处理
  174. }
  175. -(void)rotate//图片旋转
  176. {
  177. CGAffineTransform t=CGAffineTransformRotate(self.musicImg.transform, 0.01);
  178. self.musicImg.transform=t;
  179. }
  180. - (void)updateValue//拖动进度条动作
  181. {
  182. self.player.currentTime = self.player.duration * self.slider.value;
  183. [self setTLableCur];
  184. self.indexLrc = ;//歌词数组遍历完成了 或者 当前指向的歌词的播放时间 比 当前歌曲播放时间大;就跳出循环
  185. while(self.indexLrc != self.lrc.lrcArrayTime.count && [self.lrc.lrcArrayTime[self.indexLrc] doubleValue] < self.player.currentTime)
  186. {
  187. self.indexLrc++;
  188. }
  189. self.labellrc.text = self.lrc.lrcArrayStr[self.indexLrc->-?self.indexLrc-:];//跳出循环的 就播放当前指向的前一句歌词
  190. }
  191. - (void)setTLableCur//设置当前播放时间
  192. {
  193. NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
  194. [formatter setDateFormat:@"mm:ss"]; //格式化时间配置
  195. self.tlablecur.text = [formatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:self.player.currentTime]]; //设置显示时间
  196. }
  197. - (void)didReceiveMemoryWarning {
  198. [super didReceiveMemoryWarning];
  199. // Dispose of any resources that can be recreated.
  200. }
  201. @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图片加载耗内存的更多相关文章

  1. iso 开发学习--简易音乐播放器(基于iPhone4s屏幕尺寸)

    三个按钮  一个进度条 贴图(软件中部分图片,来自网络,如果侵犯了您的权益,请联系我,会立刻撤下) 核心代码 // // ViewController.m // 08-10-MusicPlayer / ...

  2. ios开发:一个音乐播放器的设计与实现

    github地址:https://github.com/wzpziyi1/MusicPlauer 这个Demo,关于歌曲播放的主要功能都实现了的.下一曲.上一曲,暂停,根据歌曲的播放进度动态滚动歌词, ...

  3. 简易音乐播放器主界面设计 - .NET CORE(C#) WPF开发

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. 简易音乐播放器主界面设计 - .NET CORE(C#) WPF开发 阅读导航 本文背景 代码 ...

  4. 微信小程序(有始有终,全部代码)开发---跑步App+音乐播放器 Bug修复

    开篇语 昨晚发了一篇: <简年15: 微信小程序(有始有终,全部代码)开发---跑步App+音乐播放器 > 然后上午起来吃完午饭之后,我就准备继续开工的,但是突然的,想要看B站.然后在一股 ...

  5. iOS图片加载到内存中占用内存情况

    我的测试结果: 图片占用内存   图片尺寸           .png文件大小 1MB              512*512          316KB 4MB              10 ...

  6. IOS开发之简单音频播放器

    今天第一次接触IOS开发的UI部分,之前学OC的时候一直在模拟的使用Target-Action回调模式,今天算是真正的用了一次.为了熟悉一下基本控件的使用方法,和UI部分的回调,下面开发了一个特别简易 ...

  7. 记一次酷狗音乐API的获取,感兴趣的可以自己封装开发自己的音乐播放器

    1.本教程仅供个人学习用,禁止用于任何的商业和非法用途,如涉及版权问题请联系笔者删除. 2.随笔系作者原创文档,转载请注明文档来源:http://www.cnblogs.com/apresunday/ ...

  8. android全功能音乐播放器、基于MVP-Clean + Weex + RxJava2 + Retrofit + Dagger2 + MTRVA的综合应用、图片滤镜处理等源码

    Android仿微信朋友圈查看图片下拽返回. Android图片滤镜处理,相机滤镜处理效果源码 Android自定义View源码:一个水平的进度条 基于MVP-Clean + Weex + RxJav ...

  9. iOS开发图片加载的内存问题及优化方案

    原创作者:Magic-Unique 原文地址:https://github.com/Magic-Unique/HXImage猿吧 - 资源共享论坛: http://www.coderbar.cn 做最 ...

随机推荐

  1. 搭建docker私有仓库 笔记

    抄送消息到企业微圈 avalon组件 twitterCopy/twitterCopy 说明 说明 说明 说明 说明 说明 该组件提供接口 开发者可以吧 有需要分享到微圈的的信息 发布到微圈中去. 应用 ...

  2. javascript中涉及到汉字的比较

    在使用js中的"=="进行字符串的比较时,发现在英文情况下是ok的,但在中文比较时则不行了. 在网上搜索,提供了一个解决方法,使用 stringObject.localeCompa ...

  3. Linux - CentOS6.5服务器搭建与初始化配置详解(上)

    1.新建一个虚拟机 选择典型 单机下一步 p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm 0cm 0.0001pt; text-align: ...

  4. js request

    比如你要获取aaa.aspx?id=2 使用方法为:var id= request('id'); 

  5. 设计模式学习——准备(UML类图)

    前言 其实吧,最早接触UML是源于软件设计师的考试,半路出家实在难为我了.学设计模式总是要画类图的,所以补充UML的类图的知识是很重要滴.第一篇就偷懒一点copy别人的东西了.实话说,我们都是踩在巨人 ...

  6. U3D 脚本添加和获得对象

    有时候,一开始可能没有对象,而是由于某种触发,产生的一个对象,这里讲解下,如何通过脚本来创建一个对象: 这是通过脚本创建一个立方体: using UnityEngine; using System.C ...

  7. WisDom.Net 框架设计(一) 总体框架

    WisDom.Net总体框架 1.目标 WisDom.Net  做为以后快速开发相关的软件的基础框架,实现用户,权限,角色,菜单,和工作流的管理功能.相关功能可以独立使用,快速用于其他程序的开发.预计 ...

  8. kvc简单实现

      除了一般的赋值和取值的方法,我们还可以用Key-Value-Coding(KVC)键值编码来访问你要存取的类的属性 kvc: kvc    key value coding 键值对编码 可以通过 ...

  9. 确认(confirm 消息对话框)

    confirm 消息对话框通常用于允许用户做选择的动作(包括一个确定按钮和一个取消按钮). 语法: confirm(str) str:在消息对话框中要显示的文本 返回值: 当用户点击"确定& ...

  10. String 方法

    import java.lang.*; /** * 1.查找"asdfjvjadsffvaadfkfasaffdsasdffadsafafsafdadsfaafd" * 该字符串中 ...