iOS-纯代码编写本地音乐播放器AVAudioPlayer

背景:天天听着网易云音乐,想着哪天要是自己能做一个类似网易云音乐的播放器就好了(大三还没毕业)。在CocoaChina代码库里面逛了有些日子了,就干脆下载几个音乐播放器的demo来练练手。实践结果告诉我:一个完整的播放器确实要做很多功能,确实有些难度。那么就开始说说我做的本地音乐播放器吧。


个人觉得吧,无论做什么项目或工程,都要先架构好再写,不然真的会很凌乱地。以前吧,我总是拿着东西就写,从不管什么架构,什么分层的。如果逮着某个部分就写,写到最后你会发现,你的代码耦合性太强了,不容易分离。当另一个控制器或者View层或者Model层要用到当前数据,不容易传递。(传递当然是可以传递的,只是逻辑看起来很别扭)。我个人还是比较喜欢先分好层,再写代码。当然也有人喜欢全部写好,再把每个部分分离出来,归类为不同的层。我更喜欢前者。


好啦,开始说说我整个工程的架构吧:

  • 采用MVC的模式来管理项目,层管理控件,View层显示控件,Model层处理数据。
  • 歌词界面归为View层(视图内的要显示东西太多,分离出来),其余控件在主控制器初始化显示。
  • 自定义UITableViewCell来显示歌词,并且用算法按照播放进度来显示歌词的颜色。
  • 有一些算法处理可以归为Category分类或者自己建一个工具类。

再说说这个工程里面的控件结构位置的概述吧:

第一个界面:

  • 模糊的背景里面是一个UIImageView,采用了高斯(毛玻璃)效果。中间那个圆圈图片也是一个UIImageView,并且修改他的Layer变成圆形。不难看出,这两个UIImageView 的图片是一样的,其实是从当前MP3音乐里面提取出来的。
  • 上面歌名和歌手是用两个UILabel来显示,信息也是从当前MP3歌曲里面提取出来的。
  • 下面有一个UISlider来控制歌曲播放进度。
  • 还有两个UILabel分别来显示当前播放时间和歌曲总时长,歌曲里面提取出来的总时长是时间戳NSTimeInterval的单位,我们用算法格式化转发为我们熟知的时间格式。
  • 最下面自然是三个UIButton,来控制歌曲的播放暂停、上一曲、下一曲。

    第二个界面:

  • 显示歌词的部分,使用一个UIScrollView作为父视图。真正显示歌词的部分是一个自定义cellUITableView。这个UIScrollViewcontentSize有两个屏幕宽度,UITableView放在第二个屏幕宽度的位置,效果就是:向右滑动就到歌词界面。

  • 继承UILabelZFLabel,并增加一个进度属性,按照当前歌曲进度播放来绘制这个UILabel的颜色(即播放到哪里,歌词颜色就显示到哪里)。把这个ZFLabel作为自定义的cell
  • 第一个界面其实还有一个当前歌词的显示,其实也就是让他等于当前歌词显示的ZFLabel而已。

除此之外,本工程用了两个计时器。第一个计时器为NSTimer,用来更新第一个界面的播放时间。第二个计时器为CADisplayLink,用来更新歌词。为什么要用两个不一样的计时器?第一个计时器NSTimer我就不多说了,相信大家用得最多。第二个计时器不需要设置时间,每秒有固定的调用频率,而且调用精确度相当高,比NSTimer高。因为要显示歌词嘛,为了不出现卡顿的现象,就采用CADisplayLink计时器。

至于播放器类,当然是用系统的类AVAudioPlayer啦。一方面,我喜欢原生开发。另一方面,把系统的学会了,第三方的也是基于系统的嘛,学起来也很容易的。

iOS-纯代码编写本地音乐播放器AVAudioPlayer_第1张图片

iOS-纯代码编写本地音乐播放器AVAudioPlayer_第2张图片


对音频最大的认识:

每个MP3里面都已经录制好了这首歌的信息,比如:歌曲图片(被我提取出来用来显示高斯效果和中央旋转图)、歌手、歌曲名字、专辑名称。

我们可以用AVURLAssetAVMetadataItem提取出歌曲里面的信息。

代码:

#import 
#import 

@interface AssetModel : NSObject

/**图片*/
@property(nonatomic,strong) UIImage *image;
/**歌曲名*/
@property(nonatomic,strong) NSString *songName;
/**歌手*/
@property(nonatomic,strong) NSString *artist;
/**专辑名称*/
@property(nonatomic,strong) NSString *albumName;


/**
 初始化歌曲的信息,包括歌曲的图片、歌曲名、歌手、专辑名称信息

 @param url 歌曲的url路径
 @return 初始化好的对象
 */
+(AssetModel *)AssetModelWithURL:(NSURL *)url;
-(AssetModel *)initAssetWithURL:(NSURL *)url;

@end
#import "AssetModel.h"

@implementation AssetModel

+(AssetModel *)AssetModelWithURL:(NSURL *)url
{
    return [[self alloc] initAssetWithURL:url];
}


-(AssetModel *)initAssetWithURL:(NSURL *)url
{
        AVURLAsset *mp3Asset = [AVURLAsset URLAssetWithURL:url options:nil];

        for (NSString *format in [mp3Asset availableMetadataFormats]) {
            for (AVMetadataItem *metadataItem in [mp3Asset metadataForFormat:format]) {
                if ([metadataItem.commonKey isEqual:@"artwork"]) {
                    //提取图片
                    self.image = [UIImage imageWithData:(NSData *)metadataItem.value];
                }
                else if ([metadataItem.commonKey isEqualToString:@"title"])
                {
                    //提取歌曲名
                    self.songName = (NSString *)metadataItem.value;
                }
                else if ([metadataItem.commonKey isEqualToString:@"artist"])
                {
                    //提取歌手
                    self.artist = (NSString *)metadataItem.value;
                }
                else if ([metadataItem.commonKey isEqualToString:@"albumName"])
                {
                    //提取专辑名称
                    self.albumName = (NSString *)metadataItem.value;
                }
            }
        }
    return self;
}

@end

对动画的最大认识:

CoreAnimation里面有四种:基础动画、帧动画、转场动画、组动画。而该工程只是用到了基础动画CABasicAnimation。点击播放音乐时候,就让中央旋转图开始沿着Z轴方向旋转。当然,要设置中央旋转图(UIImageView)的旋转时间、旋转角度之类的。

以上就是我这几天写该工程的心得~~~

详细代码:https://github.com/HZhenF/MyMusicPlayer.git

你可能感兴趣的:(iOS-视频音频多媒体)