2011-06-06 21 views
5

का उपयोग कर आईफोन पर कई अलग-अलग वीडियो बजाना मैं AVFoundation का उपयोग करके आईओएस के लिए एक कस्टम वीडियो प्लेयर पर काम कर रहा हूं। विचार एक अलग वीडियो पर एक इशारा (टैप, स्वाइप, जो कुछ भी) के साथ स्विच करने में सक्षम होना है। अभी खिलाड़ी सिम्युलेटर पर बेकार ढंग से काम कर रहा है, लेकिन जब मैं इसे वास्तविक डिवाइस पर परीक्षण करता हूं, तो दृश्य 3 या 4 स्वाइप के बाद खाली हो जाता है। मैंने अपने प्लेयर के लिए प्लेबैक नियंत्रण भी बनाए हैं, जब दृश्य खाली हो जाता है, तो ये नियंत्रण सही ढंग से लोड होते हैं लेकिन कुछ भी नहीं करते हैं। कोई विचार लोग? इस खिलाड़ी के लिए प्रारंभ हैAVPlayer

  - (id)initWithContentURL:(NSString *)aContentURL delegate:(id)aDelegate { 
     self = [super initWithNibName:@"NoCashMoviePlayer" bundle:nil]; 
     if (self == nil) 
      return nil; 
     delegate = aDelegate; 
     systemPath = [aContentURL retain]; 
     contentURL = [[NSURL alloc]initFileURLWithPath:systemPath]; 
     asset = [AVURLAsset URLAssetWithURL:contentURL options:nil]; 
     playerItem = [AVPlayerItem playerItemWithAsset:asset]; 
     isPaused = false; 
     controlsHidden = false; 
     self.player = [[AVPlayer playerWithPlayerItem:playerItem] retain]; 
     duration = self.player.currentItem.asset.duration; 

     return self; 
    } 

यह कोड सीधे वीडियो निभाता है:

-(void)playMovie{ 

     UITapGestureRecognizer *tapRecon = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(toggleControls:)]; 
     [tapRecon setNumberOfTapsRequired:2]; 
     [self.movieContainer addGestureRecognizer:tapRecon]; 
     [tapRecon release]; 

     NSLog(@"Playing item: %@",contentURL); 
     playerLayer = [AVPlayerLayer playerLayerWithPlayer:player]; 
     [movieContainer.layer addSublayer:playerLayer]; 
     playerLayer.frame = movieContainer.layer.bounds; 
     playerLayer.videoGravity = AVLayerVideoGravityResizeAspect; 
     self.seeker.alpha = 1.0; 
     [self.view addSubview:movieContainer]; 
     [self.movieContainer addSubview:controls]; 
     [self setSlider]; 
     [player play]; 
     player.actionAtItemEnd = AVPlayerActionAtItemEndNone; 

     [[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(playerItemDidReachEnd:) 
              name:AVPlayerItemDidPlayToEndTimeNotification 
              object:[player currentItem]]; 


    } 

कोड क्लिप का चयन करने के खेले जाने वाले:

-(void)viewSelect: (double) curTime{ 
     self.myView.backgroundColor = [UIColor blackColor]; 
     UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeFrom:)]; 
     swipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight; 
     [self.myView addGestureRecognizer:swipeRecognizer]; 
     [swipeRecognizer release]; 

     UISwipeGestureRecognizer *leftRecognizer = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleSwipeFromLeft:)]; 
     swipeRecognizer.direction = UISwipeGestureRecognizerDirectionLeft; 
     [self.myView addGestureRecognizer:leftRecognizer]; 
     [leftRecognizer release]; 


     if(isMain){ 
      [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationTransitionFlipFromLeft animations:^{ 
       self.myView.alpha = 1.0; 
       moviePlayer = [[NoCashMoviePlayer alloc]initWithContentURL:[self movieURL:vidIndex] delegate:self]; 
       self.moviePlayer.view.frame = self.myView.bounds; 
       self.moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight; 
       [self.myView addSubview:moviePlayer.view]; 

      }completion:^(BOOL finished) { 
       [self.moviePlayer.player seekToTime:CMTimeMake(curTime, 1)]; 
       [self.moviePlayer playMovie]; 
      }]; 
     }else{ 

      [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationTransitionFlipFromLeft animations:^{ 
       self.otherView.alpha = 1.0; 
       moviePlayer = [[NoCashMoviePlayer alloc]initWithContentURL:[self movieURL:vidIndex] delegate:self]; 
       self.moviePlayer.view.frame = self.otherView.bounds; 
       self.moviePlayer.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |UIViewAutoresizingFlexibleHeight; 
       [self.otherView addSubview:moviePlayer.view]; 

      }completion:^(BOOL finished) { 

       [self.moviePlayer.player seekToTime:CMTimeMake(curTime, 1)]; 
       [self.moviePlayer playMovie]; 
      }]; 
     } 
    } 

और आखिरी इशारा कार्रवाई:

- (void)handleSwipeFromLeft:(UISwipeGestureRecognizer *)recognizer { 

     double elapsedTime = 0.0; 
     if(vidIndex==0){ 
      vidIndex = 3; 
     }else vidIndex = vidIndex --; 
     elapsedTime = [self.moviePlayer currentTimeInSeconds]; 
     [self.moviePlayer stopMovie]; 
     isMain = !isMain; 
     [self viewSelect: elapsedTime]; 

    } 

संपादित करें: प्रत्येक वीडियो फ़ाइल के लिए अलग-अलग AVPlayerLayers का उपयोग करने का प्रयास किया, एक ही स्थिति, सिम्युलेटर में काम करता है, न कि आईपैड पर।

संपादित करें 2: मैंने कोर एनीमेशन प्रदर्शन का विश्लेषण करने के लिए यंत्र चलाए, और जब वीडियो चल रहा है तो यह लगभग 30 एफपीएस की फ़्रेमेट दिखा रहा है, जब खिलाड़ी खाली हो जाता है तो यह 1 या 2 एफपीएस तक नीचे गिर जाता है। यह अजीब हो सकता है, लेकिन फिर भी, अगर यह थोड़ा और प्रकाश देने में मदद करता है .....

संपादित करें 3: ठीक है, मैं अंत में कहीं और हो रहा हूं, मुझे पता है कि समस्या क्या है, मेरे पास कोर एनीमेशन मेमोरी है रिसाव में, सिम्युलेटर में यह "काम करता है" क्योंकि कंप्यूटर में आईपैड की तुलना में बहुत अधिक स्मृति है, लेकिन चूंकि आईपैड में बहुत सीमित स्मृति है, यह बहुत जल्दी काम करना बंद कर देता है। अगर किसी को कोर एनीमेशन लीक के बारे में कोई सलाह है, तो यह बहुत अच्छी तरह से प्राप्त होगा।

उत्तर

4

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

[player pause]; 
    contentURL = [[NSURL alloc] initFileURLWithPath:newPath]; 
    AVAsset *newAsset = [AVURLAsset URLAssetWithURL:contentURL options:nil]; 
    AVPlayerItem *newPlayerItem = [AVPlayerItem playerItemWithAsset:newAsset]; 
    [player replaceCurrentItemWithPlayerItem:newPlayerItem]; 
    [contentURL release]; 

और अब यह अद्भुत काम कर रहा है। आपकी मदद के लिए आप सभी को शुक्रिया।

1

कोड में 2 स्थान हैं जहां आपने ऑब्जेक्ट बनाए रखा है, और मुझे आपके द्वारा पोस्ट किए गए कोड में कहीं भी इसी रिलीज को नहीं दिखाई देता है। मैं यह सुनिश्चित करके शुरू करूंगा कि स्मृति संदर्भ गणना वृद्धि और कमी सभी उचित रूप से संतुलित हैं।

पहला रखरखाव मुझे संदिग्ध लग रहा है। आम तौर पर आप पहली बार autorelease चाहिए चर आप के लिए बताए जाते हैं और फिर बनाए रखने इस प्रकार है:

[systemPath autorelease]; 
systemPath = [aContentURL retain] 

उपरोक्त कोड में देखने के लिए कि बनाए रखने/रिलीज मिलान बनाए रखा है आसान है, और अब तक कम त्रुटि है अन्य योजनाओं की तुलना में प्रवण। ध्यान दें कि यदि systemPath == aContentURL ऑब्जेक्ट जारी नहीं किया जाएगा।

+0

सभी बनाए रखा ऑब्जेक्ट 'dealloc' विधि में जारी किए जाते हैं। क्या वह पर्याप्त होगा? असल में मैं 'रखरखाव' कीवर्ड के बिना खिलाड़ी होता था, लेकिन यह बदतर था, अंततः यह एक दुर्घटना का कारण बन गया, क्योंकि ऑब्जेक्ट रनटाइम के दौरान किसी बिंदु पर जारी किया जा रहा था। – Samssonart

+0

सटीक कोड को देखे बिना सुनिश्चित नहीं है। लेकिन पहला रखरखाव मानक पैटर्न का पालन नहीं करता है। –

+0

हिमाद्री की सहायता के लिए धन्यवाद, मैंने कुछ अलग मेमोरी/रेफरीस गिनती समाधानों की कोशिश की है, लेकिन यह काम नहीं कर रहा है। मैंने उपकरणों का उपयोग करने की कोशिश की है और कुछ रिसाव थे, मैंने उनका ख्याल रखा, और अभी भी कुछ भी नहीं। मैं कोशिश करूँगा। – Samssonart

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