QQ音乐播放的过程中,锁屏状态下的效果如下:
也就是说,QQ音乐播放过程中,添加锁屏远程事件的监听。
本文只记录本人知道的小知识点,不提供完整的代码。
实现的原理:
(1)获取锁屏歌曲信息中心:MPNowPlayingInfoCenter
(2)设置锁屏下要显示的歌曲的信息
(3)启动远程事件的监听
1.MPNowPlayingInfoCenter简要说明:
(1)官方文档对MPNowPlayingInfoCenter的解说如下:
// -----------------------------------------------------------------------------
// MPNowPlayingInfoCenter provides an interface for setting the current now
// playing information for the application. This information will be displayed
// wherever now playing information typically appears, such as the lock screen
// and app switcher. The now playing info dictionary contains a group of
// metadata properties for a now playing item. The list of property constants
// is available in <MediaPlayer/MPMediaItem.h>. The properties which are
// currently supported include:
//
// MPMediaItemPropertyAlbumTitle
// MPMediaItemPropertyAlbumTrackCount
// MPMediaItemPropertyAlbumTrackNumber
// MPMediaItemPropertyArtist
// MPMediaItemPropertyArtwork
// MPMediaItemPropertyComposer
// MPMediaItemPropertyDiscCount
// MPMediaItemPropertyDiscNumber
// MPMediaItemPropertyGenre
// MPMediaItemPropertyPersistentID
// MPMediaItemPropertyPlaybackDuration
// MPMediaItemPropertyTitle
//
// In addition, metadata properties specific to the current playback session
// may also be specified -- see "Additional metadata properties" below.
上面那段话大体的意思如下:
MPNowPlayingInfoCenter(播放信息中心)为应用程序提供设置当前正在播放的信息的接口; 此信息将显示在正在播放信息类型调用的任何位置,例如锁屏下或者应用程序切换中; 正在播放的信息字典包含一组正在播放项的元数据属性,这些属性常量列表在<MediaPlayer/MPMediaItem.h>有提供; 这些属性目前提供的包括: MPMediaItemPropertyAlbumTitle (标题) MPMediaItemPropertyAlbumTrackCount(专辑歌曲数) MPMediaItemPropertyAlbumTrackNumber (专辑歌曲编号) MPMediaItemPropertyArtist (艺术家/歌手) MPMediaItemPropertyArtwork (封面图片 MPMediaItemArtwork 类型) MPMediaItemPropertyComposer (作曲) MPMediaItemPropertyDiscCount (专辑数) MPMediaItemPropertyDiscNumber (专辑编号) MPMediaItemPropertyGenre (类型\流派) MPMediaItemPropertyPersistentID (唯一标识符) MPMediaItemPropertyPlaybackDuration (歌曲时长) MPMediaItemPropertyTitle (歌曲名称) 此外,音乐播放必须支持后台播放的功能。
另外,当前播放信息中心还提供了一个方法和一个属性如下:
/// Returns the default now playing info center.
/// The default center holds now playing info about the current application.
+ (MPNowPlayingInfoCenter *)defaultCenter;/// The current now playing info for the center.
/// Setting the info to nil will clear it.
@property (nonatomic, copy, nullable) NSDictionary<NSString *, id> *nowPlayingInfo;
也就是说,可以用defaultCenter来获取当前的MPNowPlayingInfoCenter,然后在 nowPlayingInfo 以字典的形式设置 锁屏中的歌曲信息。
其中,这个类,还提供了一些额外的元组属性,如下:
MP_EXTERN NSString *const MPNowPlayingInfoPropertyElapsedPlaybackTime 当前时间 NSNumber
MP_EXTERN NSString *const MPNowPlayingInfoPropertyPlaybackRate
MP_EXTERN NSString *const MPNowPlayingInfoPropertyDefaultPlaybackRate
MP_EXTERN NSString *const MPNowPlayingInfoPropertyPlaybackQueueIndex
MP_EXTERN NSString *const MPNowPlayingInfoPropertyPlaybackQueueCount
MP_EXTERN NSString *const MPNowPlayingInfoPropertyChapterNumber
MP_EXTERN NSString *const MPNowPlayingInfoPropertyChapterCount
MP_EXTERN NSString *const MPNowPlayingInfoPropertyAvailableLanguageOptions MPNowPlayingInfoLanguageOptionGroup
MP_EXTERN NSString *const MPNowPlayingInfoPropertyCurrentLanguageOptions
找到了一个对这些属性解说不错的文档:
蹩脚英文翻译系列:(未标注版本的键均为iOS8及以下可用)
Name | Type | meaning |
---|---|---|
MPMediaItemPropertyAlbumTitle | NSString | 专辑歌曲数 |
MPMediaItemPropertyAlbumTrackCount | NSNumber of NSUInteger | 专辑歌曲数 |
MPMediaItemPropertyAlbumTrackNumber | NSNumber of NSUInteger | 艺术家/歌手 |
MPMediaItemPropertyArtist | NSString | 艺术家/歌手 |
MPMediaItemPropertyArtwork | MPMediaItemArtwork | 封面图片 MPMediaItemArtwork类型 |
MPMediaItemPropertyComposer | NSString | 作曲 |
MPMediaItemPropertyDiscCount | NSNumber of NSUInteger | 专辑数 |
MPMediaItemPropertyDiscNumber NSNumber of NSUInteger | 专辑编号 | |
MPMediaItemPropertyGenre | NSString | 类型/流派 |
MPMediaItemPropertyPersistentID | NSNumber of uint64_t | 唯一标识符 |
MPMediaItemPropertyPlaybackDuration | NSNumber of NSTimeInterval | 歌曲时长 NSNumber类型 |
MPMediaItemPropertyTitle | NSString | 歌曲名称 |
MPNowPlayingInfoPropertyElapsedPlaybackTime | NSNumber (double) | 在播资源的时间流逝,s为单位。流逝时间会从播放时间和播放速率中自动计算,不合适频繁得更新 |
MPNowPlayingInfoPropertyPlaybackRate | NSNumber (double) | 在播资源的速率(保持与APP内播放器的速率一致) |
MPNowPlayingInfoPropertyDefaultPlaybackRate | NSNumber (double) | 在播资源的“默认”播放速率,当你的APP需要播放资源的播放速率默认都是大于1的,那么就应该使用这属性 |
MPNowPlayingInfoPropertyPlaybackQueueIndex | NSNumber (NSUInteger) | 应用重放队列中,当前播放项的索引。注意索引值从0开始 |
MPNowPlayingInfoPropertyPlaybackQueueCount | NSNumber (NSUInteger) | 应用重放队列的总资源数目 |
MPNowPlayingInfoPropertyChapterNumber | NSNumber (NSUInteger) | 这在播放的部分,索引值从0开始 |
MPNowPlayingInfoPropertyChapterCount | NSNumber (NSUInteger) | 在播资源的总章节数目 |
MPNowPlayingInfoPropertyIsLiveStream(iOS 10.0) | NSNumber (BOOL) | 表示当前的资源是不是实时流 |
MPNowPlayingInfoPropertyAvailableLanguageOptions(iOS 9.0) | NSArrayRef of MPNowPlayingInfoLanguageOptionGroup | 在播资源的一组可用的语言类型。在给定组中一次只能播放一种语言类型的资源 |
MPNowPlayingInfoPropertyCurrentLanguageOptions(iOS 9.0) | NSArray of MPNowPlayingInfoLanguageOption | 当前播放项目的语言选项列表 |
MPNowPlayingInfoCollectionIdentifier(iOS 9.3) | NSString | 表示当前播放资源所归属的那个集合的标识符,可指作者、专辑、播放列表等。可用于请求重新播放这个集合。 |
MPNowPlayingInfoPropertyExternalContentIdentifier(iOS 10.0) | NSString | 一个不暴露的唯一标志符,标志当前正在播放的item,贯穿APP重启。可使用任何格式,仅用于引用这个item和返回到正在播放资源的APP中 |
MPNowPlayingInfoPropertyExternalUserProfileIdentifier(iOS 10.0) | NSString | 一个可选型的不暴露的标志,标志当前正在播放的资源的配置文件,贯穿APP重启。可使用任何格式,仅用于返回到这个配置文件对应的正在播放视频的APP |
MPNowPlayingInfoPropertyServiceIdentifier(iOS 11.0) | NSString | 服务商的唯一标志。如果当前播放的资源属于一个频道或者是定于的服务类型,这个ID可以用于区分和协调特定服务商的多种资源类型 |
MPNowPlayingInfoPropertyPlaybackProgress(iOS 10.0) | NSNumber (float) | 表示当前播放资源的播放进度,0.0表示未开始,1.0表示完全浏览完。区分于ElapsedPlaybackTime,无需更高的精度要求。如:当字幕开始滚动时,这个电影可能被用户期望开始播放(由字幕驱动播放进度) |
MPNowPlayingInfoPropertyMediaType | NSNumber (MPNowPlayingInfoMediaType) | 指定当前媒体类型,用于确定系统显示的用户界面类型 |
MPNowPlayingInfoPropertyAssetURL(iOS 10.3) | NSURL | 指向当前正播放的视频或音频资源的URL。可将视频缩略图或者音频的波普图使用于系统的UI上 |
2.锁屏下要显示歌曲信息的设置
从上文中,已经可以知道,用
MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
来获取锁屏信息控制中心,然后把锁屏情况下要显示的图片、歌曲名字、歌手、歌词、时间等信息以字典的形式赋值给center的nowPlayInfo属性。
示例代码如下:
MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
NSMutableDictionary *infoDic = [NSMutableDictionary dictionary];
[infoDic setObject:@"泡沫" forKey:MPMediaItemPropertyAlbumTitle];
[infoDic setObject:@"歌手" forKey:MPMediaItemPropertyArtist];
[infoDic setObject:[[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"61149b0491243c749fc871e67550a7f6"]] forKey:MPMediaItemPropertyArtwork];
[infoDic setObject:@"" forKey:MPMediaItemPropertyPlaybackDuration];
[infoDic setObject:@"歌词" forKey:MPMediaItemPropertyTitle];
center.nowPlayingInfo = infoDic;
3.锁屏远程事件的监听的简要说明:
(1)ios71.版本
可以用的是[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
然后监听remoteControlReceivedWithEvent:这个方法,
event的类中有UIEventSubtype的subtype。
subtype的类型如下:
typedef NS_ENUM(NSInteger, UIEventSubtype) {
// available in iPhone OS 3.0
UIEventSubtypeNone = , // for UIEventTypeMotion, available in iPhone OS 3.0
UIEventSubtypeMotionShake = , // for UIEventTypeRemoteControl, available in iOS 4.0
UIEventSubtypeRemoteControlPlay = , //播放
UIEventSubtypeRemoteControlPause = , //暂停
UIEventSubtypeRemoteControlStop = , //停止
UIEventSubtypeRemoteControlTogglePlayPause = , //耳机上的播放暂停命令
UIEventSubtypeRemoteControlNextTrack = , //下一首
UIEventSubtypeRemoteControlPreviousTrack = , //上一首
UIEventSubtypeRemoteControlBeginSeekingBackward = , //开始后退
UIEventSubtypeRemoteControlEndSeekingBackward = , //后退结束
UIEventSubtypeRemoteControlBeginSeekingForward = , //开始快进
UIEventSubtypeRemoteControlEndSeekingForward = , //快进结束
};
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
NSLog(@"---event.type = %ld", (long)event.subtype);
//在这里面监听操作的类型
}
(2)iOS7.1以后
可以使用MPRemoteCommandCenter这个类的方法,这个类提供了一个类方法:sharedCommandCenter;
提供一个不错可参考的链接:https://www.jianshu.com/p/b9cc97db16b8
MPRemoteCommandCenter是获取到这个单例对象后,使用共享的这个MPRemoteCommand对象,用于响应各种远程控制事件配置自己的需求。
如:像网易云音乐一样,在锁屏以及多媒体系统UI界面配置滑动播放进度(seekTime),下一曲,上一曲,喜欢,不喜欢等配置;
MPRemoteCommandCenter提供的配置信息如下:
// Playback Commands
@property (nonatomic, readonly) MPRemoteCommand *pauseCommand; //暂停
@property (nonatomic, readonly) MPRemoteCommand *playCommand; //播放
@property (nonatomic, readonly) MPRemoteCommand *stopCommand; //停止
@property (nonatomic, readonly) MPRemoteCommand *togglePlayPauseCommand; //耳机线控制暂停和播放
@property (nonatomic, readonly) MPRemoteCommand *enableLanguageOptionCommand MP_API(ios(9.0), macos(10.12.)); //不知
@property (nonatomic, readonly) MPRemoteCommand *disableLanguageOptionCommand MP_API(ios(9.0), macos(10.12.)); //不知
@property (nonatomic, readonly) MPChangePlaybackRateCommand *changePlaybackRateCommand; //不知
@property (nonatomic, readonly) MPChangeRepeatModeCommand *changeRepeatModeCommand; //不知
@property (nonatomic, readonly) MPChangeShuffleModeCommand *changeShuffleModeCommand; 不知 // Previous/Next Track Commands
@property (nonatomic, readonly) MPRemoteCommand *nextTrackCommand; //下一首
@property (nonatomic, readonly) MPRemoteCommand *previousTrackCommand; //上一首 // Skip Interval Commands
@property (nonatomic, readonly) MPSkipIntervalCommand *skipForwardCommand; //快进几秒(如果与下一首同时设置,优先显示快进)
@property (nonatomic, readonly) MPSkipIntervalCommand *skipBackwardCommand; //快退几秒(如果与上一首同时设置,优先显示快退) // Seek Commands
@property (nonatomic, readonly) MPRemoteCommand *seekForwardCommand; //不知
@property (nonatomic, readonly) MPRemoteCommand *seekBackwardCommand; //不知
@property (nonatomic, readonly) MPChangePlaybackPositionCommand *changePlaybackPositionCommand MP_API(ios(9.1), macos(10.12.)); // Rating Command
@property (nonatomic, readonly) MPRatingCommand *ratingCommand; //设置倍速,不知道在哪里显示 // Feedback Commands
// These are generalized to three distinct actions. Your application can provide
// additional context about these actions with the localizedTitle property in
// MPFeedbackCommand.
@property (nonatomic, readonly) MPFeedbackCommand *likeCommand; //设置喜欢
@property (nonatomic, readonly) MPFeedbackCommand *dislikeCommand; //设置不喜欢
@property (nonatomic, readonly) MPFeedbackCommand *bookmarkCommand; //添加标签
设置的方式如下:
MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter];
//添加暂停监听
[rcc.pauseCommand addTarget:self action:@selector(playOrPauseEvent:)];
整体的代码如下:
//
// ViewController.m
// 音效播放
//
// Created by 珠珠 on 2019/10/31.
// Copyright © 2019 珠珠. All rights reserved.
// #import "ViewController.h" #import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h> @interface ViewController () @property (nonatomic,strong) AVAudioPlayer *player ; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad]; //设置音乐的后台播放,注意background mode中需要勾选上
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil]; //获取信息中心
MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
//设置要锁屏要显示的基本信息
NSMutableDictionary *infoDic = [NSMutableDictionary dictionary];
[infoDic setObject:@"泡沫" forKey:MPMediaItemPropertyAlbumTitle];
[infoDic setObject:@"歌手" forKey:MPMediaItemPropertyArtist];
[infoDic setObject:[[MPMediaItemArtwork alloc] initWithImage:[UIImage imageNamed:@"61149b0491243c749fc871e67550a7f6"]] forKey:MPMediaItemPropertyArtwork];
[infoDic setObject:@"" forKey:MPMediaItemPropertyPlaybackDuration];
[infoDic setObject:@"歌词" forKey:MPMediaItemPropertyTitle];
//给信息中心赋值
center.nowPlayingInfo = infoDic;
//添加远程事件监听
NSString *version= [UIDevice currentDevice].systemVersion;
if(version.doubleValue <=7.1) {
//iOS版本7.1以下的建议使用这个方法
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
}else{
//iOS版本7.1以上的的建议使用这个方法
[self addRemoteCommandCenter];
}
} #pragma mark - 基本播放操作
//开始播放
- (IBAction)player:(id)sender {
[self.player play]; UIView *view = [[UIView alloc] initWithFrame:CGRectMake(, , , )];
[self.view addSubview:view];
} //暂停播放
- (IBAction)pause:(id)sender {
[self.player pause];
} //停止播放
- (IBAction)stop:(id)sender {
[self.player stop];
} //前进5秒
- (IBAction)qianJin5s:(id)sender {
self.player.currentTime += ;
} //后退5秒
- (IBAction)houTui5s:(id)sender {
self.player.currentTime -= ;
} //2倍速度播放
- (IBAction)faster:(id)sender {
self.player.rate = ;
} //播放一次
- (IBAction)playOnce:(id)sender {
self.player.numberOfLoops = ;
} //播放3次
- (IBAction)playThirst:(id)sender {
self.player.numberOfLoops = ;
} //循环播放
- (IBAction)playAllTheTime:(id)sender {
self.player.numberOfLoops = -;
} //听筒播放
- (IBAction)tingTongPlay:(id)sender {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions: error:nil];
} //扬声器播放
- (IBAction)outSpeakerPlayer:(id)sender {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
} #pragma mark - MPRemoteCommandCenter相关的方法
- (void)addRemoteCommandCenter {
MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter];
//添加暂停监听
[rcc.pauseCommand addTarget:self action:@selector(playOrPauseEvent:)];
//添加播放监听
[rcc.playCommand addTarget:self action:@selector(playOrPauseEvent:)];
//下一首
[rcc.nextTrackCommand addTarget:self action:@selector(nextCommandEvent:)];
//上一首
[rcc.previousTrackCommand addTarget:self action:@selector(previousTrackCommand:)];
//耳机暂停和播放的监听
[rcc.togglePlayPauseCommand addTarget:self action:@selector(togglePlayPauseCommand:)];
//快进(如果同时设置了下一首和快进,那么锁屏下只会显示快进的按钮)
[rcc.skipForwardCommand addTarget:self action:@selector(handleSkipForward:)];
[rcc.skipForwardCommand setPreferredIntervals:@[@()]]; // 设置快进时间(最大 99)
//快退(如果同时设置了下一首和后退,那么锁屏下只会显示快退的按钮)
[rcc.skipBackwardCommand addTarget:self action:@selector(handleSkipBack:)];
[rcc.skipBackwardCommand setPreferredIntervals:@[@]]; // 设置快退时间(最大99) // [self feedbackCommand]
} - (void)playOrPauseEvent:(MPRemoteCommand *)command
{
NSLog(@"播放或者暂停");
if (self.player.isPlaying) {
[self.player pause];
}else {
[self.player play];
}
} - (void)nextCommandEvent:(MPRemoteCommand *)command
{
NSLog(@"%@",@"下一曲");
} - (void)previousTrackCommand:(MPRemoteCommand *)command
{
NSLog(@"%@",@"上一曲");
} - (void)togglePlayPauseCommand:(MPRemoteCommand *)command {
NSLog(@"耳机的开始和暂停");
if (self.player.isPlaying) {
[self.player pause];
}else {
[self.player play];
}
} - (void)handleSkipForward:(MPRemoteCommand *)command
{
NSLog(@"快进%@",command);
} - (void)handleSkipBack:(MPRemoteCommand *)command
{
NSLog(@" 快退%@",command);
} -(void)feedbackCommand:(MPRemoteCommandCenter *)rcc
{
MPFeedbackCommand *likeCommand = [rcc likeCommand];
[likeCommand setEnabled:YES];
[likeCommand setLocalizedTitle:@"I love it"]; // can leave this out for default
[likeCommand addTarget:self action:@selector(likeEvent:)]; MPFeedbackCommand *dislikeCommand = [rcc dislikeCommand];
[dislikeCommand setEnabled:YES];
[dislikeCommand setActive:YES];
[dislikeCommand setLocalizedTitle:@"I hate it"]; // can leave this out for default
[dislikeCommand addTarget:self action:@selector(dislikeEvent:)]; BOOL userPreviouslyIndicatedThatTheyDislikedThisItemAndIStoredThat = YES; if (userPreviouslyIndicatedThatTheyDislikedThisItemAndIStoredThat) {
[dislikeCommand setActive:YES];
} MPFeedbackCommand *bookmarkCommand = [rcc bookmarkCommand];
[bookmarkCommand setEnabled:YES];
[bookmarkCommand addTarget:self action:@selector(bookmarkEvent:)];
} -(void)dislikeEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
NSLog(@"Mark the item disliked");
}
-(void)likeEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
NSLog(@"Mark the item liked");
}
-(void)bookmarkEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
NSLog(@"Bookmark the item or playback position");
} #pragma mark - 远程事件的监听:[[UIApplication sharedApplication] beginReceivingRemoteControlEvents]
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
NSLog(@"---event.type = %ld", (long)event.subtype);
} #pragma mark - 懒加载播放器
- (AVAudioPlayer *)player {
if (!_player) {
//获取播放的路径 paomo.mp3 2018-11-27 10_36_51 1.wav
NSURL *path = [[NSBundle mainBundle] URLForResource:@"paomo.mp3" withExtension:nil];
//根据路径创建播放对象
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:path error:nil]; //如果这个属性不设置的话,那么不能设置倍速播放的功能
player.enableRate = YES; //准备播放
[player prepareToPlay];
_player = player; }
return _player;
} @end
另参考链接:http://www.cocoachina.com/articles/15767
OC-音乐播放器-锁屏处理的更多相关文章
-
iOS 音乐播放器之锁屏效果+歌词解析
概述 功能描述:锁屏歌曲信息.控制台远程控制音乐播放:暂停/播放.上一首/下一首.快进/快退.列表菜单弹框和拖拽控制台的进度条调节进度(结合了QQ音乐和网易云音乐在锁屏状态下的效果).歌词解析并随音乐 ...
-
swift 音乐播放器项目-《lxy的杰伦情歌》开发实战演练
近期准备将项目转化为OC与swift混合开发.试着写一个swift音乐播放器的demo,体会到了swift相对OC的优势所在.废话不多说.先上效果图: watermark/2/text/aHR0cDo ...
-
轻仿QQ音乐之音频歌词播放、锁屏歌词-b
先上效果图 歌词播放界面 音乐播放界面 锁屏歌词界面 一. 项目概述 前面内容实在是太基础..只想看知识点的同学可以直接跳到第三部分的干货 项目播放的mp3文件及lrc文件均来自QQ音乐 本文主要主要 ...
-
iOS商城demo、音乐播放器、视频通话、自定义搜索、转场动画等源码
iOS精选源码 微信自定义搜索框实现 一个商城Demo,持续更新中 在Object-C中学习数据结构与算法之排序算法 iOS 音乐播放器之锁屏歌词+歌词解析+锁屏效果 XLsn0wPushTimePi ...
-
iOS电商常见动画与布局、微信悬浮窗、音乐播放器、歌词解析、拖动视图等源码
iOS精选源码 MXScroll 介绍 混合使用UIScrollView ios 电商demo(实现各种常见动画效果和页面布局) 一行代码集成微信悬浮窗 可拖动,大小的视图,可放置在屏幕边缘. 在使用 ...
-
Swift 3 :基于 AVAudioPlayer 的简单音乐播放器
2017.05.22 17:46* 字数 1585 阅读 5095评论 0喜欢 8赞赏 2 https://www.jianshu.com/p/4d5c257428a1 学习ios以来差不多接近两个月 ...
-
iOS音乐播放器相关
iOS音乐播放器框架主要有两大类:AvPlayer.AvaudioPlayer AvPlayer 能播放本地及网络歌曲 AvaudioPlayer 能播放本地歌曲.有相关代理方法(其实也可以播放网络歌 ...
-
【竞品分析】Android音乐播放器的竞品分析
迄今为止最长的一篇博客,各位看官笑纳~~ 本次分析基于Android平台,选取了几款我体验过的播放器进行比较分析.主要分为两类,一类是大而全的,功能全面,可满足用户管理歌曲.导入导出歌单等多方面需求, ...
-
酷狗、QQ、天天动听——手机音乐播放器竞品对比
如果说什么艺术与人们生活最贴近,那应该属音乐了,因此当代人不离身的手机里必然会有自己喜欢的音乐播放器APP存在. 在当今无论PC端还是手机端音乐播放器都越来越同质化,我们应该选择哪款手机音乐播放器?它 ...
随机推荐
-
python的变量传递
python中变量都被视为对象的引用.python函数调用传递参数的时候,不允许程序员选择传值还是传引用,python参数传递采用的都是“传对象引用”的方式. 这种方式相当于传值和传引用的结合 ...
-
HTML5 格式化、样式、链接、表格
HTML格式化.样式.链接.表格的使用举例
-
『NOIP2018普及组题解』
标题统计 题目描述 凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符? 注意:标题中可能包含大.小写英文字母.数字字符.空格和换行符.统计标题字 符数时,空格和换行符不计算在内. 输入格式 ...
-
7.2 if else 语句
7.2 if else 语句 if else语句的通用形式是: if ( expression ) statement1 else statement2 如果expression为真(非0),则执行s ...
-
nginx学习笔记(三)
浏览器缓存
-
HDU 1796 (容斥原理)
容斥原理练习题,忘记处理gcd 和 lcm,wa了几发0.0. #include<iostream> #include<cstdio> #include<cstring& ...
-
ThreadLocal用法详解和原理
一.用法 ThreadLocal用于保存某个线程共享变量:对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量. 1.Thr ...
-
FZU 2273 Triangles 第八届福建省赛 (三角形面积交 有重边算相交)
Problem Description This is a simple problem. Given two triangles A and B, you should determine they ...
-
idea创建maven spring项目,出现的问题
1.jetty启动后,明明配置文件配置的是 <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId ...
-
linux命令系列 ls
ls是linux中最常用的命令之一 ls 的功能是list directory contents,其常用的选项如下: (1) -l use a long listing format(长格式,显示 ...