OC-音乐播放器-锁屏处理

时间:2022-08-29 19:48:27

QQ音乐播放的过程中,锁屏状态下的效果如下:

OC-音乐播放器-锁屏处理

也就是说,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)参考到链接:https://www.jianshu.com/p/21396afffe62
 

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-音乐播放器-锁屏处理的更多相关文章

  1. iOS 音乐播放器之锁屏效果&plus;歌词解析

    概述 功能描述:锁屏歌曲信息.控制台远程控制音乐播放:暂停/播放.上一首/下一首.快进/快退.列表菜单弹框和拖拽控制台的进度条调节进度(结合了QQ音乐和网易云音乐在锁屏状态下的效果).歌词解析并随音乐 ...

  2. swift 音乐播放器项目-《lxy的杰伦情歌》开发实战演练

    近期准备将项目转化为OC与swift混合开发.试着写一个swift音乐播放器的demo,体会到了swift相对OC的优势所在.废话不多说.先上效果图: watermark/2/text/aHR0cDo ...

  3. 轻仿QQ音乐之音频歌词播放、锁屏歌词-b

    先上效果图 歌词播放界面 音乐播放界面 锁屏歌词界面 一. 项目概述 前面内容实在是太基础..只想看知识点的同学可以直接跳到第三部分的干货 项目播放的mp3文件及lrc文件均来自QQ音乐 本文主要主要 ...

  4. iOS商城demo、音乐播放器、视频通话、自定义搜索、转场动画等源码

    iOS精选源码 微信自定义搜索框实现 一个商城Demo,持续更新中 在Object-C中学习数据结构与算法之排序算法 iOS 音乐播放器之锁屏歌词+歌词解析+锁屏效果 XLsn0wPushTimePi ...

  5. iOS电商常见动画与布局、微信悬浮窗、音乐播放器、歌词解析、拖动视图等源码

    iOS精选源码 MXScroll 介绍 混合使用UIScrollView ios 电商demo(实现各种常见动画效果和页面布局) 一行代码集成微信悬浮窗 可拖动,大小的视图,可放置在屏幕边缘. 在使用 ...

  6. Swift 3 &colon;基于 AVAudioPlayer 的简单音乐播放器

    2017.05.22 17:46* 字数 1585 阅读 5095评论 0喜欢 8赞赏 2 https://www.jianshu.com/p/4d5c257428a1 学习ios以来差不多接近两个月 ...

  7. iOS音乐播放器相关

    iOS音乐播放器框架主要有两大类:AvPlayer.AvaudioPlayer AvPlayer 能播放本地及网络歌曲 AvaudioPlayer 能播放本地歌曲.有相关代理方法(其实也可以播放网络歌 ...

  8. 【竞品分析】Android音乐播放器的竞品分析

    迄今为止最长的一篇博客,各位看官笑纳~~ 本次分析基于Android平台,选取了几款我体验过的播放器进行比较分析.主要分为两类,一类是大而全的,功能全面,可满足用户管理歌曲.导入导出歌单等多方面需求, ...

  9. 酷狗、QQ、天天动听——手机音乐播放器竞品对比

    如果说什么艺术与人们生活最贴近,那应该属音乐了,因此当代人不离身的手机里必然会有自己喜欢的音乐播放器APP存在. 在当今无论PC端还是手机端音乐播放器都越来越同质化,我们应该选择哪款手机音乐播放器?它 ...

随机推荐

  1. python的变量传递

    python中变量都被视为对象的引用.python函数调用传递参数的时候,不允许程序员选择传值还是传引用,python参数传递采用的都是“传对象引用”的方式.     这种方式相当于传值和传引用的结合 ...

  2. HTML5 格式化、样式、链接、表格

    HTML格式化.样式.链接.表格的使用举例

  3. 『NOIP2018普及组题解』

    标题统计 题目描述 凯凯刚写了一篇美妙的作文,请问这篇作文的标题中有多少个字符? 注意:标题中可能包含大.小写英文字母.数字字符.空格和换行符.统计标题字 符数时,空格和换行符不计算在内. 输入格式 ...

  4. 7&period;2 if else 语句

    7.2 if else 语句 if else语句的通用形式是: if ( expression ) statement1 else statement2 如果expression为真(非0),则执行s ...

  5. nginx学习笔记(三)

    浏览器缓存

  6. HDU 1796 &lpar;容斥原理)

    容斥原理练习题,忘记处理gcd 和 lcm,wa了几发0.0. #include<iostream> #include<cstdio> #include<cstring& ...

  7. ThreadLocal用法详解和原理

    一.用法 ThreadLocal用于保存某个线程共享变量:对于同一个static ThreadLocal,不同线程只能从中get,set,remove自己的变量,而不会影响其他线程的变量. 1.Thr ...

  8. FZU 2273 Triangles 第八届福建省赛 (三角形面积交 有重边算相交)

    Problem Description This is a simple problem. Given two triangles A and B, you should determine they ...

  9. idea创建maven spring项目,出现的问题

    1.jetty启动后,明明配置文件配置的是 <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId ...

  10. linux命令系列 ls

    ls是linux中最常用的命令之一 ls 的功能是list directory contents,其常用的选项如下: (1) -l   use a long listing format(长格式,显示 ...