Podfile
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'SCMusic' do
# Comment the next line if you're not using Swift and don' t want to use dynamic frameworks
use_frameworks!
# Pods for SCMusic
pod 'AFNetworking' , '~> 3.0'
pod 'Masonry'
pod 'MBProgressHUD'
pod 'MJExtension'
pod 'MJRefresh'
end
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "AFNetworking.h"
#import "MJExtension.h"
#import "OMHotSongInfo.h"
#import "OMSongInfo.h"
@interface MusicDownloader : NSObject
@property (nonatomic , assign ) BOOL isDataRequestFinish;
@property (nonatomic , strong ) OMHotSongInfo *hotSonginfo;
@property (nonatomic , copy) void (^completionHandler)(void );
@property (nonatomic , strong ) OMSongInfo *songInfo;
-(void ) requestData: (NSString *)urlString ;
- (void )startDownload;
- (void )cancelDownload;
@end
#import <UIKit/UIKit.h>
#import "MusicDownloader.h"
#import <AFNetworking/AFNetworking.h>
#import "MJExtension/MJExtension.h"
#import "OMHotSongInfo.h"
#import "OMSongInfo.h"
#define kAppIconSize 48
@interface MusicDownloader ()
@property (nonatomic , strong ) NSOperationQueue *queue;
@property (nonatomic , strong ) NSURLSessionDataTask *sessionTask;
@end
@implementation MusicDownloader
-(instancetype) init {
self = [super init];
if (self ) {
_songInfo = OMSongInfo.sharedManager ;
}
return self ;
}
- (void )startDownload
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:self .hotSonginfo .pic_small ]];
_sessionTask = [[NSURLSession sharedSession] dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error != nil )
{
if ([error code] == NSURLErrorAppTransportSecurityRequiresSecureConnection)
{
abort();
}
}
[[NSOperationQueue mainQueue] addOperationWithBlock: ^{
UIImage *image = [[UIImage alloc] initWithData:data];
if (image.size .width != kAppIconSize || image.size .height != kAppIconSize)
{
CGSize itemSize = CGSizeMake(kAppIconSize, kAppIconSize);
UIGraphicsBeginImageContextWithOptions(itemSize, NO , 0.0 f);
CGRect imageRect = CGRectMake(0.0 , 0.0 , itemSize.width , itemSize.height );
[image drawInRect:imageRect];
self .hotSonginfo .albumImage_small = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
else
{
self .hotSonginfo .albumImage_small = image;
}
if (self .completionHandler != nil )
{
self .completionHandler ();
}
}];
}];
[self .sessionTask resume];
}
- (void )cancelDownload
{
[self .sessionTask cancel];
_sessionTask = nil ;
}
- (void )handleError:(NSError *)error
{
NSString *errorMessage = [error localizedDescription];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Cannot Show Top Paid Apps"
message:errorMessage
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *OKAction = [UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
}];
[alert addAction:OKAction];
}
@end
MusicPlayerManager.h
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
@interface MusicPlayerManager : NSObject
typedef enum : NSUInteger {
RepeatPlayMode,
RepeatOnlyOnePlayMode,
ShufflePlayMode,
} ShuffleAndRepeatState;
@property (nonatomic ,strong ) AVPlayer *play;
@property (nonatomic ,strong ) AVPlayerItem *playItem;
@property (nonatomic ,assign ) ShuffleAndRepeatState shuffleAndRepeatState;
@property (nonatomic ,assign ) NSInteger playingIndex;
+ (MusicPlayerManager *)sharedManager;
-(void ) setPlayItem: (NSString *)songURL;
-(void ) setPlay;
-(void ) startPlay;
-(void ) stopPlay;
-(void ) play: (NSString *)songURL;
@end
MusicPlayerManager.m
#import "MusicPlayerManager.h"
@implementation MusicPlayerManager
static MusicPlayerManager *_sharedManager = nil ;
+(MusicPlayerManager *)sharedManager {
@synchronized( [MusicPlayerManager class] ){
if (!_sharedManager)
_sharedManager = [[self alloc] init];
return _sharedManager;
}
return nil ;
}
-(void ) setPlayItem: (NSString *)songURL {
NSURL * url = [NSURL URLWithString:songURL];
_playItem = [[AVPlayerItem alloc] initWithURL:url];
}
-(void ) setPlay {
_play = [[AVPlayer alloc] initWithPlayerItem:_playItem];
}
-(void ) startPlay {
[_play play];
}
-(void ) stopPlay {
[_play pause];
}
-(void ) play: (NSString *)songURL {
[self setPlayItem:songURL];
[self setPlay];
[self startPlay];
}
@end
AppDelegate.h
AppDelegate.m
#import "AppDelegate.h"
#import "RootViewController.h"
#import "NavigationViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import <notify.h>
#import "ContentTableViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL )application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self .window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds ];
self .window .backgroundColor = [UIColor whiteColor];
self .window .rootViewController = [[NavigationViewController alloc] initWithRootViewController:[[RootViewController alloc] init]];
[self .window makeKeyAndVisible];
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setActive:YES error:nil ];
[session setCategory:AVAudioSessionCategoryPlayback error:nil ];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
return YES ;
}
NavigationViewController.h
#import <UIKit/UIKit.h>
#import "RootViewController.h"
@interface NavigationViewController : UINavigationController
@end
NavigationViewController.m
#import "NavigationViewController.h"
@implementation NavigationViewController
#pragma mark - viewDidLoad
- (void )viewDidLoad {
[super viewDidLoad];
[self navigationBarSettting];
}
- (void )didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void ) navigationBarSettting {
[self .navigationBar setBarTintColor:UIColorFromRGB(0xff0000 )];
[self .navigationBar setTranslucent:NO ];
[self .navigationBar setTintColor:[UIColor whiteColor]];
[self .navigationBar setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], NSForegroundColorAttributeName, nil ]];
[self .navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
[self .navigationBar setShadowImage:[[UIImage alloc] init]];
}
@end
RootViewController.h
#import <UIKit/UIKit.h>
#import "AFNetworking.h"
#import "MJExtension.h"
#import "OMHotSongInfo.h"
#import "OMSongInfo.h"
#import "MusicPlayerManager.h"
#import "OMHotSongInfo.h"
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
#import <notify.h>
#import "SCImageView.h"
#import "DetailControlViewController.h"
#import "Const.h"
#import "TTTopChannelContianerView.h"
#import "ContentTableViewController.h"
#import "Masonry.h"
@interface RootViewController : UIViewController <UIScrollViewDelegate ,TTTopChannelContianerViewDelegate >
@property (nonatomic , strong ) NSMutableArray *currentChannelsArray;
@property (nonatomic , weak ) TTTopChannelContianerView *topContianerView;
@property (nonatomic , strong ) DetailControlViewController *detailController;
@property (nonatomic , weak ) UIScrollView *contentScrollView;
@property (nonatomic , strong ) NSArray *arrayLists;
@property (nonatomic ,assign ) NSInteger currentRow;
@property (nonatomic , strong ) UIImageView * lrcImageView;
@property (nonatomic , strong ) UIImage * lastImage;
@property (nonatomic , strong ) UIView *playControllerView;
@property (nonatomic , strong ) SCImageView *currentPlaySongImage;
@property (nonatomic , strong ) UIButton *playAndPauseButton;
@property (nonatomic , strong ) UIButton *nextSongButton;
@property (nonatomic , strong ) UISlider *songSlider;
@property (nonatomic , strong ) UILabel *songName;
@property (nonatomic , strong ) UILabel *singerName;
@property (nonatomic , strong ) id playerTimeObserver;
@end
RootViewController.m
#import "RootViewController.h"
MusicPlayerManager *musicPlayer
OMSongInfo *songInfo
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad]
// 设置导航栏title
self.title = @"SCMusic"
musicPlayer = MusicPlayerManager.sharedManager
songInfo = OMSongInfo.sharedManager
// 设置Subview
[self setupSubview]
// 锁屏播放设置
[self createRemoteCommandCenter]
// 设置KVO
[songInfo addObserver:self forKeyPath:@"playSongIndex" options:NSKeyValueObservingOptionOld
|NSKeyValueObservingOptionNew context:nil]
[songInfo addObserver:self forKeyPath:@"isDataRequestFinish" options:NSKeyValueObservingOptionOld
|NSKeyValueObservingOptionNew context:nil]
[musicPlayer addObserver:self forKeyPath:@"finishPlaySongIndex" options:NSKeyValueObservingOptionOld
|NSKeyValueObservingOptionNew context:nil]
// Notification
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(playSongSetting)
name: @"repeatPlay"
object: nil]
// 播放遇到中断,比如电话进来
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onAudioSessionEvent:) name:AVAudioSessionInterruptionNotification object:nil]
}
-(void)viewDidAppear:(BOOL)animated {
[self playStateRecover]
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]
// Dispose of any resources that can be recreated.
}
#pragma mark - setupSubview
-(void) setupSubview {
// 初始化detailController
_detailController = [[DetailControlViewController alloc] init]
// 主页控制View
_playControllerView = [[UIView alloc] initWithFrame:CGRectMake(0 , CGRectGetHeight(self.view .frame ) * 0.92 - CGRectGetHeight(self.navigationController .navigationBar .frame ), CGRectGetWidth(self.view .frame ), CGRectGetHeight(self.view .frame ) * 0.08 )]
_playControllerView.backgroundColor = UIColorFromRGB(0xff0000 )
_playControllerView.userInteractionEnabled = YES
[self.view bringSubviewToFront:_playControllerView]
[self.view addSubview:_playControllerView]
[_playControllerView mas_makeConstraints:^(MASConstraintMaker *make) {
make.bottom .equalTo (self.view .mas _bottom).with .offset (0 )
make.left .equalTo (self.view .mas _left).with .offset (0 )
make.right .equalTo (self.view .mas _right).with .offset (0 )
make.width .mas _equalTo(CGRectGetWidth(self.view .frame ))
make.height .mas _equalTo(CGRectGetHeight(self.view .frame ) * 0.08 )
}]
// 专辑图片
_currentPlaySongImage = [[SCImageView alloc] initWithFrame:CGRectMake(_playControllerView.frame .size .height * 0.1 , -_playControllerView.frame .size .height * 0.2 , _playControllerView.frame .size .height * 1.1 , _playControllerView.frame .size .height * 1.1 )]
_currentPlaySongImage.image = [UIImage imageNamed:@"cm2_simple_defaut_album_image" ]
_currentPlaySongImage.clipsToBounds = true
_currentPlaySongImage.layer .cornerRadius = _playControllerView.frame .size .height * 0.55
[_playControllerView addSubview:_currentPlaySongImage]
_currentPlaySongImage.userInteractionEnabled = YES
UITapGestureRecognizer *tag = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(jumpToDeitalController)]
[_currentPlaySongImage addGestureRecognizer:tag]
//播放控制
_playAndPauseButton = [[UIButton alloc] initWithFrame:CGRectMake(_playControllerView.frame .size .width * 0.75 , _playControllerView.frame .size .height * 0.25 , _playControllerView.frame .size .height * 0.65 , _playControllerView.frame .size .height * 0.65 )]
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause" ] forState:UIControlStateNormal]
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause_prs" ] forState:UIControlStateHighlighted]
[_playAndPauseButton addTarget:self action:@selector(playAndPauseButtonAction:) forControlEvents:UIControlEventTouchUpInside]
[_playControllerView addSubview:_playAndPauseButton]
_nextSongButton = [[UIButton alloc] initWithFrame:CGRectMake(_playControllerView.frame .size .width * 0.88 , _playControllerView.frame .size .height * 0.25 , _playControllerView.frame .size .height * 0.65 , _playControllerView.frame .size .height * 0.65 )]
[_nextSongButton setImage:[UIImage imageNamed:@"cm2_fm_btn_next" ] forState:UIControlStateNormal]
[_nextSongButton setImage:[UIImage imageNamed:@"cm2_fm_btn_next_prs" ] forState:UIControlStateHighlighted]
[_nextSongButton addTarget:self action:@selector(nextButtonAction:) forControlEvents:UIControlEventTouchUpInside]
[_playControllerView addSubview:_nextSongButton]
// 歌曲进度条
_songSlider = [[UISlider alloc] initWithFrame:CGRectMake(_playControllerView.frame .size .height * 1.3 , 0 , _playControllerView.frame .size .width - _playControllerView.frame .size .height * 1.3 , _playControllerView.frame .size .height * 0.3 )]
[_songSlider setThumbImage:[UIImage imageNamed:@"cm2_simple_knob_nomal" ] forState:UIControlStateNormal]
[_songSlider setThumbImage:[UIImage imageNamed:@"cm2_simple_knob_prs" ] forState:UIControlStateHighlighted]
_songSlider.tintColor = UIColorFromRGB(0xffffff )
//设置slider响应事件
[_songSlider addTarget:self //事件委托对象
action:@selector(playbackSliderValueChanged) //处理事件的方法
forControlEvents:UIControlEventValueChanged//具体事件
]
[_songSlider addTarget:self //事件委托对象
action:@selector(playbackSliderValueChangedFinish) //处理事件的方法
forControlEvents:UIControlEventTouchUpInside//具体事件
]
[_playControllerView addSubview:_songSlider]
// 歌名和歌手名
_songName = [[UILabel alloc] initWithFrame:CGRectMake(_playControllerView.frame .size .height * 1.3 , _playControllerView.frame .size .height * 0.3 , _playControllerView.frame .size .width * 0.5 , _playControllerView.frame .size .height * 0.3 )]
// songName.backgroundColor = [UIColor blackColor]
_songName.text = @"Unkown"
_songName.textColor = [UIColor whiteColor]
_songName.font = [UIFont systemFontOfSize:16.0 ]
[_playControllerView addSubview:_songName]
_singerName = [[UILabel alloc] initWithFrame:CGRectMake(_playControllerView.frame .size .height * 1.3 , _playControllerView.frame .size .height * 0.7 , _playControllerView.frame .size .width * 0.5 , _playControllerView.frame .size .height * 0.2 )]
// singerName.backgroundColor = [UIColor blackColor]
_singerName.text = @"Unkown"
_singerName.textColor = [UIColorFromRGB(0xfafafa ) colorWithAlphaComponent:0.95 ]
_singerName.font = [UIFont systemFontOfSize:13.0 ]
[_playControllerView addSubview:_singerName]
[self.view addSubview:_playControllerView]
self.automaticallyAdjustsScrollViewInsets = NO
[self setupTopContianerView]
[self setupChildController]
[self setupContentScrollView]
}
#pragma mark - 初始化子控制器
-(void)setupChildController {
for (NSInteger i = 0
ContentTableViewController *viewController = [[ContentTableViewController alloc] init]
viewController.channelTitle = self.currentChannelsArray [i]
[self addChildViewController:viewController]
}
}
#pragma mark - 初始化顶部标题scrollView
- (void)setupTopContianerView{
CGFloat top = CGRectGetMaxY(self.navigationController .navigationBar .frame )
TTTopChannelContianerView *topContianerView = [[TTTopChannelContianerView alloc] initWithFrame:CGRectMake(0 , 0 , [UIScreen mainScreen].bounds .size .width , 30 )]
topContianerView.channelNameArray = self.currentChannelsArray
self.topContianerView = topContianerView
//self.topContianerView .backgroundColor = [UIColor redColor]
topContianerView.delegate = self
[self.view addSubview:topContianerView]
}
#pragma mark - 初始化ContentScrollView
- (void)setupContentScrollView {
UIScrollView *contentScrollView = [[UIScrollView alloc] init]
self.contentScrollView = contentScrollView
contentScrollView.frame = self.view .bounds
contentScrollView.contentSize = CGSizeMake(contentScrollView.frame .size .width * self.currentChannelsArray .count , 0 )
contentScrollView.pagingEnabled = YES
contentScrollView.delegate = self
[self.view insertSubview:contentScrollView atIndex:0 ]
[self scrollViewDidEndScrollingAnimation:contentScrollView]
}
#pragma mark - scrollView滑动停止调用
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
if (scrollView == self.contentScrollView ) {
NSInteger index = scrollView.contentOffset .x /self.contentScrollView .frame .size .width
ContentTableViewController *vc = self.childViewControllers [index]
vc.view .frame = CGRectMake(scrollView.contentOffset .x , 0 , self.contentScrollView .frame .size .width , self.contentScrollView .frame .size .height )
vc.tableView .contentInset = UIEdgeInsetsMake(self.topContianerView .scrollView .frame .size .height , 0 , self.tabBarController .tabBar .frame .size .height , 0 )
[scrollView addSubview:vc.view ]
for (int i = 0
NSInteger currentIndex = vc.tableView .frame .origin .x /self.contentScrollView .frame .size .width
if ([self.contentScrollView .subviews [i] isKindOfClass:[UITableView class]]) {
UITableView *theTableView = self.contentScrollView .subviews [i]
NSInteger theIndex = theTableView.frame .origin .x /self.contentScrollView .frame .size .width
NSInteger gap = theIndex - currentIndex
if (gap<=2 &&gap>=-2 ) {
continue
} else {
[theTableView removeFromSuperview]
}
}
}
}
}
#pragma mark --UIScrollViewDelegate-- 滑动的减速动画结束后会调用这个方法
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
if (scrollView == self.contentScrollView ) {
[self scrollViewDidEndScrollingAnimation:scrollView]
NSInteger index = scrollView.contentOffset .x /self.contentScrollView .frame .size .width
[self.topContianerView selectChannelButtonWithIndex:index]
}
}
#pragma mark - UICollectionViewDataSource-- 返回每个UICollectionViewCell发Size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat kDeviceWidth = [UIScreen mainScreen].bounds .size .width
CGFloat kMargin = 10
return CGSizeMake((kDeviceWidth - 5 *kMargin)/4 , 40 )
}
#pragma mark - TTTopChannelContianerViewDelegate
- (void)chooseChannelWithIndex:(NSInteger)index {
[self.contentScrollView setContentOffset:CGPointMake(self.contentScrollView .frame .size .width * index, 0 ) animated:YES]
}
#pragma mark - 顶部标题数组设置
-(NSMutableArray *)currentChannelsArray {
if (!_currentChannelsArray) {
if (!_currentChannelsArray) {
_currentChannelsArray = [NSMutableArray arrayWithObjects:@"新歌" , @"热歌" , @"经典" , @"情歌" , @"网络" , @"影视" , @"欧美" ,@"Bill" , @"摇滚" , @"爵士" , @"流行" , nil]
}
}
return _currentChannelsArray
}
#pragma mark - 锁屏界面开启和监控远程控制事件
//锁屏界面开启和监控远程控制事件
- (void)createRemoteCommandCenter{
// 远程控制命令中心 iOS 7.1 之后 详情看官方文档:https://developer.apple .com /documentation/mediaplayer/mpremotecommandcenter
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter]
// MPFeedbackCommand对象反映了当前App所播放的反馈状态. MPRemoteCommandCenter对象提供feedback对象用于对媒体文件进行喜欢, 不喜欢, 标记的操作. 效果类似于网易云音乐锁屏时的效果
//添加喜欢按钮
MPFeedbackCommand *likeCommand = commandCenter.likeCommand
likeCommand.enabled = YES
likeCommand.localizedTitle = @"喜欢"
[likeCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
NSLog(@"喜欢" )
return MPRemoteCommandHandlerStatusSuccess
}]
//添加不喜欢按钮,这里用作“下一首”
MPFeedbackCommand *dislikeCommand = commandCenter.dislikeCommand
dislikeCommand.enabled = YES
dislikeCommand.localizedTitle = @"下一首"
[dislikeCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
NSLog(@"下一首" )
[self nextButtonAction:nil]
return MPRemoteCommandHandlerStatusSuccess
}]
//标记
MPFeedbackCommand *bookmarkCommand = commandCenter.bookmarkCommand
bookmarkCommand.enabled = YES
bookmarkCommand.localizedTitle = @"标记"
[bookmarkCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
NSLog(@"标记" )
return MPRemoteCommandHandlerStatusSuccess
}]
// 远程控制播放
[commandCenter.pauseCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
[musicPlayer.play pause]
return MPRemoteCommandHandlerStatusSuccess
}]
// 远程控制暂停
[commandCenter.playCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
[musicPlayer.play play]
return MPRemoteCommandHandlerStatusSuccess
}]
// 远程控制上一曲
[commandCenter.previousTrackCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
NSLog(@"上一曲" )
return MPRemoteCommandHandlerStatusSuccess
}]
// 远程控制下一曲
[commandCenter.nextTrackCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
NSLog(@"下一曲" )
[self nextButtonAction:nil]
return MPRemoteCommandHandlerStatusSuccess
}]
//快进
MPSkipIntervalCommand *skipBackwardIntervalCommand = commandCenter.skipForwardCommand
skipBackwardIntervalCommand.preferredIntervals = @[@(54 )]
skipBackwardIntervalCommand.enabled = YES
[skipBackwardIntervalCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
NSLog(@"你按了快进按键!" )
// 歌曲总时间
CMTime duration = musicPlayer.play .currentItem .asset .duration
Float64 completeTime = CMTimeGetSeconds(duration)
// 快进10 秒
_songSlider.value = _songSlider.value + 10 / completeTime
// 计算快进后当前播放时间
Float64 currentTime = (Float64)(_songSlider.value ) * completeTime
// 播放器定位到对应的位置
CMTime targetTime = CMTimeMake((int64_t)(currentTime), 1 )
[musicPlayer.play seekToTime:targetTime]
return MPRemoteCommandHandlerStatusSuccess
}]
//在控制台拖动进度条调节进度(仿QQ音乐的效果)
[commandCenter.changePlaybackPositionCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent * _Nonnull event) {
CMTime totlaTime = musicPlayer.play .currentItem .duration
MPChangePlaybackPositionCommandEvent * playbackPositionEvent = (MPChangePlaybackPositionCommandEvent *)event
[musicPlayer.play seekToTime:CMTimeMake(totlaTime.value *playbackPositionEvent.positionTime /CMTimeGetSeconds(totlaTime), totlaTime.timescale ) completionHandler:^(BOOL finished) {
}]
return MPRemoteCommandHandlerStatusSuccess
}]
}
#pragma mark - removeObserver
- (void)dealloc{
[self removeObserver]
}
- (void)removeObserver{
[musicPlayer.play removeTimeObserver:_playerTimeObserver]
_playerTimeObserver = nil
[musicPlayer.play .currentItem cancelPendingSeeks]
[musicPlayer.play .currentItem .asset cancelLoading]
MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter]
[commandCenter.likeCommand removeTarget:self]
[commandCenter.dislikeCommand removeTarget:self]
[commandCenter.bookmarkCommand removeTarget:self]
[commandCenter.nextTrackCommand removeTarget:self]
[commandCenter.skipForwardCommand removeTarget:self]
[commandCenter.changePlaybackPositionCommand removeTarget:self]
}
#pragma mark - KVO
-(void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
if ([keyPath isEqual: @"playSongIndex" ]) {
[self playSongSetting]
}
if ([keyPath isEqual:@"isDataRequestFinish" ]) {
if (songInfo.isDataRequestFinish == YES) {
songInfo.isDataRequestFinish = NO
[_detailController.songListView .tableView reloadData]
}
}
if ([keyPath isEqual: @"finishPlaySongIndex" ]) {
[self playSongSetting]
}
}
#pragma mark - 音乐被中断处理
- (void) onAudioSessionEvent: (NSNotification *) notification
{
//Check the type of notification, especially if you are sending multiple AVAudioSession events here
if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
NSLog(@"Interruption notification received!" )
//Check to see if it was a Begin interruption
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
NSLog(@"Interruption began!" )
[musicPlayer stopPlay]
} else {
NSLog(@"Interruption ended!" )
//Resume your audio
[musicPlayer startPlay]
}
}
}
#pragma mark - 状态恢复
-(void) playStateRecover {
[_currentPlaySongImage startRotating]
if (musicPlayer.play .rate == 1 ) {
NSLog(@"播放!" )
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play" ] forState:UIControlStateNormal]
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play_prs" ] forState:UIControlStateHighlighted]
[_currentPlaySongImage resumeRotate]
} else {
NSLog(@"暂停" )
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause" ] forState:UIControlStateNormal]
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause_prs" ] forState:UIControlStateHighlighted]
[_currentPlaySongImage stopRotating]
}
}
#pragma mark - 播放音乐调用
-(void) playSongSetting {
if (_playerTimeObserver != nil) {
[musicPlayer.play removeTimeObserver:_playerTimeObserver]
_playerTimeObserver = nil
[musicPlayer.play .currentItem cancelPendingSeeks]
[musicPlayer.play .currentItem .asset cancelLoading]
}
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play" ] forState:UIControlStateNormal]
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play_prs" ] forState:UIControlStateHighlighted]
// 主页面控制界面信息设置
_songName.text = songInfo.title
_singerName.text = songInfo.author
_currentPlaySongImage.image = songInfo.pic _small
[_currentPlaySongImage resumeRotate]
// detail页面控制界面信息设置
_detailController.topView .songTitleLabel .text = songInfo.title
_detailController.topView .singerNameLabel .text = [[@"- " stringByAppendingString:songInfo.author ] stringByAppendingString:@" -" ]
[_detailController.midView .midIconView setAlbumImage:songInfo.pic _big]
[_detailController.midView .midLrcView AnalysisLRC:songInfo.lrcString ]
// 播放设置
[musicPlayer setPlayItem:songInfo.file _link]
[musicPlayer setPlay]
[musicPlayer startPlay]
// 歌词index清零
songInfo.lrcIndex = 0
// 控制界面设置
[_detailController playStateRecover]
// 播放结束通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(finishedPlaying) name:AVPlayerItemDidPlayToEndTimeNotification object:musicPlayer.play .currentItem ]
// 设置Observer更新播放进度
_playerTimeObserver = [musicPlayer.play addPeriodicTimeObserverForInterval:CMTimeMake(1.0 , 1.0 ) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
CGFloat currentTime = CMTimeGetSeconds(time)
NSLog(@"当前播放时间:%f" , currentTime)
CMTime total = musicPlayer.play .currentItem .duration
CGFloat totalTime = CMTimeGetSeconds(total)
// 当前播放时间
_detailController.bottomView .currentTimeLabel .text = [songInfo intToString:(int)currentTime]
// 总时间
_detailController.bottomView .durationTimeLabel .text =[songInfo intToString:(int)totalTime]
_songSlider.value = (float) ( currentTime / totalTime )
_detailController.bottomView .songSlider .value = (float) ( currentTime / totalTime )
// 更新歌词
if (songInfo.isLrcExistFlg == true) {
if (!_detailController.midView .midLrcView .isDragging ) {
if (songInfo.lrcIndex <= songInfo.mLRCDictinary .count - 1 ) {
if ((int)currentTime >= [songInfo stringToInt:songInfo.mTimeArray [songInfo.lrcIndex ]]) {
_detailController.midView .midLrcView .currentRow = songInfo.lrcIndex
dispatch_async(dispatch_get_main_queue(), ^{
[_detailController.midView .midLrcView .tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:_detailController.midView .midLrcView .currentRow inSection:0 ] atScrollPosition:UITableViewScrollPositionMiddle animated:YES]
[_detailController.midView .midLrcView .lockScreenTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow: _detailController.midView .midLrcView .currentRow inSection:0 ] atScrollPosition:UITableViewScrollPositionMiddle animated:YES]
})
// 刷新歌词列表
[_detailController.midView .midLrcView .tableView reloadData]
[_detailController.midView .midLrcView .lockScreenTableView reloadData]
songInfo.lrcIndex = songInfo.lrcIndex + 1
} else {
if (songInfo.lrcIndex != 0 ) {
if (((int)currentTime >= [songInfo stringToInt:songInfo.mTimeArray [songInfo.lrcIndex - 1 ]]) && ((int)currentTime < [songInfo stringToInt:songInfo.mTimeArray [songInfo.lrcIndex ]])) {
_detailController.midView .midLrcView .currentRow = songInfo.lrcIndex - 1
dispatch_async(dispatch_get_main_queue(), ^{
[_detailController.midView .midLrcView .tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:_detailController.midView .midLrcView .currentRow inSection:0 ] atScrollPosition:UITableViewScrollPositionMiddle animated:YES]
[_detailController.midView .midLrcView .lockScreenTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow: _detailController.midView .midLrcView .currentRow inSection:0 ] atScrollPosition:UITableViewScrollPositionMiddle animated:YES]
})
// 刷新歌词列表
[_detailController.midView .midLrcView .tableView reloadData]
[_detailController.midView .midLrcView .lockScreenTableView reloadData]
}
}
}
}
}
}
//监听锁屏状态 lock=1 则为锁屏状态
uint64_t locked
__block int token = 0
notify_register_dispatch("com.apple.springboard.lockstate" ,&token,dispatch_get_main_queue(),^(int t){
})
notify_get_state(token, &locked)
//监听屏幕点亮状态 screenLight = 1 则为变暗关闭状态
uint64_t screenLight
__block int lightToken = 0
notify_register_dispatch("com.apple.springboard.hasBlankedScreen" ,&lightToken,dispatch_get_main_queue(),^(int t){
})
notify_get_state(lightToken, &screenLight)
BOOL isShowLyricsPoster = NO
// NSLog(@"screenLight=%llu locked=%llu" ,screenLight,locked)
if (screenLight == 0 && locked == 1 ) {
//点亮且锁屏时
isShowLyricsPoster = YES
}else if(screenLight){
return
}
//展示锁屏歌曲信息,上面监听屏幕锁屏和点亮状态的目的是为了提高效率
[self showLockScreenTotaltime:totalTime andCurrentTime:currentTime andLyricsPoster:isShowLyricsPoster]
}]
}
#pragma mark - 锁屏播放设置
//展示锁屏歌曲信息:图片、歌词、进度、演唱者
- (void)showLockScreenTotaltime:(float)totalTime andCurrentTime:(float)currentTime andLyricsPoster:(BOOL)isShow{
NSMutableDictionary * songDict = [[NSMutableDictionary alloc] init]
//设置歌曲题目
[songDict setObject:songInfo.title forKey:MPMediaItemPropertyTitle]
//设置歌手名
[songDict setObject:songInfo.author forKey:MPMediaItemPropertyArtist]
//设置专辑名
[songDict setObject:songInfo.album _title forKey:MPMediaItemPropertyAlbumTitle]
//设置歌曲时长
[songDict setObject:[NSNumber numberWithDouble:totalTime] forKey:MPMediaItemPropertyPlaybackDuration]
//设置已经播放时长
[songDict setObject:[NSNumber numberWithDouble:currentTime] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime]
UIImage * lrcImage = songInfo.pic _big
if (isShow) {
//制作带歌词的海报
if (!_lrcImageView) {
_lrcImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0 , 0 , 480 ,800 )]
}
//主要为了把歌词绘制到图片上,已达到更新歌词的目的
[_lrcImageView addSubview:_detailController.midView .midLrcView .lockScreenTableView ]
_lrcImageView.image = lrcImage
_lrcImageView.backgroundColor = [UIColor blackColor]
//获取添加了歌词数据的海报图片
UIGraphicsBeginImageContextWithOptions(_lrcImageView.frame .size , NO, 0.0 )
CGContextRef context = UIGraphicsGetCurrentContext()
[_lrcImageView.layer renderInContext:context]
lrcImage = UIGraphicsGetImageFromCurrentImageContext()
_lastImage = lrcImage
UIGraphicsEndImageContext()
}else{
if (_lastImage) {
lrcImage = _lastImage
}
}
//设置显示的海报图片
[songDict setObject:[[MPMediaItemArtwork alloc] initWithImage:lrcImage]
forKey:MPMediaItemPropertyArtwork]
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songDict]
}
#pragma mark - 播放或暂停
-(void)playAndPauseButtonAction: (UIButton *)sender {
NSLog(@"当前播放曲目:%@" , songInfo.title )
if (musicPlayer.play .rate == 0 ) {
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play" ] forState:UIControlStateNormal]
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play_prs" ] forState:UIControlStateHighlighted]
[_currentPlaySongImage resumeRotate]
[musicPlayer startPlay]
} else {
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause" ] forState:UIControlStateNormal]
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause_prs" ] forState:UIControlStateHighlighted]
[_currentPlaySongImage stopRotating]
[musicPlayer stopPlay]
}
}
#pragma mark - 下一曲
-(void) nextButtonAction: (UIButton *)sender {
if (songInfo.playSongIndex < songInfo.OMSongs .count - 1 ) {
OMHotSongInfo *info = songInfo.OMSongs [songInfo.playSongIndex + 1 ]
NSLog(@"即将播放下一首歌曲: 《%@》" , info.title )
[songInfo setSongInfo:info]
[songInfo getSelectedSong:info.song _id index:songInfo.playSongIndex + 1 ]
} else {
OMHotSongInfo *info = songInfo.OMSongs [0 ]
NSLog(@"即将播放下一首歌曲: 《%@》" , info.title )
[songInfo setSongInfo:info]
[songInfo getSelectedSong:info.song _id index:0 ]
}
}
#pragma mark - 歌曲播放结束操作
-(void) finishedPlaying {
NSLog(@"本歌曲播放结束,准备播放下一首歌曲!" )
// songInfo.playSongIndex = songInfo.playSongIndex + 1
[self nextButtonAction:nil]
}
#pragma mark - 点击专辑图片
-(void) jumpToDeitalController {
[self presentViewController:_detailController animated:YES completion:nil]
}
#pragma mark - 进度条改变值时触发
//拖动进度条改变值时触发
-(void) playbackSliderValueChanged {
// 更新播放时间
[self updateTime]
//如果当前时暂停状态,则自动播放
if (musicPlayer.play .rate == 0 ) {
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play" ] forState:UIControlStateNormal]
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play_prs" ] forState:UIControlStateHighlighted]
[_currentPlaySongImage resumeRotate]
[musicPlayer startPlay]
}
}
#pragma mark - 进度条改变值结束时触发
-(void) playbackSliderValueChangedFinish {
// 更新播放时间
[self updateTime]
//如果当前时暂停状态,则自动播放
if (musicPlayer.play .rate == 0 ) {
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play" ] forState:UIControlStateNormal]
[_playAndPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play_prs" ] forState:UIControlStateHighlighted]
[_currentPlaySongImage resumeRotate]
[musicPlayer startPlay]
}
}
#pragma mark - 更新播放时间
-(void) updateTime {
CMTime duration = musicPlayer.play .currentItem .asset .duration
// 歌曲总时间和当前时间
Float64 completeTime = CMTimeGetSeconds(duration)
Float64 currentTime = (Float64)(_songSlider.value ) * completeTime
//播放器定位到对应的位置
CMTime targetTime = CMTimeMake((int64_t)(currentTime), 1 )
[musicPlayer.play seekToTime:targetTime]
int index = 0
for (NSString *indexStr in songInfo.mTimeArray ) {
if ((int)currentTime < [songInfo stringToInt:indexStr]) {
songInfo.lrcIndex = index
} else {
index = index + 1
}
}
}
@end
ContentTableViewController.h
#import <UIKit/UIKit.h>
#import "AFNetworking.h"
#import "OMHotSongInfo.h"
#import "OMSongInfo.h"
#import "OMAlbumInfo.h"
#import "OMArtistInfo.h"
#import "MJRefresh.h"
#import "Const.h"
#import "MusicDownloader.h"
#import "DetailControlViewController.h"
@interface ContentTableViewController : UITableViewController <UIScrollViewDelegate >
@property (nonatomic , strong ) NSString *channelTitle;
@property (nonatomic , strong ) DetailControlViewController *detailController;
-(void )reloadData;
-(void )getSelectedSong: (NSString *)songID index: (long )index;
@end
ContentTableViewController.m
#import "ContentTableViewController.h"
#define kCustomRowCount 7
static NSString *CellIdentifier = @"LazyTableCell" ;
static NSString *PlaceholderCellIdentifier = @"PlaceholderCell" ;
@interface ContentTableViewController ()
{
NSArray *hotArtistsArray;
NSArray *newAlbumsArray;
NSArray *onlineMusicArray;
NSString *choosedAlbumID;
NSString *choosedArtistUID;
OMSongInfo *songInfo;
}
@property (nonatomic , strong ) NSMutableArray *arrayList;
@property (nonatomic , strong ) NSMutableDictionary *imageDownloadInProgress;
@property (nonatomic , strong ) UIActivityIndicatorView *indicator;
@property (nonatomic , strong ) MusicDownloader *downloader;
@end
@implementation ContentTableViewController
- (void )viewDidLoad {
[super viewDidLoad];
_downloader = [[MusicDownloader alloc] init];
_downloader.isDataRequestFinish = false ;
_imageDownloadInProgress = [NSMutableDictionary dictionary];
songInfo = OMSongInfo.sharedManager ;
[self setupBasic];
[self setupRefresh];
}
- (void )didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark --private Method--设置tableView
-(void )setupBasic {
self .automaticallyAdjustsScrollViewInsets = NO ;
self .tableView .separatorStyle = UITableViewCellSeparatorStyleNone;
self .tableView .scrollIndicatorInsets = UIEdgeInsetsMake(104 , 0 , 0 , 0 );
}
#pragma mark --private Method--初始化刷新控件
-(void )setupRefresh {
self .tableView .mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector (loadData)];
self .tableView .mj_header .automaticallyChangeAlpha = YES ;
[self .tableView .mj_header beginRefreshing];
self .tableView .mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector (loadMoreData)];
}
#pragma mark - /************************* 刷新数据 ***************************/
- (void )loadData
{
uint8_t type;
if ([self .channelTitle isEqual: @"新歌" ]) {
type = NEW_SONG_LIST;
}else if ([self .channelTitle isEqual: @"热歌" ]) {
type = HOT_SONG_LIST;
}else if ([self .channelTitle isEqual: @"经典" ]) {
type = OLD_SONG_LIST;
}else if ([self .channelTitle isEqual: @"情歌" ]) {
type = LOVE_SONG_LIST;
}else if ([self .channelTitle isEqual: @"网络" ]) {
type = INTERNET_SONG_LIST;
}else if ([self .channelTitle isEqual: @"影视" ]) {
type = MOVIE_SONG_LIST;
}else if ([self .channelTitle isEqual: @"欧美" ]) {
type = EUROPE_SONG_LIST;
}else if ([self .channelTitle isEqual: @"Bill" ]) {
type = BILLBOARD_MUSIC_LIST;
}else if ([self .channelTitle isEqual: @"摇滚" ]) {
type = ROCK_MUSIC_LIST;
}else if ([self .channelTitle isEqual: @"爵士" ]) {
type = JAZZ_MUSIC_LIST;
}else if ([self .channelTitle isEqual: @"流行" ]) {
type = POP_MUSIC_LIST;
}else {
return ;
}
NSString *partOne = @"http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&" ;
NSString *partTwo = [NSString stringWithFormat:@"type=%d&offset=0&size=%d" ,type, 20 ];
NSString *urlString = [partOne stringByAppendingString:partTwo];
[self loadDataForType:1 withURL:urlString];
}
- (void )loadMoreData
{
uint8_t type;
if ([self .channelTitle isEqual: @"新歌" ]) {
type = NEW_SONG_LIST;
}else if ([self .channelTitle isEqual: @"热歌" ]) {
type = HOT_SONG_LIST;
}else if ([self .channelTitle isEqual: @"经典" ]) {
type = OLD_SONG_LIST;
}else if ([self .channelTitle isEqual: @"情歌" ]) {
type = LOVE_SONG_LIST;
}else if ([self .channelTitle isEqual: @"网络" ]) {
type = INTERNET_SONG_LIST;
}else if ([self .channelTitle isEqual: @"影视" ]) {
type = MOVIE_SONG_LIST;
}else if ([self .channelTitle isEqual: @"欧美" ]) {
type = EUROPE_SONG_LIST;
}else if ([self .channelTitle isEqual: @"Bill" ]) {
type = BILLBOARD_MUSIC_LIST;
}else if ([self .channelTitle isEqual: @"摇滚" ]) {
type = ROCK_MUSIC_LIST;
}else if ([self .channelTitle isEqual: @"爵士" ]) {
type = JAZZ_MUSIC_LIST;
}else if ([self .channelTitle isEqual: @"流行" ]) {
type = POP_MUSIC_LIST;
}else {
return ;
}
NSString *partOne = @"http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.billboard.billList&format=json&" ;
NSString *partTwo = [NSString stringWithFormat:@"type=%d&offset=%lu&size=%d" ,type,(unsigned long )self .arrayList .count , 20 ];
NSString *urlString = [partOne stringByAppendingString:partTwo];
[self loadDataForType:2 withURL:urlString];
}
- (void )loadDataForType:(int )loadingType withURL:(NSString *)urlString
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSString *path = urlString;
[manager GET:path parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if ([responseObject isKindOfClass:[NSDictionary class]])
{
NSArray *array = [responseObject objectForKey:@"song_list" ];
NSArray *loadSongArray = [OMHotSongInfo mj_objectArrayWithKeyValuesArray:array];
if (loadingType == 1 ) {
self .arrayList = [loadSongArray mutableCopy];
[self .tableView .mj_header endRefreshing];
}else if (loadingType == 2 ){
if (self .arrayList .count >= 100 ) {
[self .tableView .mj_footer endRefreshing];
return ;
}
[self .arrayList addObjectsFromArray:loadSongArray];
[self .tableView .mj_footer endRefreshing];
}
songInfo.isDataRequestFinish = YES ;
songInfo.OMSongs = self .arrayList ;
[self .tableView reloadData];
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog (@"error--%@" ,error);
}];
}
- (void )startIconDownload:(OMHotSongInfo *)info forIndexPath:(NSIndexPath *)indexPath
{
MusicDownloader *downloader = (self .imageDownloadInProgress )[indexPath];
if (downloader == nil )
{
downloader = [[MusicDownloader alloc] init];
downloader.hotSonginfo = info;
[downloader setCompletionHandler:^{
UITableViewCell *cell = [self .tableView cellForRowAtIndexPath:indexPath];
cell.imageView .image = info.albumImage_small ;
[self .imageDownloadInProgress removeObjectForKey:indexPath];
}];
(self .imageDownloadInProgress )[indexPath] = downloader;
[downloader startDownload];
}
}
-(void ) loadImagesForOnScreenRows {
if (self .arrayList .count > 0 ) {
NSArray *visiblePaths= [self .tableView indexPathsForVisibleRows];
for (NSIndexPath *indexPath in visiblePaths) {
OMHotSongInfo *info = (self .arrayList )[indexPath.row ];
if (!info.albumImage_small ) {
[self startIconDownload:info forIndexPath:indexPath];
}
}
}
}
#pragma - mark TableView代理
-(NSInteger )numberOfSectionsInTableView:(UITableView *)tableView
{
return 1 ;
}
-(CGFloat )tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70 ;
}
- (NSInteger )tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger )section {
if ([self .channelTitle isEqualToString:@"新歌" ]) {
return self .arrayList .count ;
}else if ([self .channelTitle isEqual: @"热歌" ]) {
return self .arrayList .count ;
}else if ([self .channelTitle isEqual: @"经典" ]) {
return self .arrayList .count ;
}else if ([self .channelTitle isEqual: @"情歌" ]) {
return self .arrayList .count ;
}else if ([self .channelTitle isEqual: @"网络" ]) {
return self .arrayList .count ;
}else if ([self .channelTitle isEqual: @"影视" ]) {
return self .arrayList .count ;
}else if ([self .channelTitle isEqual: @"欧美" ]) {
return self .arrayList .count ;
}else if ([self .channelTitle isEqual: @"Bill" ]) {
return self .arrayList .count ;
}else if ([self .channelTitle isEqual: @"摇滚" ]) {
return self .arrayList .count ;
}else if ([self .channelTitle isEqual: @"爵士" ]) {
return self .arrayList .count ;
}else if ([self .channelTitle isEqual: @"流行" ]) {
return self .arrayList .count ;
}
return 0 ;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil ;
NSUInteger nodeCount = self .arrayList .count ;
if (nodeCount == 0 && indexPath.row == 0 )
{
cell = [self .tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
if (cell == nil ) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:PlaceholderCellIdentifier];
}
}
else
{
cell = [self .tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil ) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (nodeCount > 0 )
{
OMHotSongInfo *info = (self .arrayList )[indexPath.row ];
cell.textLabel .text = info.title ;
cell.detailTextLabel .text = info.author ;
if (!info.albumImage_small )
{
if (self .tableView .dragging == NO && self .tableView .decelerating == NO )
{
[self startIconDownload:info forIndexPath:indexPath];
}
cell.imageView .image = [UIImage imageNamed:@"Placeholder.png" ];
}
else
{
cell.imageView .image = info.albumImage_small ;
}
}
}
return cell;
}
-(void )tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
OMHotSongInfo *info = (self .arrayList )[indexPath.row ];
NSLog (@"你选择了《%@》这首歌" , info.title );
[songInfo setSongInfo:info];
[songInfo getSelectedSong:info.song_id index:indexPath.row ];
}
#pragma mark - UIScrollViewDelegate
-(void ) scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL )decelerate {
if (!decelerate) {
[self loadImagesForOnScreenRows];
}
}
- (void )scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self loadImagesForOnScreenRows];
}
@end
DetailControlViewController.h
#import <UIKit/UIKit.h>
#import "TopView.h"
#import "MidView.h"
#import "BottomView.h"
#import "OMSongInfo.h"
#import "MusicPlayerManager.h"
#import "OMHotSongInfo.h"
#import "SongListView.h"
#import "Const.h"
@interface DetailControlViewController : UIViewController
@property (nonatomic ,strong ) SongListView *songListView;
@property (nonatomic ,strong ) UIView *shadowView;
@property (nonatomic , strong ) TopView *topView;
@property (nonatomic , strong ) MidView *midView;
@property (nonatomic , strong ) BottomView *bottomView;
@property (nonatomic , strong ) UIImageView *backgroundImageView;
-(void ) setBackgroundImage: (UIImage *)image;
-(void ) playStateRecover;
@end
DetailControlViewController.m
#import "DetailControlViewController.h"
extern MusicPlayerManager *musicPlayer;
extern OMSongInfo *songInfo;
@implementation DetailControlViewController
int lrcIndex = 0 ;
-(instancetype) init {
self = [super init];
if (self ) {
[self configSubView];
}
return self ;
}
- (void )viewDidLoad {
[super viewDidLoad];
[self getShuffleAndRepeatState];
}
-(void ) viewWillAppear:(BOOL )animated {
[self playStateRecover];
}
- (void )didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark - configSubView
-(void ) configSubView {
musicPlayer = MusicPlayerManager.sharedManager ;
songInfo = OMSongInfo.sharedManager ;
_topView = [[TopView alloc] initWithFrame:CGRectMake(0 , 0 , self .view .frame .size .width , self .view .frame .size .height / 5 )];
[_topView.backBtn addTarget:self action:@selector (backAction) forControlEvents: UIControlEventTouchUpInside];
[self .view addSubview:_topView];
_midView = [[MidView alloc] initWithFrame:CGRectMake(0 , self .view .frame .size .height / 5 , self .view .frame .size .width , self .view .frame .size .height / 5 * 3 )];
[self .view addSubview:_midView];
_bottomView = [[BottomView alloc] initWithFrame:CGRectMake(0 , self .view .frame .size .height / 5 * 4 , self .view .frame .size .width , self .view .frame .size .height / 5 )];
[self .view addSubview:_bottomView];
_songListView = [[SongListView alloc] initWithFrame:CGRectMake(0 , 0 , ScreenWidth, ScreenHeight * 0.618 )];
_songListView.backgroundColor = [UIColor whiteColor];
[_bottomView.playOrPauseButton addTarget:self action:@selector (playOrPauseButtonAction) forControlEvents:UIControlEventTouchUpInside];
[_bottomView.nextSongButton addTarget:self action:@selector (nextButtonAction) forControlEvents:UIControlEventTouchUpInside];
[_bottomView.preSongButtton addTarget:self action:@selector (preButtonAction) forControlEvents:UIControlEventTouchUpInside];
[_bottomView.playModeButton addTarget:self action:@selector (shuffleAndRepeat) forControlEvents:UIControlEventTouchUpInside];
[_bottomView.songListButton addTarget:self action:@selector (songListButtonAction) forControlEvents:UIControlEventTouchUpInside];
[_bottomView.songSlider addTarget:self
action:@selector (playbackSliderValueChanged)
forControlEvents:UIControlEventValueChanged
];
[_bottomView.songSlider addTarget:self
action:@selector (playbackSliderValueChangedFinish)
forControlEvents:UIControlEventTouchUpInside
];
[self setBackgroundImage:[UIImage imageNamed:@"backgroundImage3" ]];
}
#pragma mark - 状态恢复
-(void ) playStateRecover {
[_midView.midIconView .imageView startRotating];
if (musicPlayer.play .rate == 1 ) {
NSLog (@"播放!" );
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play" ] forState:UIControlStateNormal];
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play_prs" ] forState:UIControlStateHighlighted];
[_midView.midIconView .imageView resumeRotate];
} else {
NSLog (@"暂停" );
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause" ] forState:UIControlStateNormal];
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause_prs" ] forState:UIControlStateHighlighted];
[_midView.midIconView .imageView stopRotating];
}
}
#pragma - mark 设置detail控制界面背景图片
-(void ) setBackgroundImage: (UIImage *)image {
_backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectMake(-UIScreen.mainScreen .bounds .size .width / 2 , -UIScreen.mainScreen .bounds .size .height / 2 , UIScreen.mainScreen .bounds .size .width * 2 , UIScreen.mainScreen .bounds .size .height * 2 )];
_backgroundImageView.image = image;
_backgroundImageView.clipsToBounds = true ;
[self .view addSubview:_backgroundImageView];
[self .view sendSubviewToBack:_backgroundImageView];
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *visualView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
visualView.alpha = 1.0 ;
visualView.frame = CGRectMake(-UIScreen.mainScreen .bounds .size .width / 2 , -UIScreen.mainScreen .bounds .size .height / 2 , UIScreen.mainScreen .bounds .size .width * 2 , UIScreen.mainScreen .bounds .size .height * 2 );
visualView.clipsToBounds = true ;
[_backgroundImageView addSubview:visualView];
}
#pragma - mark 播放或暂停
-(void ) playOrPauseButtonAction {
if (musicPlayer.play .rate == 0 ) {
NSLog (@"播放!" );
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play" ] forState:UIControlStateNormal];
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play_prs" ] forState:UIControlStateHighlighted];
[_midView.midIconView .imageView resumeRotate];
[musicPlayer startPlay];
} else {
NSLog (@"暂停" );
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause" ] forState:UIControlStateNormal];
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause_prs" ] forState:UIControlStateHighlighted];
[_midView.midIconView .imageView stopRotating];
[musicPlayer stopPlay];
}
}
#pragma - mark 下一曲
-(void ) nextButtonAction {
musicPlayer.playingIndex = songInfo.playSongIndex ;
switch (musicPlayer.shuffleAndRepeatState )
{
case RepeatPlayMode:
{
musicPlayer.playingIndex ++;
if (musicPlayer.playingIndex >= songInfo.OMSongs .count )
{
musicPlayer.playingIndex = 0 ;
}
}
break ;
case RepeatOnlyOnePlayMode:
{
}
break ;
case ShufflePlayMode:
{
if (musicPlayer.playingIndex == songInfo.OMSongs .count - 1 )
{
musicPlayer.playingIndex = [self getRandomNumber:0 with:(songInfo.OMSongs .count - 2 )];
}
else
{
musicPlayer.playingIndex = [self getRandomNumber:(musicPlayer.playingIndex + 1 ) with:(songInfo.OMSongs .count - 1 )];
}
}
break ;
default :
break ;
}
if ( musicPlayer.playingIndex != songInfo.playSongIndex ) {
if (songInfo.playSongIndex < songInfo.OMSongs .count ) {
OMHotSongInfo *info = songInfo.OMSongs [ musicPlayer.playingIndex ];
NSLog (@"即将播放下一首歌曲: 《%@》" , info.title );
[songInfo setSongInfo:info];
[songInfo getSelectedSong:info.song_id index:songInfo.playSongIndex + 1 ];
}
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:@"repeatPlay" object:self ];
}
}
#pragma - mark 上一曲
-(void ) preButtonAction {
musicPlayer.playingIndex = songInfo.playSongIndex ;
switch (musicPlayer.shuffleAndRepeatState )
{
case RepeatPlayMode:
{
if ( musicPlayer.playingIndex == 0 )
{
musicPlayer.playingIndex = songInfo.OMSongs .count - 1 ;
}
else
{
musicPlayer.playingIndex --;
}
}
break ;
case RepeatOnlyOnePlayMode:
{
}
break ;
case ShufflePlayMode:
{
if ( musicPlayer.playingIndex == 0 )
{
musicPlayer.playingIndex = [self getRandomNumber:1 with:(songInfo.OMSongs .count - 1 )];
}
else
{
musicPlayer.playingIndex = [self getRandomNumber:0 with:( musicPlayer.playingIndex - 1 )];
}
}
break ;
default :
break ;
}
if ( musicPlayer.playingIndex != songInfo.playSongIndex ) {
if (songInfo.playSongIndex > 0 ) {
OMHotSongInfo *info = songInfo.OMSongs [songInfo.playSongIndex - 1 ];
NSLog (@"即将播放上一首歌曲: 《%@》" , info.title );
[songInfo setSongInfo:info];
[songInfo getSelectedSong:info.song_id index:songInfo.playSongIndex - 1 ];
}
} else {
[[NSNotificationCenter defaultCenter] postNotificationName:@"repeatPlay" object:self ];
}
}
#pragma - mark 歌曲列表
-(void ) songListButtonAction {
NSLog (@"你按下了songList按键!" );
[_songListView setPlayModeButtonState];
_shadowView = [[UIView alloc] init];
_shadowView.frame = CGRectMake(0 , 0 , ScreenWidth, ScreenHeight * (1.0 - 0.618 ));
_shadowView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.0 ];
UIWindow *appWindow = [[UIApplication sharedApplication] keyWindow];
[appWindow addSubview:_shadowView];
[appWindow addSubview:_songListView];
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector (responseGlide)];
gesture.numberOfTapsRequired = 1 ;
gesture.cancelsTouchesInView = NO ;
[_shadowView addGestureRecognizer:gesture];
_songListView.transform = CGAffineTransformMakeTranslation(0.0 , ScreenHeight);
_shadowView.transform = CGAffineTransformMakeTranslation(0.0 , ScreenHeight);
[UIView animateWithDuration:0.3 animations:^{
_shadowView.transform = CGAffineTransformMakeTranslation(0.0 , 0.0 );
_songListView.transform = CGAffineTransformMakeTranslation(0.0 , ScreenHeight * (1.0 - 0.618 ));
} completion:^(BOOL finished){
_shadowView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.2 ];
}];
}
#pragma mark - 下滑退出detail控制界面
- (void )responseGlide {
[self setShuffleAndRepeatState];
[UIView animateWithDuration:0.3 animations:^{
_songListView.transform = CGAffineTransformMakeTranslation(0.0 , ScreenHeight);
_shadowView.alpha = 0 ;
} completion:^(BOOL finished) {
[_shadowView removeFromSuperview];
[_songListView removeFromSuperview];
}];
}
#pragma - mark 进度条改变值时触发
-(void ) playbackSliderValueChanged {
[self updateTime];
if (musicPlayer.play .rate == 0 ) {
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play" ] forState:UIControlStateNormal];
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play_prs" ] forState:UIControlStateHighlighted];
[_midView.midIconView .imageView resumeRotate];
[musicPlayer startPlay];
}
}
#pragma - mark 进度条改变值结束时触发
-(void ) playbackSliderValueChangedFinish {
[self updateTime];
if (musicPlayer.play .rate == 0 ) {
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play" ] forState:UIControlStateNormal];
[_bottomView.playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_play_prs" ] forState:UIControlStateHighlighted];
[_midView.midIconView .imageView resumeRotate];
[musicPlayer startPlay];
}
}
#pragma - mark 更新播放时间
-(void ) updateTime {
CMTime duration = musicPlayer.play .currentItem .asset .duration ;
Float64 completeTime = CMTimeGetSeconds(duration);
Float64 currentTime = (Float64)(_bottomView.songSlider .value ) * completeTime;
CMTime targetTime = CMTimeMake((int64_t)(currentTime), 1 );
[musicPlayer.play seekToTime:targetTime];
int index = 0 ;
for (NSString *indexStr in songInfo.mTimeArray ) {
if ((int )currentTime < [songInfo stringToInt:indexStr]) {
songInfo.lrcIndex = index;
} else {
index = index + 1 ;
}
}
}
#pragma - mark 播放模式按键action
-(void ) shuffleAndRepeat {
switch (musicPlayer.shuffleAndRepeatState )
{
case RepeatPlayMode:
{
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_one" ] forState:UIControlStateNormal];
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_one_prs" ] forState:UIControlStateHighlighted];
musicPlayer.shuffleAndRepeatState = RepeatOnlyOnePlayMode;
[self showMiddleHint:@"单曲循环" ];
}
break ;
case RepeatOnlyOnePlayMode:
{
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_shuffle" ] forState:UIControlStateNormal];
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_shuffle_prs" ] forState:UIControlStateHighlighted];
musicPlayer.shuffleAndRepeatState = ShufflePlayMode;
[self showMiddleHint:@"列表播放" ];
}
break ;
case ShufflePlayMode:
{
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_loop" ] forState:UIControlStateNormal];
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_loop_prs" ] forState:UIControlStateHighlighted];
musicPlayer.shuffleAndRepeatState = RepeatPlayMode;
[self showMiddleHint:@"随机播放" ];
}
break ;
default :
break ;
}
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInteger:musicPlayer.shuffleAndRepeatState ] forKey:@"SHFFLEANDREPEATSTATE" ];
}
#pragma - mark 获取保存的播放模式
- (void )getShuffleAndRepeatState
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSNumber *repeatAndShuffleNumber = [defaults objectForKey:@"SHFFLEANDREPEATSTATE" ];
if (repeatAndShuffleNumber == nil )
{
musicPlayer.shuffleAndRepeatState = RepeatPlayMode;
}
else
{
musicPlayer.shuffleAndRepeatState = (ShuffleAndRepeatState)[repeatAndShuffleNumber integerValue];
}
switch (musicPlayer.shuffleAndRepeatState )
{
case RepeatPlayMode:
{
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_loop" ] forState:UIControlStateNormal];
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_loop_prs" ] forState:UIControlStateHighlighted];
}
break ;
case RepeatOnlyOnePlayMode:
{
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_one" ] forState:UIControlStateNormal];
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_one_prs" ] forState:UIControlStateHighlighted];
}
break ;
case ShufflePlayMode:
{
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_shuffle" ] forState:UIControlStateNormal];
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_shuffle_prs" ] forState:UIControlStateHighlighted];
break ;
default :
break ;
}
}
}
#pragma - mark 设置播放模式
-(void ) setShuffleAndRepeatState {
switch (musicPlayer.shuffleAndRepeatState )
{
case RepeatPlayMode:
{
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_loop" ] forState:UIControlStateNormal];
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_loop_prs" ] forState:UIControlStateHighlighted];
}
break ;
case RepeatOnlyOnePlayMode:
{
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_one" ] forState:UIControlStateNormal];
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_one_prs" ] forState:UIControlStateHighlighted];
}
break ;
case ShufflePlayMode:
{
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_shuffle" ] forState:UIControlStateNormal];
[_bottomView.playModeButton setImage:[UIImage imageNamed:@"cm2_icn_shuffle_prs" ] forState:UIControlStateHighlighted];
break ;
default :
break ;
}
}
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInteger:musicPlayer.shuffleAndRepeatState ] forKey:@"SHFFLEANDREPEATSTATE" ];
}
#pragma mark - 播放模式提示框
- (void )showMiddleHint:(NSString *)hint {
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self .view animated:YES ];
hud.userInteractionEnabled = NO ;
hud.mode = MBProgressHUDModeText;
hud.label .font = [UIFont systemFontOfSize:15 ];
hud.label .text = hint;
hud.margin = 10. f;
hud.offset = CGPointMake(0. f, 0. f);
hud.removeFromSuperViewOnHide = YES ;
[hud hideAnimated:YES afterDelay:2. f];
}
-(void ) backAction {
[self dismissViewControllerAnimated:YES completion:nil ];
}
#pragma - mark 获取随机数,用于随机播放
-(NSUInteger) getRandomNumber:(NSUInteger)from with:(NSUInteger)to
{
NSUInteger res = from + (arc4random() % (to - from + 1 ));
return res;
}
@end
OMAlbumInfo.h
#import <Foundation/Foundation.h>
@interface OMAlbumInfo : NSObject
@property (nonatomic , strong ) NSString *album_id;
@property (nonatomic , strong ) NSString *title;
@property (nonatomic , strong ) NSString *pic_small;
@property (nonatomic , strong ) NSString *pic_big;
@end
OMAlbumInfo.m
#import "OMAlbumInfo.h"
@implementation OMAlbumInfo
@end
OMHotSongInfo.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface OMHotSongInfo : NSObject
@property (nonatomic ,strong ) UIImage *albumImage_big;
@property (nonatomic ,strong ) UIImage *albumImage_small;
@property (nonatomic ,strong ) NSString *pic_big;
@property (nonatomic ,strong ) NSString *lrclink;
@property (nonatomic ,strong ) NSString *pic_small;
@property (nonatomic ,strong ) NSString *song_id;
@property (nonatomic ,strong ) NSString *title;
@property (nonatomic ,strong ) NSString *author;
@property (nonatomic ,strong ) NSString *album_title;
@property (nonatomic ,strong ) NSString *file_duration;
@end
OMHotSongInfo.m
#import "OMHotSongInfo.h"
@implementation OMHotSongInfo
@end
OMArtistInfo.h
#import <Foundation/Foundation.h>
@interface OMArtistInfo : NSObject
@property (nonatomic ,strong ) NSString *ting_uid;
@property (nonatomic ,strong ) NSString *name;
@property (nonatomic ,strong ) NSString *avatar_big;
@property (nonatomic ,strong ) NSString *avatar_middle;
@end
OMArtistInfo.m
#import "OMArtistInfo.h"
@implementation OMArtistInfo
@end
OMSongInfo.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "AFNetworking.h"
#import "MJExtension.h"
#import "OMHotSongInfo.h"
@interface OMSongInfo : NSObject
+ (OMSongInfo *)sharedManager;
@property (nonatomic ,strong ) UIImage *pic_big;
@property (nonatomic ,strong ) UIImage *pic_small;
@property (nonatomic ,strong ) NSString *song_id;
@property (nonatomic ,strong ) NSString *title;
@property (nonatomic ,strong ) NSString *author;
@property (nonatomic ,strong ) NSString *album_title;
@property (nonatomic ,strong ) NSString *file_duration;
@property (nonatomic ,strong ) NSString *file_link;
@property (nonatomic ,strong ) NSString *file_size;
@property (nonatomic ,strong ) NSString *lrclink;
@property (nonatomic ,assign ) BOOL isLrcExistFlg;
@property (nonatomic ,strong ) NSString *lrcString;
@property (nonatomic ,strong ) NSMutableDictionary *mLRCDictinary;
@property (nonatomic ,strong ) NSMutableArray *mTimeArray;
@property (nonatomic ,assign ) int lrcIndex;
@property (nonatomic ,assign ) long playSongIndex;
@property (nonatomic ,assign ) BOOL isDataRequestFinish;
@property (nonatomic ,strong ) NSArray *OMSongs;
- (void )loadNewSongs: (UITableView *)songListTableView;
- (void )loadHotSongs: (UITableView *)songListTableView;
- (void )loadHotArtists: (UITableView *)songListTableView;
- (void )loadClassicOldSongs: (UITableView *)songListTableView;
- (void )loadLoveSongs: (UITableView *)songListTableView;
- (void )loadMovieSongs: (UITableView *)songListTableView;
- (void )loadEuropeAndTheUnitedStatesSongs: (UITableView *)songListTableView;
-(void )getSelectedSong: (NSString *)songID index: (long )index;
-(void ) setSongInfo: (OMHotSongInfo *)info;
-(NSString *)intToString: (int )needTransformInteger;
-(int ) stringToInt: (NSString *)timeString;
@end
OMSongInfo.m
#import "OMSongInfo.h"
@implementation OMSongInfo
static OMSongInfo *_sharedManager = nil ;
+(OMSongInfo *)sharedManager {
@synchronized( [OMSongInfo class] ){
if (!_sharedManager)
_sharedManager = [[self alloc] init];
return _sharedManager;
}
return nil ;
}
#pragma mark - 获取歌曲url
-(void )getSelectedSong: (NSString *)songID index: (long )index {
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
NSString *path = [@"http://tingapi.ting.baidu.com/v1/restserver/ting?from=qianqian&version=2.1.0&method=baidu.ting.song.play&songid=" stringByAppendingString:songID];
[manager GET:path parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
if ([responseObject isKindOfClass:[NSDictionary class]])
{
NSDictionary *array = [responseObject objectForKey:@"bitrate" ];
self .file_link = [array objectForKey:@"file_link" ];
self .file_size = [array objectForKey:@"file_size" ];
self .file_duration = [array objectForKey:@"file_duration" ];
self .playSongIndex = index;
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog (@"error--%@" ,error);
}];
}
#pragma mark - 设置歌曲的所有信息
-(void ) setSongInfo: (OMHotSongInfo *)info {
self .title = info.title ;
self .author = info.author ;
self .album_title = info.author ;
self .lrclink = info.lrclink ;
NSString *path = info.pic_small ;
if (path)
{
NSURL *url = [NSURL URLWithString:path];
@try {
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *albumArt = [UIImage imageWithData:imageData];
if (albumArt)
{
self .pic_small = albumArt;
}
else
{
self .pic_small = [UIImage imageNamed:@"album_default" ];
}
} @catch (NSException *exception) {
NSLog (@"下载图片出错!" );
}
}
else
{
self .pic_small = [UIImage imageNamed:@"album_default" ];
}
path = info.pic_big ;
if (path)
{
NSURL *url = [NSURL URLWithString:path];
@try {
NSData *imageData = [NSData dataWithContentsOfURL:url];
UIImage *albumArt = [UIImage imageWithData:imageData];
if (albumArt)
{
self .pic_big = albumArt;
}
else
{
self .pic_big = [UIImage imageNamed:@"album_default" ];
}
} @catch (NSException *exception) {
NSLog (@"下载图片出错!" );
}
}
else
{
self .pic_big = [UIImage imageNamed:@"album_default" ];
}
path = info.lrclink ;
if (![path isEqualToString:@"" ] && path != nil )
{
NSURL *url = [NSURL URLWithString:path];
@try {
NSData *lrcData = [NSData dataWithContentsOfURL:url];
NSString *lrcStr = [[NSString alloc] initWithData:lrcData encoding:NSUTF8StringEncoding];
if (![lrcStr isEqualToString:@"" ] && lrcStr != nil ) {
self .lrcString = lrcStr;
self .isLrcExistFlg = true ;
} else {
NSLog (@"获取歌词出错!" );
self .isLrcExistFlg = false ;
}
} @catch (NSException *exception) {
NSLog (@"获取歌词出错!" );
self .isLrcExistFlg = false ;
}
}
else
{
NSLog (@"歌词不存在!" );
self .isLrcExistFlg = false ;
}
}
#pragma mark - int转NSString
-(NSString *)intToString: (int )needTransformInteger {
int wholeTime = needTransformInteger;
int min = wholeTime / 60 ;
int sec = wholeTime % 60 ;
NSString *str = [NSString stringWithFormat:@"%02d:%02d" , min , sec];
return str;
}
#pragma mark - NSString转int
-(int ) stringToInt: (NSString *)timeString {
NSArray *strTemp = [timeString componentsSeparatedByString:@":" ];
int time = [strTemp.firstObject intValue] * 60 + [strTemp.lastObject intValue];
return time;
}
@end
Const.h
#import <Foundation/Foundation.h>
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
#define ScreenWidth ([UIScreen mainScreen].bounds.size.width)
#define ScreenHeight ([UIScreen mainScreen].bounds.size.height)
#define NEW_SONG_LIST 1
#define HOT_SONG_LIST 2
#define OLD_SONG_LIST 22
#define LOVE_SONG_LIST 23
#define INTERNET_SONG_LIST 25
#define MOVIE_SONG_LIST 24
#define EUROPE_SONG_LIST 21
#define BILLBOARD_MUSIC_LIST 8
#define ROCK_MUSIC_LIST 11
#define JAZZ_MUSIC_LIST 12
#define POP_MUSIC_LIST 16
@interface Const : NSObject
@end
Const.m
#import "Const.h"
@implementation Const
@end
TTTopChannelContianerView.h
#import <UIKit/UIKit.h>
@protocol TTTopChannelContianerViewDelegate <NSObject >
@optional
- (void )showOrHiddenAddChannelsCollectionView:(UIButton *)button;
- (void )chooseChannelWithIndex:(NSInteger )index;
@end
@interface TTTopChannelContianerView : UIView
- (instancetype)initWithFrame:(CGRect )frame;
- (void )addAChannelButtonWithChannelName:(NSString *)channelName;
- (void )selectChannelButtonWithIndex:(NSInteger )index;
- (void )deleteChannelButtonWithIndex:(NSInteger )index;
@property (nonatomic , strong ) NSArray *channelNameArray;
@property (nonatomic , weak ) UIScrollView *scrollView;
@property (nonatomic , weak ) id <TTTopChannelContianerViewDelegate> delegate;
@end
TTTopChannelContianerView.m
#import "TTTopChannelContianerView.h"
@interface TTTopChannelContianerView ()
@property (nonatomic , weak ) UIButton *lastSelectedButton;
@property (nonatomic , weak ) UIView *indicatorView;
@end
static CGFloat kTitleLabelNorimalFont = 13 ;
static CGFloat kTitleLabelSelectedFont = 16 ;
static CGFloat kAddChannelWidth = 30 ;
static CGFloat kSliderViewWidth = 20 ;
static CGFloat buttonWidth = 70 ;
@implementation TTTopChannelContianerView
#pragma mark 初始化View
- (instancetype)initWithFrame:(CGRect )frame {
if (self = [super initWithFrame:frame]) {
[self initialization];
}
return self ;
}
#pragma mark channelNameArray的setter方法,channelNameArray
- (void )setChannelNameArray:(NSArray *)channelNameArray {
_channelNameArray = channelNameArray;
self .scrollView .contentSize = CGSizeMake(buttonWidth * channelNameArray.count , 0 );
for (NSInteger i = 0 ; i < channelNameArray.count ; i++) {
UIButton *button = [self createChannelButton];
button.frame = CGRectMake(i*buttonWidth, 0 , buttonWidth, self .frame .size .height );
[button setTitle:channelNameArray[i] forState:UIControlStateNormal];
[self .scrollView addSubview:button];
}
[self clickChannelButton:self .scrollView .subviews [1 ]];
}
#pragma mark 初始化子控件
- (void )initialization {
self .alpha = 0.9 ;
UIScrollView *scrollView = [self createScrollView];
self .scrollView = scrollView;
[self addSubview:self .scrollView ];
UIView *indicatorView = [self createIndicatorView];
self .indicatorView = indicatorView;
[self .scrollView addSubview:self .indicatorView ];
}
#pragma mark 创建容纳channelButton的ScrollView
- (UIScrollView *)createScrollView {
UIScrollView *scrollView = [[UIScrollView alloc] init];
self .scrollView = scrollView;
scrollView.frame = CGRectMake(0 , 0 , [UIScreen mainScreen].bounds .size .width , self .frame .size .height );
scrollView.showsHorizontalScrollIndicator = NO ;
scrollView.showsVerticalScrollIndicator = NO ;
return scrollView;
}
#pragma mark 初始化scrollView右侧的显示阴影效果的imageView
- (UIView *)createSliderView {
UIImageView *slideView = [[UIImageView alloc] init];
slideView.frame = CGRectMake(self .frame .size .width - kSliderViewWidth -kAddChannelWidth, 0 , kSliderViewWidth, self .frame .size .height );
slideView.alpha = 0.9 ;
slideView.image = [UIImage imageNamed:@"slidetab_mask" ];
return slideView;
}
#pragma mark 创建被选中channelButton的红线,也就是indicatorView
- (UIView *)createIndicatorView {
UIView *indicatorView = [[UIView alloc] init];
indicatorView.backgroundColor = [UIColor colorWithRed:243 /255.0 green:75 /255.0 blue:80 /255.0 alpha:1.0 ];
[self addSubview:indicatorView];
return indicatorView;
}
#pragma mark 创建ChannelButton
- (UIButton *)createChannelButton{
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor colorWithRed:255.0 /255.0 green:255.0 /255.0 blue:255.0 /255.0 alpha:1.0 ]];
[button setTitleColor:[UIColor colorWithRed:243 /255.0 green:75 /255.0 blue:80 /255.0 alpha:1.0 ] forState:UIControlStateDisabled];
[button.titleLabel setFont:[UIFont systemFontOfSize:kTitleLabelNorimalFont]];
[button addTarget:self action:@selector (clickChannelButton:) forControlEvents:UIControlEventTouchUpInside];
[button layoutIfNeeded];
return button;
}
#pragma mark 选择了某个ChannelButton
- (void )clickChannelButton:(UIButton *)sender {
self .lastSelectedButton .titleLabel .font = [UIFont systemFontOfSize:kTitleLabelNorimalFont];
self .lastSelectedButton .enabled = YES ;
self .lastSelectedButton = sender;
self .lastSelectedButton .enabled = NO ;
CGFloat newOffsetX = sender.center .x - [UIScreen mainScreen].bounds .size .width *0.5 ;
if (newOffsetX < 0 ) {
newOffsetX = 0 ;
}
if (newOffsetX > self .scrollView .contentSize .width - self .scrollView .frame .size .width ) {
newOffsetX = self .scrollView .contentSize .width - self .scrollView .frame .size .width ;
}
[UIView animateWithDuration:0.25 animations:^{
[sender.titleLabel setFont:[UIFont systemFontOfSize:kTitleLabelSelectedFont]];
[sender layoutIfNeeded];
[self .scrollView setContentOffset:CGPointMake(newOffsetX, 0 )];
self .indicatorView .frame = CGRectMake(sender.frame .origin .x + sender.titleLabel .frame .origin .x - 10 , self .frame .size .height - 2 , sender.titleLabel .frame .size .width + 20 , 2 );
}];
NSInteger index = [self .scrollView .subviews indexOfObject:sender] - 1 ;
if ([self .delegate respondsToSelector:@selector (chooseChannelWithIndex:)]) {
[self .delegate chooseChannelWithIndex:index];
}
}
#pragma mark 选中某个ChannelButton
- (void )selectChannelButtonWithIndex:(NSInteger )index {
self .indicatorView .hidden = NO ;
[self clickChannelButton:self .scrollView .subviews [index+1 ]];
}
#pragma mark 删除某个ChannelButton
- (void )deleteChannelButtonWithIndex:(NSInteger )index {
NSInteger realIndex= index + 1 ;
[self .scrollView .subviews [realIndex] removeFromSuperview];
for (NSInteger i = realIndex; i<self .scrollView .subviews .count ; i++) {
UIButton *button = self .scrollView .subviews [i];
CGRect buttonFrame = button.frame ;
button.frame = CGRectMake(buttonFrame.origin .x - button.frame .size .width , buttonFrame.origin .y , buttonFrame.size .width , buttonFrame.size .height );
}
self .scrollView .contentSize = CGSizeMake(self .scrollView .contentSize .width - self .scrollView .frame .size .width /5 , 0 );
}
#pragma mark 添加新闻频道:增加scrollView的contensize,然后在最后添加一个channelButton
- (void )addAChannelButtonWithChannelName:(NSString *)channelName {
UIButton *button = [self createChannelButton];
self .scrollView .contentSize = CGSizeMake(self .scrollView .contentSize .width + buttonWidth, 0 );
button.frame = CGRectMake(self .scrollView .contentSize .width - buttonWidth , 0 , buttonWidth, self .frame .size .height );
[button setTitle:channelName forState:UIControlStateNormal];
[self .scrollView addSubview:button];
}
@end
SCImageView.h
#import <UIKit/UIKit.h>
@interface SCImageView : UIImageView
-(void ) startRotating;
-(void ) stopRotating;
-(void ) resumeRotate;
@end
SCImageView.m
#import "SCImageView.h"
@implementation SCImageView
-(void ) startRotating {
CABasicAnimation* rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation" ];
rotateAnimation.fromValue = [NSNumber numberWithFloat:0.0 ];
rotateAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2 ];
rotateAnimation.duration = 20.0 ;
rotateAnimation.repeatCount = MAXFLOAT;
[self .layer addAnimation:rotateAnimation forKey:nil ];
}
-(void ) stopRotating {
CFTimeInterval pausedTime = [self .layer convertTime:CACurrentMediaTime() fromLayer:nil ];
self .layer .speed = 0.0 ;
self .layer .timeOffset = pausedTime;
}
-(void ) resumeRotate {
if (self .layer .timeOffset == 0 ) {
[self startRotating];
return ;
}
CFTimeInterval pausedTime = self .layer .timeOffset ;
self .layer .speed = 1.0 ;
self .layer .timeOffset = 0.0 ;
self .layer .beginTime = 0.0 ;
CFTimeInterval timeSincePause = [self .layer convertTime:CACurrentMediaTime() fromLayer:nil ] - pausedTime;
self .layer .beginTime = timeSincePause;
}
@end
SimpleControlView.h
#import <UIKit/UIKit.h>
#define ScreenWidth UIScreen.mainScreen.bounds.size.width
#define ScreenHeight UIScreen.mainScreen.bounds.size.height
@interface SimpleControlView : UIView
@property (nonatomic , strong ) UIImageView *albumImage;
@property (nonatomic , strong ) UILabel *songName;
@property (nonatomic , strong ) UILabel *singerName;
@property (nonatomic , strong ) UIButton *playOrPauseBtn;
@property (nonatomic , strong ) UIButton *nextBtn;
@end
SimpleControlView.m
#import "SimpleControlView.h"
#import "Masonry.h"
#import "Const.h"
@implementation SimpleControlView
-(instancetype) initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame]
if (self) {
[self setBackgroundColor:UIColorFromRGB(0xff0000 )]
//创建imageView添加到SimpleControlView中
_albumImage = [[UIImageView alloc] init]
[self addSubview:_albumImage]
[_albumImage mas_makeConstraints:^(MASConstraintMaker *make) {
make.top .equalTo (self.mas _top).with .offset (5 )
make.left .equalTo (self.mas _left).with .offset (5 )
make.width .mas _equalTo(60 )
make.height .mas _equalTo(60 )
make.bottom .equalTo (self.mas _bottom).with .offset (-5 )
}]
// 创建歌名label添加到SimpleControlView中
_songName = [[UILabel alloc] init]
_songName.font = [UIFont systemFontOfSize:18.0 ]
[_songName setTextColor:UIColorFromRGB(0x000000 )]
[self addSubview:_songName]
[_songName mas_makeConstraints:^(MASConstraintMaker *make) {
make.top .equalTo (self.mas _top).with .offset (5 )
make.left .equalTo (_albumImage.mas _right).with .offset (5 )
make.width .mas _equalTo(150 )
make.height .mas _equalTo(35 )
make.bottom .equalTo (self.mas _bottom).with .offset (-30 )
}]
// 创建歌手名label添加到SimpleControlView中
_singerName = [[UILabel alloc] init]
_singerName.font = [UIFont systemFontOfSize:12.0 ]
[_singerName setTextColor:UIColorFromRGB(0x000000 )]
[self addSubview:_singerName]
[_singerName mas_makeConstraints:^(MASConstraintMaker *make) {
make.top .equalTo (_songName.mas _bottom).with .offset (5 )
make.left .equalTo (_albumImage.mas _right).with .offset (5 )
make.width .mas _equalTo(150 )
make.height .mas _equalTo(20 )
make.bottom .equalTo (self.mas _bottom).with .offset (-5 )
}]
// 创建下一曲按键添加到SimpleControlView中
_nextBtn = [[UIButton alloc] init]
[_nextBtn setImage:[UIImage imageNamed:@"cm2_fm_btn_next" ] forState:UIControlStateNormal]
[_nextBtn setImage:[UIImage imageNamed:@"cm2_fm_btn_next_prs" ] forState:UIControlStateHighlighted]
[self addSubview:_nextBtn]
[_nextBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.top .equalTo (self.mas _top).with .offset (10 )
make.right .equalTo (self.mas _right).with .offset (20 )
make.width .mas _equalTo(50 )
make.height .mas _equalTo(50 )
make.bottom .equalTo (self.mas _bottom).with .offset (-10 )
}]
// 创建播放暂停按键添加到SimpleControlView中
_playOrPauseBtn = [[UIButton alloc] init]
[_playOrPauseBtn setImage:[UIImage imageNamed:@"cm2_fm_btn_pause" ] forState:UIControlStateNormal]
[_playOrPauseBtn setImage:[UIImage imageNamed:@"cm2_fm_btn_pause_prs" ] forState:UIControlStateHighlighted]
[self addSubview:_playOrPauseBtn]
[_playOrPauseBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.top .equalTo (self.mas _top).with .offset (10 )
make.right .equalTo (_nextBtn.mas _right).with .offset (10 )
make.width .mas _equalTo(50 )
make.height .mas _equalTo(50 )
make.bottom .equalTo (self.mas _bottom).with .offset (-10 )
}]
}
return self
}
@end
TopView.h
#import <UIKit/UIKit.h>
@interface TopView : UIView
@property (nonatomic , strong ) UIButton *backBtn;
@property (nonatomic , strong ) UILabel *songTitleLabel;
@property (nonatomic , strong ) UILabel *singerNameLabel;
@end
TopView.m
#import "TopView.h"
@implementation TopView
-(instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
_backBtn = [[UIButton alloc] initWithFrame:CGRectMake(10, 30, 40, 40)];
[_backBtn setImage:[UIImage imageNamed:@"cm2_live_btn_back"] forState:UIControlStateNormal];
[_backBtn setImage:[UIImage imageNamed:@"cm2_live_btn_back_prs"] forState:UIControlStateHighlighted];
[self addSubview:_backBtn];
_songTitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, frame.size.width - 20, frame.size.height / 2)];
[_songTitleLabel setFont:[UIFont systemFontOfSize:20.0]];
[_songTitleLabel setTextColor:[UIColor whiteColor]] ;
[_songTitleLabel setText:@"" ];
_songTitleLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview: _songTitleLabel];
_singerNameLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, frame.size.height / 2 - 20, frame.size.width - 20, frame.size.height / 2 - 30)];
[_singerNameLabel setFont:[UIFont systemFontOfSize:17.0]] ;
[_singerNameLabel setTextColor:[UIColor whiteColor]];
[_singerNameLabel setText:@"" ];
_singerNameLabel.textAlignment = NSTextAlignmentCenter;
[self addSubview: _singerNameLabel];
return self;
}
@end
MidView.h
#import <UIKit/UIKit.h>
#import "SCIconView.h"
#import "SCLrcTableView.h"
@interface MidView : UIScrollView <UIScrollViewDelegate >
@property (nonatomic , strong ) SCIconView* midIconView;
@property (nonatomic , strong ) SCLrcTableView *midLrcView;
@end
MidView.m
#import "MidView.h"
#define Screen_Width ([UIScreen mainScreen].bounds.size.width)
#define Screen_Height ([UIScreen mainScreen].bounds.size.height)
@implementation MidView
-(instancetype)initWithFrame:(CGRect )frame {
self = [super initWithFrame:frame];
self .delegate = self ;
self .showsHorizontalScrollIndicator = false ;
self .pagingEnabled = true ;
self .contentSize = CGSizeMake(Screen_Width * 2 , 0 );
_midIconView = [[SCIconView alloc] initWithFrame:CGRectMake(0 , 0 , self .frame .size .width , frame.size .height )];
[self addSubview:_midIconView];
_midLrcView = [[SCLrcTableView alloc] initWithStyle:UITableViewStylePlain];
[_midLrcView SC_SetUpLrcTableViewFrame:CGRectMake(Screen_Width, 0 , frame.size .width , frame.size .height )];
_midLrcView.tableView .allowsSelection = false ;
_midLrcView.tableView .backgroundColor = [UIColor clearColor];
_midLrcView.tableView .separatorStyle = UITableViewCellSeparatorStyleNone;
_midLrcView.tableView .showsVerticalScrollIndicator = false ;
_midLrcView.tableView .contentInset = UIEdgeInsetsMake(frame.size .height / 2 , 0 , frame.size .height / 2 , 0 );
[self addSubview:_midLrcView.view ];
return self ;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self ) {
}
return self ;
}
-(void ) scrollViewDidScroll: (UIScrollView *)scrollView {
double spread = self .contentOffset .x / Screen_Width;
_midIconView.alpha = 1.0 - spread;
_midLrcView.tableView .alpha = spread;
}
@end
SCLrcTableView.h
#import <UIKit/UIKit.h>
#import "SCLrcTableViewCell.h"
#import "OMSongInfo.h"
@interface SCLrcTableView : UITableViewController
@property (nonatomic , assign ) int Lrc_Index;
@property (nonatomic , assign ) SCLrcTableViewCell *currentCell;
@property (nonatomic , assign ) SCLrcTableViewCell *lrcOldCell;
@property (nonatomic , strong ) UITableView * lockScreenTableView;
@property (nonatomic , assign ) SCLrcTableViewCell *lockCurrentCell;
@property (nonatomic , assign ) SCLrcTableViewCell *loackLrcOldCell;
@property (nonatomic ,assign ) NSInteger currentRow;
@property (nonatomic , assign ) BOOL isDragging;
@property (nonatomic , assign ) int old_Index;
@property (nonatomic , assign ) int mLineNumber;
@property (nonatomic , assign ) BOOL mIsLRCPrepared;
-(instancetype)initWithStyle:(UITableViewStyle)style;
-(void ) SC_SetUpLrcTableViewFrame: (CGRect )frame;
-(void ) setLrc_Index: (int )lrc_index;
-(void ) AnalysisLRC: (NSString *)lrcPath;
-(UIImage *)getBlurredImage:(UIImage *)image;
@end
SCLrcTableView.m
#import "SCLrcTableView.h"
@implementation SCLrcTableView
extern OMSongInfo *songInfo;
-(void ) setLrc_Index: (int )lrc_index {
if (_Lrc_Index == lrc_index || lrc_index > songInfo.mLRCDictinary .count - 1 ) {
return ;
}
id indexPath = [NSIndexPath indexPathForRow:lrc_index inSection:0 ];
[self .tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow: lrc_index inSection:0 ] atScrollPosition:UITableViewScrollPositionMiddle animated:YES ];
UITableViewCell *currentCell = [self .tableView cellForRowAtIndexPath:indexPath];
_currentCell = (SCLrcTableViewCell *)currentCell;
[_currentCell.textLabel setTextColor:[UIColor redColor]];
id oldIndexPath = [NSIndexPath indexPathForRow:_Lrc_Index inSection:0 ];
UITableViewCell *oldCell = [self .tableView cellForRowAtIndexPath:oldIndexPath];
_lrcOldCell = (SCLrcTableViewCell *)oldCell;
[_lrcOldCell.textLabel setTextColor:[UIColor whiteColor]];
[_currentCell addAnimation:scaleAlways];
[_lockScreenTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow: lrc_index inSection:0 ] atScrollPosition:UITableViewScrollPositionMiddle animated:YES ];
UITableViewCell *lockCurrentCell = [_lockScreenTableView cellForRowAtIndexPath:indexPath];
_currentCell = (SCLrcTableViewCell *)lockCurrentCell;
[_currentCell.textLabel setTextColor:[UIColor redColor]];
id lockOldIndexPath = [NSIndexPath indexPathForRow:_Lrc_Index inSection:0 ];
UITableViewCell *lockOldCell = [_lockScreenTableView cellForRowAtIndexPath:lockOldIndexPath];
_lrcOldCell = (SCLrcTableViewCell *)lockOldCell;
[_lrcOldCell.textLabel setTextColor:[UIColor whiteColor]];
_Lrc_Index = lrc_index;
}
-(instancetype)initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self ) {
songInfo.mLRCDictinary = [[NSMutableDictionary alloc] init];
songInfo.mTimeArray = [[NSMutableArray alloc] init];
if (!_lockScreenTableView) {
_lockScreenTableView = [[UITableView alloc] initWithFrame:CGRectMake(0 , 800 - 44 * 7 + 20 , 480 , 44 * 3 ) style:UITableViewStyleGrouped];
_lockScreenTableView.dataSource = self ;
_lockScreenTableView.delegate = self ;
_lockScreenTableView.separatorStyle = NO ;
_lockScreenTableView.backgroundColor = [UIColor clearColor];
[_lockScreenTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"lrccellID" ];
}
}
return self ;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self ) {
}
return self ;
}
-(void ) SC_SetUpLrcTableViewFrame: (CGRect )frame {
self .view .frame = frame;
}
-(void ) AnalysisLRC: (NSString *)lrcStr {
if (songInfo.isLrcExistFlg ) {
NSString * contentStr = lrcStr;
NSArray *lrcArray = [contentStr componentsSeparatedByString:@"\n" ];
[songInfo.mLRCDictinary removeAllObjects];
[songInfo.mTimeArray removeAllObjects];
for (NSString *line in lrcArray) {
if ([line containsString:@"[0" ] || [line containsString:@"[1" ] || [line containsString:@"[2" ] || [line containsString:@"[3" ]) {
NSArray *lineArr = [line componentsSeparatedByString:@"]" ];
NSString *str1 = [line substringWithRange:NSMakeRange(3 , 1 )];
NSString *str2 = [line substringWithRange:NSMakeRange(6 , 1 )];
if ([str1 isEqualToString:@":" ] && [str2 isEqualToString:@"." ]) {
NSString *lrcStr = lineArr[1 ];
NSString *timeStr = [lineArr[0 ] substringWithRange:NSMakeRange(1 , 5 )];
[songInfo.mLRCDictinary setObject:lrcStr forKey:timeStr];
[songInfo.mTimeArray addObject:timeStr];
}
} else {
continue ;
}
}
_mIsLRCPrepared = true ;
[self .tableView reloadData];
} else {
[songInfo.mLRCDictinary removeAllObjects];
[songInfo.mTimeArray removeAllObjects];
[songInfo.mLRCDictinary setObject:@"没有找到该歌词" forKey:@"0:0" ];
[songInfo.mTimeArray addObject:@"0:0" ];
[self .tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0 ] atScrollPosition:UITableViewScrollPositionMiddle animated:NO ];
[self .tableView reloadData];
}
}
-(UIImage *)getBlurredImage:(UIImage *)image{
CIContext *context = [CIContext contextWithOptions:nil ];
CIImage *ciImage=[CIImage imageWithCGImage:image.CGImage ];
CIFilter *filter=[CIFilter filterWithName:@"CIGaussianBlur" ];
[filter setValue:ciImage forKey:kCIInputImageKey];
[filter setValue:@5.0 f forKey:@"inputRadius" ];
CIImage *result=[filter valueForKey:kCIOutputImageKey];
CGImageRef ref=[context createCGImage:result fromRect:[result extent]];
return [UIImage imageWithCGImage:ref];
}
#pragma - mark tableView
-(NSInteger )numberOfSectionsInTableView:(UITableView *)tableView {
return 1 ;
}
-(NSInteger )tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger )section {
return songInfo.mLRCDictinary .count ;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SCLrcTableViewCell *cell = [SCLrcTableViewCell SC_CellForRowWithTableVieW:tableView];
cell.textLabel .text = songInfo.mLRCDictinary [songInfo.mTimeArray [indexPath.row ]];
[cell.textLabel setFont:[UIFont systemFontOfSize:16.0 ]];
cell.textLabel .textAlignment = NSTextAlignmentCenter;
cell.textLabel .lineBreakMode = NSLineBreakByWordWrapping;
[cell setBackgroundColor:[UIColor clearColor]];
cell.textLabel .backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (_currentRow == indexPath.row ) {
cell.textLabel .textColor = [UIColor redColor];
}else {
cell.textLabel .textColor = [UIColor whiteColor];
}
return cell;
}
- (void )scrollViewWillBeginDragging:(UIScrollView *)scrollView{
_isDragging = YES ;
}
- (void )scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
_isDragging = NO ;
}
@end
SCLrcTableViewCell.h
#import <UIKit/UIKit.h>
@interface SCLrcTableViewCell : UITableViewCell
typedef enum SC_AnimationType {
translation,
scale,
rotation,
scaleAlways,
scaleNormal,
}AnimationType;
+(SCLrcTableViewCell *) SC_CellForRowWithTableVieW: (UITableView *) tableView;
-(void )addAnimation: (AnimationType)animationType;
@end
SCLrcTableViewCell.m
#import "SCLrcTableViewCell.h"
@implementation SCLrcTableViewCell
AnimationType *animationType = translation;
- (void )awakeFromNib {
[super awakeFromNib];
}
- (void )setSelected:(BOOL )selected animated:(BOOL )animated {
[super setSelected:selected animated:animated];
}
+(SCLrcTableViewCell *) SC_CellForRowWithTableVieW: (UITableView *) tableView {
NSString *cellID = @"lrccellID" ;
SCLrcTableViewCell *cell = (SCLrcTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID];
if (cell == nil ) {
cell = [[SCLrcTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
[cell setBackgroundColor:[UIColor clearColor]];
}
return cell;
}
-(void )addAnimation: (AnimationType)animationType {
switch (animationType) {
case translation:
{
[self .layer removeAnimationForKey:@"translation" ];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x" ];
animation.values = [NSArray arrayWithObjects:[NSNumber numberWithDouble:50 ], [NSNumber numberWithDouble:0 ], [NSNumber numberWithDouble:50 ], [NSNumber numberWithDouble:0 ], nil ];
animation.duration = 0.7 ;
animation.repeatCount = 1 ;
[self .layer addAnimation:animation forKey:@"translation" ];
break ;
}
case scale:
{
[self .layer removeAnimationForKey:@"scale" ];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x" ];
animation.values = [NSArray arrayWithObjects:[NSNumber numberWithDouble:0.5 ], [NSNumber numberWithDouble:1.0 ], nil ];
animation.duration = 0.7 ;
animation.repeatCount = 1 ;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[self .layer addAnimation:animation forKey:@"scale" ];
break ;
}
case rotation:
{
[self .layer removeAnimationForKey:@"rotation" ];
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z" ];
animation.values = [NSArray arrayWithObjects:[NSNumber numberWithDouble:(-1 / 6 * M_PI)], [NSNumber numberWithDouble:0 ], [NSNumber numberWithDouble:(1 / 6 * M_PI)], [NSNumber numberWithDouble:0 ], nil ];
animation.duration = 0.7 ;
animation.repeatCount = 1 ;
[self .layer addAnimation:animation forKey:@"rotation" ];
break ;
}
case scaleAlways:
{
CABasicAnimation *animatio1 = [CABasicAnimation animationWithKeyPath:@"transform.scale" ];
animatio1.repeatCount = 1 ;
animatio1.duration = 0.6 ;
animatio1.autoreverses = YES ;
animatio1.fromValue = [NSNumber numberWithFloat:1.0 ];
animatio1.toValue = [NSNumber numberWithFloat:1.2 ];
[self .layer addAnimation:animatio1 forKey:@"scale-layer" ];
break ;
}
case scaleNormal:
{
break ;
}
default : break ;
}
}
@end
SCIconView.m
#import "SCIconView.h"
@implementation SCIconView
- (instancetype)initWithFrame:(CGRect )frame
{
self = [super initWithFrame:frame];
if (self ) {
}
return self ;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
return self ;
}
-(void ) setAlbumImage: (UIImage *)image {
_imageView = [[SCImageView alloc] initWithFrame:CGRectMake(self .frame .size .width * 0.1 , self .frame .size .height / 2 - self .frame .size .width * 0.4 , self .frame .size .width * 0.8 , self .frame .size .width * 0.8 )];
_imageView.image = image;
_imageView.clipsToBounds = true ;
_imageView.layer .cornerRadius = self .frame .size .width * 0.4 ;
[self addSubview:_imageView];
}
@end
SCIconView.h
#import <UIKit/UIKit.h>
#import "SCImageView.h"
@interface SCIconView : UIView
@property (nonatomic , strong ) SCImageView *imageView;
- (instancetype)initWithFrame:(CGRect )frame;
-(void ) setAlbumImage: (UIImage *)image;
@end
BottomView.h
#import <UIKit/UIKit.h>
@interface BottomView : UIView
@property (nonatomic , strong ) UIButton *preSongButtton;
@property (nonatomic , strong ) UIButton *nextSongButton;
@property (nonatomic , strong ) UIButton *playOrPauseButton;
@property (nonatomic , strong ) UIButton *playModeButton;
@property (nonatomic , strong ) UIButton *songListButton;
@property (nonatomic , strong ) UISlider *songSlider;
@property (nonatomic , strong ) UILabel *currentTimeLabel;
@property (nonatomic , strong ) UILabel *durationTimeLabel;
@end
BottomView.m
#import "BottomView.h"
@implementation BottomView
-(instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame]
// 上一曲按键设置
_preSongButtton = [[UIButton alloc] initWithFrame:CGRectMake(frame.size .width / 5 , frame.size .height / 2.3 , frame.size .width * 0.2 , frame.size .width * 0.2 )]
[_preSongButtton setImage:[UIImage imageNamed:@"cm2_fm_btn_pre" ] forState:UIControlStateNormal]
[_preSongButtton setImage:[UIImage imageNamed:@"cm2_fm_btn_pre_prs" ] forState:UIControlStateHighlighted]
[self addSubview:_preSongButtton]
// 播放或暂停按键设置
_playOrPauseButton = [[UIButton alloc] initWithFrame:CGRectMake(frame.size .width / 2 - frame.size .width * 0.1 , frame.size .height / 2.3 , frame.size .width * 0.2 , frame.size .width * 0.2 )]
[_playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause" ] forState:UIControlStateNormal]
[_playOrPauseButton setImage:[UIImage imageNamed:@"cm2_fm_btn_pause_prs" ] forState:UIControlStateHighlighted]
[self addSubview:_playOrPauseButton]
// 下一曲按键设置
_nextSongButton = [[UIButton alloc] initWithFrame:CGRectMake(frame.size .width / 5 * 4 - frame.size .width * 0.2 , frame.size .height / 2.3 , frame.size .width * 0.2 , frame.size .width * 0.2 )]
[_nextSongButton setImage:[UIImage imageNamed:@"cm2_fm_btn_next" ] forState:UIControlStateNormal]
[_nextSongButton setImage:[UIImage imageNamed:@"cm2_fm_btn_next_prs" ] forState:UIControlStateHighlighted]
[self addSubview:_nextSongButton]
// 播放模式按键设置
_playModeButton = [[UIButton alloc] initWithFrame:CGRectMake(0 , frame.size .height / 2.3 , frame.size .width * 0.2 , frame.size .width * 0.2 )]
[_playModeButton setImage:[UIImage imageNamed:@"cm2_icn_loop" ] forState:UIControlStateNormal]
[_playModeButton setImage:[UIImage imageNamed:@"cm2_icn_loop_prs" ] forState:UIControlStateHighlighted]
[self addSubview:_playModeButton]
// 歌曲列表按键设置
_songListButton = [[UIButton alloc] initWithFrame:CGRectMake(frame.size .width * 4 / 5 , frame.size .height / 2.3 , frame.size .width * 0.2 , frame.size .width * 0.2 )]
[_songListButton setImage:[UIImage imageNamed:@"cm2_icn_list" ] forState:UIControlStateNormal]
[_songListButton setImage:[UIImage imageNamed:@"cm2_icn_list_prs" ] forState:UIControlStateHighlighted]
[self addSubview:_songListButton]
// 播放进度条
_songSlider = [[UISlider alloc] initWithFrame:CGRectMake(frame.size .width / 6 , frame.size .height / 4 , frame.size .width * 2 / 3 , frame.size .height * 0.2 )]
[_songSlider setThumbImage:[UIImage imageNamed:@"cm2_detail_knob_nomal" ] forState:UIControlStateNormal]
[_songSlider setThumbImage:[UIImage imageNamed:@"cm2_detail_knob_prs" ] forState:UIControlStateHighlighted]
_songSlider.tintColor = [UIColor whiteColor]
[self addSubview:_songSlider]
// 当前播放时间
_currentTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(5 , frame.size .height / 4 , frame.size .width / 6 - 10 , frame.size .height * 0.2 )]
[_currentTimeLabel setTextColor:[UIColor whiteColor]]
[_currentTimeLabel setText:@"00:00" ]
[_currentTimeLabel setFont:[UIFont systemFontOfSize:15.0 ]]
_currentTimeLabel.textAlignment = NSTextAlignmentCenter
[self addSubview:_currentTimeLabel]
// 整歌时间
_durationTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(frame.size .width * 5 / 6 + 5 , frame.size .height / 4 , frame.size .width / 6 - 10 , frame.size .height * 0.2 )]
[_durationTimeLabel setTextColor:[UIColor whiteColor]]
[_durationTimeLabel setText:@"00:00" ]
[_durationTimeLabel setFont:[UIFont systemFontOfSize:15.0 ]]
_durationTimeLabel.textAlignment = NSTextAlignmentCenter
[self addSubview:_durationTimeLabel]
return self
}
@end
SongListTableView.h
#import <UIKit/UIKit.h>
@interface SongListTableView : UITableView <UITableViewDelegate , UITableViewDataSource >
@end
SongListTableView.m
#import "SongListTableView.h"
#import "SongListTableViewCell.h"
#import "MusicPlayerManager.h"
#import "OMSongInfo.h"
#import "OMHotSongInfo.h"
static NSString *CellIdentifier = @"SCTableViewCell" ;
static NSString *PlaceholderCellIdentifier = @"PlaceholderCell" ;
extern MusicPlayerManager *musicPlayer;
extern OMSongInfo *songInfo;
@implementation SongListTableView
-(instancetype) initWithFrame:(CGRect )frame {
self = [super initWithFrame:frame];
if (self ) {
musicPlayer = MusicPlayerManager.sharedManager ;
songInfo = OMSongInfo.sharedManager ;
self .delegate = self ;
self .dataSource = self ;
self .sectionHeaderHeight = 0.1 ;
self .separatorStyle = UITableViewCellSeparatorStyleNone;
self .scrollIndicatorInsets = UIEdgeInsetsMake(104 , 0 , 0 , 0 );
[self reloadData];
}
return self ;
}
#pragma mark - UITableViewDataSource
-(NSInteger )numberOfSectionsInTableView:(UITableView *)tableView
{
return 1 ;
}
-(CGFloat )tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70 ;
}
-(NSInteger ) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger )section {
return songInfo.OMSongs .count ;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
OMHotSongInfo *info = songInfo.OMSongs [indexPath.row ];
SongListTableViewCell *cell = (SongListTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil ) {
cell = [[SongListTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.songNumber .text = [NSString stringWithFormat:@"%ld" , (long )indexPath.row ];
cell.songName .text = info.title ;
cell.singerName .text = info.author ;
return cell;
}
-(void )tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
OMHotSongInfo *info = songInfo.OMSongs [indexPath.row ];
NSLog (@"你选择了《%@》这首歌" , info.title );
[songInfo setSongInfo:info];
[songInfo getSelectedSong:info.song_id index:indexPath.row ];
}
@end
SongListTableViewCell.h
#import <UIKit/UIKit.h>
#import "Masonry.h"
@interface SongListTableViewCell : UITableViewCell
@property (nonatomic , strong ) UILabel *songNumber;
@property (nonatomic , strong ) UILabel *songName;
@property (nonatomic , strong ) UILabel *singerName;
@property (nonatomic , strong ) UIButton *playOrPauseBtn;
@property (nonatomic , strong ) UIButton *nextBtn;
@property (nonatomic , strong ) UIButton *detailControllerBtn;
@end
SongListTableViewCell.m
#import "SongListTableViewCell.h"
@implementation SongListTableViewCell
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]
if (self) {
self.backgroundColor = [UIColor clearColor]
//创建imageView添加到cell中
_songNumber = [[UILabel alloc] init]
_songNumber.font = [UIFont systemFontOfSize:20.0 ]
_songNumber.textColor = [UIColor blackColor]
_songNumber.textAlignment = NSTextAlignmentCenter
[self addSubview:_songNumber]
[_songNumber mas_makeConstraints:^(MASConstraintMaker *make) {
make.top .equalTo (self.mas _top).with .offset (5 )
make.left .equalTo (self.mas _left).with .offset (5 )
make.width .mas _equalTo(60 )
make.height .mas _equalTo(60 )
make.bottom .equalTo (self.mas _bottom).with .offset (-5 )
}]
// 创建歌名label添加到cell中
_songName = [[UILabel alloc] init]
_songName.font = [UIFont systemFontOfSize:18.0 ]
_songName.textColor = [UIColor blackColor]
[self addSubview:_songName]
[_songName mas_makeConstraints:^(MASConstraintMaker *make) {
make.top .equalTo (self.mas _top).with .offset (5 )
make.left .equalTo (_songNumber.mas _right).with .offset (5 )
make.width .mas _equalTo(150 )
make.height .mas _equalTo(35 )
make.bottom .equalTo (self.mas _bottom).with .offset (-30 )
}]
// 创建歌手名label添加到cell中
_singerName = [[UILabel alloc] init]
_singerName.font = [UIFont systemFontOfSize:12.0 ]
_singerName.textColor = [UIColor blackColor]
[self addSubview:_singerName]
[_singerName mas_makeConstraints:^(MASConstraintMaker *make) {
make.top .equalTo (_songName.mas _bottom).with .offset (5 )
make.left .equalTo (_songNumber.mas _right).with .offset (5 )
make.width .mas _equalTo(150 )
make.height .mas _equalTo(20 )
make.bottom .equalTo (self.mas _bottom).with .offset (-5 )
}]
}
return self
}
@end
SongListTopView.h
#import <UIKit/UIKit.h>
@interface SongListTopView : UIView
@property (nonatomic , strong ) UIButton *playMode;
@end
SongListTopView.m
#import "SongListTopView.h"
@implementation SongListTopView
-(instancetype) initWithFrame:(CGRect )frame {
self = [super initWithFrame:frame];
if (self ) {
_playMode = [[UIButton alloc] initWithFrame:CGRectMake(0 , 0 , self .frame .size .width / 2.5 , self .frame .size .height )];
[self addSubview:_playMode];
}
return self ;
}
@end
SongListView.h
#import <UIKit/UIKit.h>
#import "OMSongInfo.h"
#import "MusicPlayerManager.h"
#import "SongListTopView.h"
#import "SongListTableView.h"
#import "Const.h"
#import "MBProgressHUD.h"
@interface SongListView : UIView
@property (nonatomic , strong ) SongListTopView *topView;
@property (nonatomic , strong ) SongListTableView *tableView;
-(void ) setPlayModeButtonState;
@end
SongListView.m
#import "SongListView.h"
@implementation SongListView
extern MusicPlayerManager *musicPlayer;
extern OMSongInfo *songInfo;
-(instancetype) initWithFrame:(CGRect )frame {
self = [super initWithFrame:frame];
if (self ) {
musicPlayer = MusicPlayerManager.sharedManager ;
songInfo = OMSongInfo.sharedManager ;
_topView = [[SongListTopView alloc] initWithFrame:CGRectMake(0 , 0 , self .frame .size .width , self .frame .size .height / 9 )];
_topView.backgroundColor = UIColorFromRGB(0xaaaaaa );
[_topView.playMode addTarget:self action:@selector (playModeButtonAction) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:_topView];
_tableView = [[SongListTableView alloc] initWithFrame:CGRectMake(0 , self .frame .size .height / 9 , self .frame .size .width , self .frame .size .height / 9 * 8 )];
_tableView.backgroundColor = [UIColor whiteColor];
[self addSubview:_tableView];
}
return self ;
}
-(void ) setPlayModeButtonState {
switch (musicPlayer.shuffleAndRepeatState )
{
case RepeatPlayMode:
{
NSString *title = [NSString stringWithFormat:@"顺序播放(%lu)" , (unsigned long )songInfo.OMSongs .count ];
[_topView.playMode setTitle:title forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_loop" ] forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_loop_prs" ] forState:UIControlStateHighlighted];
musicPlayer.shuffleAndRepeatState = RepeatPlayMode;
}
break ;
case RepeatOnlyOnePlayMode:
{
NSString *title = [NSString stringWithFormat:@"单曲循环(%lu)" , (unsigned long )songInfo.OMSongs .count ];
[_topView.playMode setTitle:title forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_one" ] forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_one_prs" ] forState:UIControlStateHighlighted];
musicPlayer.shuffleAndRepeatState = RepeatOnlyOnePlayMode;
}
break ;
case ShufflePlayMode:
{
NSString *title = [NSString stringWithFormat:@"随机播放(%lu)" , (unsigned long )songInfo.OMSongs .count ];
[_topView.playMode setTitle:title forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_shuffle" ] forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_shuffle_prs" ] forState:UIControlStateHighlighted];
musicPlayer.shuffleAndRepeatState = ShufflePlayMode;
}
break ;
default :
break ;
}
}
-(void ) playModeButtonAction {
switch (musicPlayer.shuffleAndRepeatState )
{
case RepeatPlayMode:
{
NSString *title = [NSString stringWithFormat:@"单曲循环(%lu)" , (unsigned long )songInfo.OMSongs .count ];
[_topView.playMode setTitle:title forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_one" ] forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_one_prs" ] forState:UIControlStateHighlighted];
[self showMiddleHint:@"单曲循环" ];
musicPlayer.shuffleAndRepeatState = RepeatOnlyOnePlayMode;
}
break ;
case RepeatOnlyOnePlayMode:
{
NSString *title = [NSString stringWithFormat:@"随机播放(%lu)" , (unsigned long )songInfo.OMSongs .count ];
[_topView.playMode setTitle:title forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_shuffle" ] forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_shuffle_prs" ] forState:UIControlStateHighlighted];
[self showMiddleHint:@"随机播放" ];
musicPlayer.shuffleAndRepeatState = ShufflePlayMode;
}
break ;
case ShufflePlayMode:
{
NSString *title = [NSString stringWithFormat:@"顺序播放(%lu)" , (unsigned long )songInfo.OMSongs .count ];
[_topView.playMode setTitle:title forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_loop" ] forState:UIControlStateNormal];
[_topView.playMode setImage:[UIImage imageNamed:@"cm2_icn_loop_prs" ] forState:UIControlStateHighlighted];
[self showMiddleHint:@"顺序播放" ];
musicPlayer.shuffleAndRepeatState = RepeatPlayMode;
}
break ;
default :
break ;
}
}
#pragma mark - 播放模式提示框
- (void )showMiddleHint:(NSString *)hint {
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self .superview animated:YES ];
hud.userInteractionEnabled = NO ;
hud.mode = MBProgressHUDModeText;
hud.label .font = [UIFont systemFontOfSize:15 ];
hud.label .text = hint;
hud.margin = 10. f;
hud.offset = CGPointMake(0. f, 0. f);
hud.removeFromSuperViewOnHide = YES ;
[hud hideAnimated:YES afterDelay:2. f];
}
@end