如何根据要求清除MPMusicPlayerController的队列并在歌曲完成时添加新队列
How to clear queue of MPMusicPlayerController and add new queue when Song finished according to requirement
每首歌曲播放完毕后,我都会清空队列,然后添加新队列。但是,多次调用通知 (playing/paused/stopped/playing/paused/playing/paused/paused)。它最终会停止应用内的音频并开始从 iTunes 播放。
谁能帮我解决这个问题?
-(void)clearqueueAndAddNewQueue
{
NSMutableArray *allTheSongs = [[NSMutableArray alloc] initWithCapacity:0];
NSLog(@"setupMusic:");
for (SongsList *obj_songsList in arrSongs) {
// NSLog(@"mediaTitle: %@",obj_songsList.mediaTitle);
MPMediaQuery *songQuery = [MPMediaQuery songsQuery];
[songQuery addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:obj_songsList.persistentId forProperty:MPMediaItemPropertyPersistentID]];
NSArray *songs = [songQuery items];
[allTheSongs addObjectsFromArray: songs];
}
//Rearrange Array in Random Objects
NSUInteger count = [allTheSongs count];
for (NSUInteger i = 0; i < count; ++i) {
// Select a random element between i and end of array to swap with.
NSInteger nElements = count - i;
NSInteger n = (arc4random() % nElements) + i;
[allTheSongs exchangeObjectAtIndex:i withObjectAtIndex:n];
}
//Modify Queue
if ([[AppDelegate appDel].musicPlayerCtrl playbackState] == MPMusicPlaybackStatePlaying) {
MPMusicPlayerController *musicplayercontroller = [MPMusicPlayerController iPodMusicPlayer];
MPMediaItemCollection *currentQueue = [[MPMediaItemCollection alloc] initWithItems:allTheSongs];
MPMediaItem *nowPlaying = [[currentQueue items] objectAtIndex:0];
[musicplayercontroller setQueueWithItemCollection:currentQueue];
[musicplayercontroller setNowPlayingItem:nowPlaying];
[AppDelegate appDel].musicPlayerCtrl = musicplayercontroller;
}
//I have also used this instead of above mentioed Modify Queue
if ([[AppDelegate appDel].musicPlayerCtrl playbackState] == MPMusicPlaybackStatePlaying) {
MPMediaPropertyPredicate *predicate =
[MPMediaPropertyPredicate predicateWithValue: @"Non_Existant_Song_Name"
forProperty: MPMediaItemPropertyTitle];
MPMediaQuery *q = [[MPMediaQuery alloc] init];
[q addFilterPredicate: predicate];
[[AppDelegate appDel].musicPlayerCtrl setQueueWithQuery:q];
[AppDelegate appDel].musicPlayerCtrl.nowPlayingItem = nil;
[[AppDelegate appDel].musicPlayerCtrl stop];
MPMediaItemCollection *currentQueue = [[MPMediaItemCollection alloc] initWithItems:allTheSongs];
[[AppDelegate appDel].musicPlayerCtrl setQueueWithItemCollection:currentQueue];
[[AppDelegate appDel].musicPlayerCtrl play];
}
}
使用此方法将有助于清除队列以及创建或添加新队列而不会出现任何问题。
- (void)setupMusic:(NSArray *)arrSongs forTaggedValue:(NSString *)taggedValue {
NSMutableArray *allTheSongs = [[NSMutableArray alloc] initWithCapacity:0];
NSLog(@"setupMusic:");
for (SongsList *obj_songsList in arrSongs) {
// NSLog(@"mediaTitle: %@",obj_songsList.mediaTitle);
MPMediaQuery *songQuery = [MPMediaQuery songsQuery];
[songQuery addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:obj_songsList.persistentId forProperty:MPMediaItemPropertyPersistentID]];
NSArray *songs = [songQuery items];
[allTheSongs addObjectsFromArray: songs];
}
//Modify Queue
if ([[AppDelegate appDel].musicPlayerCtrl playbackState] == MPMusicPlaybackStatePlaying) {
[self removeNotificationCenterForMusicPlayerController];
MPMediaPropertyPredicate *predicate =
[MPMediaPropertyPredicate predicateWithValue: @"Non_Existant_Song_Name"
forProperty: MPMediaItemPropertyTitle];
MPMediaQuery *q = [[MPMediaQuery alloc] init];
[q addFilterPredicate: predicate];
[[AppDelegate appDel].musicPlayerCtrl setQueueWithQuery:q];
[AppDelegate appDel].musicPlayerCtrl.nowPlayingItem = nil;
[[AppDelegate appDel].musicPlayerCtrl stop];
MPMediaItemCollection *currentQueue = [[MPMediaItemCollection alloc] initWithItems:allTheSongs];
[[AppDelegate appDel].musicPlayerCtrl setQueueWithItemCollection:currentQueue];
[[AppDelegate appDel].musicPlayerCtrl setRepeatMode:MPMusicRepeatModeAll];
[[AppDelegate appDel].musicPlayerCtrl play];
[self addNotificationCenterForMusicPlayerController];
[[AppDelegate appDel].musicPlayerCtrl beginGeneratingPlaybackNotifications];
}
}
同时使用此代码,这有助于您的 [AppDelegate appDel].musicPlayerCtrl(MPMusicPlayerContoller 的对象)工作并防止转到 Itunes。
#pragma mark - For Hadle the Active Bugs Of MPMusicPlayerController
- (BOOL)isPlaybackStateBugActive {
MPMusicPlaybackState playbackState = [AppDelegate appDel].musicPlayerCtrl.playbackState;
if (playbackState == MPMusicPlaybackStatePlaying) {
AudioSessionInitialize (NULL, NULL, NULL, NULL);
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
AudioSessionSetActive (true);
UInt32 audioIsPlaying;
UInt32 size = sizeof(audioIsPlaying);
AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &size, &audioIsPlaying);
if (!audioIsPlaying){
NSLog(@"PlaybackState bug is active");
[[AppDelegate appDel].musicPlayerCtrl pause];
[btnPlayOrPause setImage:[UIImage imageNamed:KPlayImage] forState:UIControlStateNormal];
return YES;
}
}
return NO;
}
addNotificationCenterForMusicPlayerController 方法
#pragma mark - Default NotificationCenter For iPodLibrary/MusicPlayerController
- (void)addNotificationCenterForMusicPlayerController {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver: self selector: @selector (handle_NowPlayingItemChanged:) name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
[notificationCenter addObserver: self selector: @selector (handle_PlaybackStateChanged:) name: MPMusicPlayerControllerPlaybackStateDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
// [notificationCenter addObserver: self selector: @selector (handle_VolumeChanged:) name: MPMusicPlayerControllerVolumeDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
// [[AppDelegate appDel].musicPlayerCtrl beginGeneratingPlaybackNotifications];
}
removeNotificationCenterForMusicPlayerController 方法
- (void)removeNotificationCenterForMusicPlayerController {
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMusicPlayerControllerPlaybackStateDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
// [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMusicPlayerControllerVolumeDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
[[AppDelegate appDel].musicPlayerCtrl endGeneratingPlaybackNotifications];
}
每首歌曲播放完毕后,我都会清空队列,然后添加新队列。但是,多次调用通知 (playing/paused/stopped/playing/paused/playing/paused/paused)。它最终会停止应用内的音频并开始从 iTunes 播放。
谁能帮我解决这个问题?
-(void)clearqueueAndAddNewQueue
{
NSMutableArray *allTheSongs = [[NSMutableArray alloc] initWithCapacity:0];
NSLog(@"setupMusic:");
for (SongsList *obj_songsList in arrSongs) {
// NSLog(@"mediaTitle: %@",obj_songsList.mediaTitle);
MPMediaQuery *songQuery = [MPMediaQuery songsQuery];
[songQuery addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:obj_songsList.persistentId forProperty:MPMediaItemPropertyPersistentID]];
NSArray *songs = [songQuery items];
[allTheSongs addObjectsFromArray: songs];
}
//Rearrange Array in Random Objects
NSUInteger count = [allTheSongs count];
for (NSUInteger i = 0; i < count; ++i) {
// Select a random element between i and end of array to swap with.
NSInteger nElements = count - i;
NSInteger n = (arc4random() % nElements) + i;
[allTheSongs exchangeObjectAtIndex:i withObjectAtIndex:n];
}
//Modify Queue
if ([[AppDelegate appDel].musicPlayerCtrl playbackState] == MPMusicPlaybackStatePlaying) {
MPMusicPlayerController *musicplayercontroller = [MPMusicPlayerController iPodMusicPlayer];
MPMediaItemCollection *currentQueue = [[MPMediaItemCollection alloc] initWithItems:allTheSongs];
MPMediaItem *nowPlaying = [[currentQueue items] objectAtIndex:0];
[musicplayercontroller setQueueWithItemCollection:currentQueue];
[musicplayercontroller setNowPlayingItem:nowPlaying];
[AppDelegate appDel].musicPlayerCtrl = musicplayercontroller;
}
//I have also used this instead of above mentioed Modify Queue
if ([[AppDelegate appDel].musicPlayerCtrl playbackState] == MPMusicPlaybackStatePlaying) {
MPMediaPropertyPredicate *predicate =
[MPMediaPropertyPredicate predicateWithValue: @"Non_Existant_Song_Name"
forProperty: MPMediaItemPropertyTitle];
MPMediaQuery *q = [[MPMediaQuery alloc] init];
[q addFilterPredicate: predicate];
[[AppDelegate appDel].musicPlayerCtrl setQueueWithQuery:q];
[AppDelegate appDel].musicPlayerCtrl.nowPlayingItem = nil;
[[AppDelegate appDel].musicPlayerCtrl stop];
MPMediaItemCollection *currentQueue = [[MPMediaItemCollection alloc] initWithItems:allTheSongs];
[[AppDelegate appDel].musicPlayerCtrl setQueueWithItemCollection:currentQueue];
[[AppDelegate appDel].musicPlayerCtrl play];
}
}
使用此方法将有助于清除队列以及创建或添加新队列而不会出现任何问题。
- (void)setupMusic:(NSArray *)arrSongs forTaggedValue:(NSString *)taggedValue {
NSMutableArray *allTheSongs = [[NSMutableArray alloc] initWithCapacity:0];
NSLog(@"setupMusic:");
for (SongsList *obj_songsList in arrSongs) {
// NSLog(@"mediaTitle: %@",obj_songsList.mediaTitle);
MPMediaQuery *songQuery = [MPMediaQuery songsQuery];
[songQuery addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:obj_songsList.persistentId forProperty:MPMediaItemPropertyPersistentID]];
NSArray *songs = [songQuery items];
[allTheSongs addObjectsFromArray: songs];
}
//Modify Queue
if ([[AppDelegate appDel].musicPlayerCtrl playbackState] == MPMusicPlaybackStatePlaying) {
[self removeNotificationCenterForMusicPlayerController];
MPMediaPropertyPredicate *predicate =
[MPMediaPropertyPredicate predicateWithValue: @"Non_Existant_Song_Name"
forProperty: MPMediaItemPropertyTitle];
MPMediaQuery *q = [[MPMediaQuery alloc] init];
[q addFilterPredicate: predicate];
[[AppDelegate appDel].musicPlayerCtrl setQueueWithQuery:q];
[AppDelegate appDel].musicPlayerCtrl.nowPlayingItem = nil;
[[AppDelegate appDel].musicPlayerCtrl stop];
MPMediaItemCollection *currentQueue = [[MPMediaItemCollection alloc] initWithItems:allTheSongs];
[[AppDelegate appDel].musicPlayerCtrl setQueueWithItemCollection:currentQueue];
[[AppDelegate appDel].musicPlayerCtrl setRepeatMode:MPMusicRepeatModeAll];
[[AppDelegate appDel].musicPlayerCtrl play];
[self addNotificationCenterForMusicPlayerController];
[[AppDelegate appDel].musicPlayerCtrl beginGeneratingPlaybackNotifications];
}
}
同时使用此代码,这有助于您的 [AppDelegate appDel].musicPlayerCtrl(MPMusicPlayerContoller 的对象)工作并防止转到 Itunes。
#pragma mark - For Hadle the Active Bugs Of MPMusicPlayerController
- (BOOL)isPlaybackStateBugActive {
MPMusicPlaybackState playbackState = [AppDelegate appDel].musicPlayerCtrl.playbackState;
if (playbackState == MPMusicPlaybackStatePlaying) {
AudioSessionInitialize (NULL, NULL, NULL, NULL);
UInt32 sessionCategory = kAudioSessionCategory_AmbientSound;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory, sizeof (sessionCategory), &sessionCategory);
AudioSessionSetActive (true);
UInt32 audioIsPlaying;
UInt32 size = sizeof(audioIsPlaying);
AudioSessionGetProperty(kAudioSessionProperty_OtherAudioIsPlaying, &size, &audioIsPlaying);
if (!audioIsPlaying){
NSLog(@"PlaybackState bug is active");
[[AppDelegate appDel].musicPlayerCtrl pause];
[btnPlayOrPause setImage:[UIImage imageNamed:KPlayImage] forState:UIControlStateNormal];
return YES;
}
}
return NO;
}
addNotificationCenterForMusicPlayerController 方法
#pragma mark - Default NotificationCenter For iPodLibrary/MusicPlayerController
- (void)addNotificationCenterForMusicPlayerController {
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver: self selector: @selector (handle_NowPlayingItemChanged:) name: MPMusicPlayerControllerNowPlayingItemDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
[notificationCenter addObserver: self selector: @selector (handle_PlaybackStateChanged:) name: MPMusicPlayerControllerPlaybackStateDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
// [notificationCenter addObserver: self selector: @selector (handle_VolumeChanged:) name: MPMusicPlayerControllerVolumeDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
// [[AppDelegate appDel].musicPlayerCtrl beginGeneratingPlaybackNotifications];
}
removeNotificationCenterForMusicPlayerController 方法
- (void)removeNotificationCenterForMusicPlayerController {
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMusicPlayerControllerPlaybackStateDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
// [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMusicPlayerControllerVolumeDidChangeNotification object: [AppDelegate appDel].musicPlayerCtrl];
[[AppDelegate appDel].musicPlayerCtrl endGeneratingPlaybackNotifications];
}