zoukankan      html  css  js  c++  java
  • ios开发学习- 简易音乐播放器2 (基于iPhone4s屏幕尺寸)-- 歌词解析--plist文件应用--imageNamed图片加载耗内存

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

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

    知识点解析:

    1、

    #import "LyricsAnalysis.h"

    自己手写的歌词解析类,可以查看我的上一篇博客去看看实现,记得按照下面的更新更新类里面的修改部分;

    2、懒加载,用了下,感觉还行,具体的不会细讲,反正就是一种不用你管的自动运行的机制,想详细了解的同学,自己看,我只是声明下,以免有没见过的看见不认识,

    3、

    CGAffineTransform t=CGAffineTransformRotate(self.musicImg.transform, 0.01);

    self.musicImg.transform=t;

    实现图片旋转,系统提供的类,

    4、图片遮盖实现免切图的圆形;

    音乐播放的时候的图片,切图太麻烦,巧妙地利用背景图,将背景图置于歌曲专辑图的上方,留下一块圆形空白,于是看到的就是圆形图片了,很容易理解的逻辑

    5、歌词匹配的基本原理,是歌词应该播放的时间与当前歌曲播放的时间的差的绝对值足够小  

    6、拖动进度条歌词从第一句开始匹配,一直找到适当的位置为止,

    7、plist  文件应用。

    由于博客园上传文件大小限制,此处连接为百度云盘连接  不保证持续有效

    点我下载源码

  • 相关阅读:
    macOS 上配置 Lua
    Oracle.ManagedDataAccess.dll
    offer
    Costura.Fody
    日志系统
    实战框架ABP
    什么是算法?
    HTTP状态码->HTTP Status Code
    How to untar a TAR file using Apache Commons
    python实践3:cursor() — 数据库连接操作
  • 原文地址:https://www.cnblogs.com/kongkaikai/p/4752238.html
Copyright © 2011-2022 走看看