2012-05-09 15 views
5

मुझे AVPlayer के साथ कुछ वास्तव में अजीब समस्याएं हैं। मेरे पास एक बहुत ही सरल संगीत प्लेयर है (जो आईट्यून्स स्टोर से नमूना संगीत स्ट्रीम करता है) सिम्युलेटर (आईओएस 5.1 के साथ आईफोन और आईपैड दोनों) पर सही ढंग से काम करता है लेकिन यह वास्तविक डिवाइस पर असामान्य रूप से व्यवहार करता है।आईओएस AVPlayer स्ट्रीमिंग संगीत मुद्दों

आईओएस 5.1.1 के साथ एक आईपैड 2 पर यह सही ढंग से खेलता है भले ही मैं अपने हेडफ़ोन डिवाइस से कनेक्ट करता हूं। लेकिन जैसे ही मैं उन्हें डिस्कनेक्ट करता हूं, यह वक्ताओं के माध्यम से ध्वनि नहीं बजाएगा (भले ही मैं उन्हें दोबारा जोड़ूं, मैं गीत सुन सकता हूं)।

आईओएस 5.1 के साथ एक आईफोन 4 पर स्थापित यह वक्ताओं के माध्यम से बिल्कुल नहीं लगता है लेकिन मैं अपने हेडफोन के माध्यम से संगीत सुन सकता हूं। हालांकि यह वक्ताओं के माध्यम से खेलना प्रतीत नहीं होता है, लेकिन अब मैं सुन सकता हूं और फिर एक बहुत ही कम पल के लिए संगीत बज रहा है (और यह पुष्टि कर सकता है कि वास्तव में यह खेल रहा है क्योंकि मेरा यूआई तदनुसार जवाब देता है) हालांकि यह यादृच्छिक प्रतीत होता है।

मैं AVPlayer का उपयोग कर रहा हूं क्योंकि यह आवश्यकताओं को पूरा करने लगता है। क्या मुझे दूसरी लाइब्रेरी का उपयोग करना चाहिए? क्या मुझे ध्वनि को मैन्युअल रूप से रूट करने की ज़रूरत है? मुझे इन प्रकार की समस्या क्यों है? और क्या मैं ऑडियो सत्रों का सही ढंग से उपयोग कर रहा हूं?

Media.h:

#import <Foundation/Foundation.h> 
#import <AVFoundation/AVFoundation.h> 
#import <AudioToolbox/AudioToolbox.h> 

#define NOT_PLAYING -1 

@protocol MediaDelegate <NSObject> 
@optional 
- (void) didEndPlayingAtIndex:(int) index; 
- (void) startedToPlayAtIndex:(int) index; 
- (void) stoppedToPlayAtIndex:(int) index; 
- (void) startedToPlayAtIndex:(int) to fromIndex:(int) from; 
- (void) pausedAtIndex:(int) index; 
@end 

@interface Media : NSObject <AVAudioSessionDelegate> 

@property (nonatomic, assign) int currentItem; 
@property (nonatomic, strong) NSURL *url; 
@property (nonatomic, strong) AVPlayer *player; 
@property (nonatomic, assign) id<MediaDelegate> delegate; 

- (void) toggle:(int) index; 
- (void) stop; 

@end 

Media.m:

#import "Media.h" 

@implementation Media 

@synthesize currentItem; 
@synthesize player; 
@synthesize delegate; 
@synthesize url; 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     NSError *activationError = nil; 
     NSError *setCategoryError = nil; 
     AVAudioSession *session = [AVAudioSession sharedInstance]; 
     session.delegate = self; 
     [session setActive:YES error:&activationError]; 
     [session setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError]; 

     if(activationError || setCategoryError) 
      NSLog(@"ERROR: %@, %@",activationError,setCategoryError); 

     self.currentItem = NOT_PLAYING; 
    } 
    return self; 
} 

- (void)dealloc{ 
    NSError *activationError = nil; 
    [[AVAudioSession sharedInstance] setActive:NO error:&activationError]; 

    if(activationError) 
     NSLog(@"ERROR: %@",activationError); 

    [self.player removeObserver:self forKeyPath:@"status"]; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{  
    switch (player.status) { 
     case AVPlayerItemStatusReadyToPlay: 
      [self.player play]; 
      if([self.delegate respondsToSelector:@selector(startedToPlayAtIndex:)]) 
       [self.delegate startedToPlayAtIndex:self.currentItem]; 
      break; 
     default: 
      break; 
    } 
} 

- (void) toggle:(int) index{ 
    if (self.currentItem == NOT_PLAYING) { 
     self.player = [AVPlayer playerWithPlayerItem:[AVPlayerItem playerItemWithURL:self.url]]; 
     [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(didEnd:) 
                name:AVPlayerItemDidPlayToEndTimeNotification 
                object:self.player]; 
     self.currentItem = index; 
     [self.player addObserver:self forKeyPath:@"status" options:0 context:nil]; 
    } 
    else { 
     if (self.currentItem == index) { 
      [self.player pause]; 
      if([self.delegate respondsToSelector:@selector(stoppedToPlayAtIndex:)]) 
       [self.delegate stoppedToPlayAtIndex:index]; 
      self.currentItem = NOT_PLAYING; 
      [self.player removeObserver:self forKeyPath:@"status"]; 
      self.player = nil; 
      [[NSNotificationCenter defaultCenter] removeObserver:self]; 
     } 
     else{ 
      [self.player replaceCurrentItemWithPlayerItem:[AVPlayerItem playerItemWithURL:self.url]]; 
      if([self.delegate respondsToSelector:@selector(startedToPlayAtIndex:fromIndex:)]) 
       [self.delegate startedToPlayAtIndex:index fromIndex:self.currentItem]; 
      self.currentItem = index; 
     } 
    } 
} 

- (void) stop{ 
    [self.player pause]; 
    if([self.delegate respondsToSelector:@selector(stoppedToPlayAtIndex:)]) 
     [self.delegate stoppedToPlayAtIndex:self.currentItem]; 
} 

-(void) didEnd:(id)sender{ 
    if([self.delegate respondsToSelector:@selector(didEndPlayingAtIndex:)]) 
     [self.delegate didEndPlayingAtIndex:self.currentItem]; 
    self.currentItem = NOT_PLAYING; 
    [self.player removeObserver:self forKeyPath:@"status"]; 
    self.player = nil; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

#pragma mark - AVAudioSession delegate 

-(void)beginInterruption{ 
    NSLog(@"Interruption"); 
    if(self.currentItem != NOT_PLAYING){ 
     [self.player pause]; 
     if([self.delegate respondsToSelector:@selector(pausedAtIndex:)]) 
      [self.delegate pausedAtIndex:self.currentItem]; 
    } 
} 

-(void)endInterruption{ 
    NSLog(@"Ended interruption"); 
    if(self.currentItem != NOT_PLAYING){ 
     [self.player play]; 
     if([self.delegate respondsToSelector:@selector(startedToPlayAtIndex:)]) 
      [self.delegate startedToPlayAtIndex:self.currentItem]; 
    } 
} 

@end 
+0

मुझे पता है कि यह एक लंबा शॉट है लेकिन सेट श्रेणी को कॉल करने के बाद setActive को कॉल करने का प्रयास करें। – SteveB

+0

खैर, मुझे पूरा यकीन नहीं है कि ऐसा इसलिए हुआ क्योंकि मैंने एक ही समय में कुछ और बदलाव किए हैं, लेकिन जब भी मैं डिस्कनेक्ट करता हूं तो ध्वनि के अपवाद के साथ अब यह सामान्य रूप से काम कर रहा है (अब तक) हेडफोन। आपका बहुत बहुत धन्यवाद! – dvieira

+0

AVAudioSessionCategory प्लेबैक के साथ ध्वनि को स्पीकर को स्वचालित रूप से रूट किया जाना चाहिए। वहां कुछ कोड होना चाहिए जो ऐसा होने से रोक रहा है। यदि आप कुछ और कोड पोस्ट कर सकते हैं या कहीं भी अपनी परियोजना अपलोड कर सकते हैं तो मैं एक नज़र डाल सकता हूं। – SteveB

उत्तर

0

ऐसा लगता है कि आप सही ऑडियो रूटिंग के साथ एक समस्या है। मैं एक ऑडियो रूट परिवर्तन श्रोता कॉलबैक जोड़ने का सुझाव देता हूं। सबसे पहले एक प्रणाली की घोषणा:

void audioRouteChangeListenerCallback(void *inUserData, AudioSessionPropertyID inPropertyID, UInt32 inPropertyValueSize, const void *inPropertyValue); 

फिर अपने init विधि में एक कॉलबैक जोड़ें:

void audioRouteChangeListenerCallback(void *inUserData, AudioSessionPropertyID inPropertyID, UInt32 inPropertyValueSize, const void *inPropertyValue) { 
    if (inPropertyID != kAudioSessionProperty_AudioRouteChange) { 
     return; 
    } 

    CFDictionaryRef routeChangeDictionary = inPropertyValue; 
    CFNumberRef  routeChangeReasonRef = CFDictionaryGetValue(routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_Reason)); 
    SInt32   routeChangeReason; 
    CFNumberGetValue(routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason); 

    if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) { 
     // Headset is unplugged.. 
     NSLog(@"Headset is unplugged.."); 
     // Delayed play: 0.5 s. 
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 
      [CORE.player play]; // NOTE: change this line according your current player implementation 
      NSLog(@"resumed play"); 
     }); 
    } 
    if (routeChangeReason == kAudioSessionRouteChangeReason_NewDeviceAvailable) { 
     // Headset is plugged in.. 
     NSLog(@"Headset is plugged in.."); 
    } 
} 

आशा इस मदद:

// Prevent from audio issues when you pull out earphone 
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, audioRouteChangeListenerCallback, (__bridge void *)(self)); 

और अंत में, एक कॉलबैक कार्यान्वयन जोड़ने! कम से कम अन्य लोगों के लिए यह सहायक टिप होगा।

संबंधित मुद्दे