2014-07-18 6 views
7

Ich habe ein Array, das Video-URLs enthält, möchte ich diese Videos auf UITableviewcell spielen, wenn es vollständig sichtbar ist.Video auf UITableViewCell wiedergeben, wenn es vollständig sichtbar ist

Ich habe diese versucht

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView 
{ 
    NSArray* cells = homeTabl.visibleCells; 

    for (HomeCell* cell in cells) 
    { 
     if (cell.frame.origin.y > offset.y && 
     cell.frame.origin.y + cell.frame.size.height < offset.y + bounds.size.height) 
     { 
      NSIndexPath *path = [homeTabl indexPathForCell:cell] ; 
      index = path.row; 
      fullvisible = YES; 
      [homeTabl reloadData]; 
     } 
     else 
     { 
      fullvisible = NO; 
     } 
    } 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if (fullvisible) 
    { 
      NSURL *url = [NSURL URLWithString:[[responsearray objectAtIndex:indexPath.row]valueForKey:@"feed_video"]]; 

      cell.videoItem = [AVPlayerItem playerItemWithURL:url]; 
      cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem]; 
      cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer]; 
      cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 
      [cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil]; 
      [cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil]; 

      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil]; 
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; 

      cell.avLayer.frame = CGRectMake(5, 9, 310, 310); 
      [cell.contentView.layer addSublayer:cell.avLayer]; 
      [cell.videoPlayer play]; 
      [cell.contentView addSubview:cell.videoActivity]; 
    } 
    else 
    { 
     cell.videoPlayer = nil; 
     [cell.avLayer removeFromSuperlayer]; 
     cell.videoItem = nil; 
     [cell.videoPlayer pause]; 
    } 
} 

Dies funktioniert gut - aber es ist schrecklich das Scrollen der Tabellenansicht verlangsamen. Bitte schlagen Sie mir eine andere bessere Methode vor.

+5

was ist videoActivity? –

+0

@MitulNakum Es ist Aktivitätsindikator. –

Antwort

9

können Sie

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    isScrolling = NO; 
    [homeTabl reloadData]; 
} 

-(void)scrollViewWillBeginDragging:(UIScrollView *)aScrollView 
{ 
    isScrolling = YES; 
    [homeTabl reloadData]; 
    index = -1; 
} 

verwenden und in cellForRowAtIndexPath

if (fullvisible && index == indexPath.row) { 
     if (!isScrolling) { 

      NSLog(@"video index---%d",indexPath.row); 

      if (index == indexPath.row) { 
       NSLog(@"video index---%d",indexPath.row); 
       cell.videoActivity.hidden = NO; 

       // if (index == indexPath.row) { 
       NSURL *url = [NSURL URLWithString:[[responsearray objectAtIndex:indexPath.row]valueForKey:@"feed_video"]]; 

       dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 

       dispatch_async(queue, ^{ 
        cell.videoItem = [AVPlayerItem playerItemWithURL:url]; 

        dispatch_sync(dispatch_get_main_queue(), ^{ 
         cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem]; 
         cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer]; 
         cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 
         [cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil]; 
         [cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil]; 

         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil]; 
         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; 

         cell.avLayer.frame = CGRectMake(5, 9, 310, 310); 
         [cell.contentView.layer addSublayer: cell.avLayer]; 
         [ cell.videoPlayer play]; 
         [cell.contentView addSubview:cell.videoActivity]; 
        }); 
       }); 
       //    } 
       //    else{ 
       //     cell.videoActivity.hidden = YES; 
       //     cell.videoPlayer = nil; 
       //     [cell.avLayer removeFromSuperlayer]; 
       //     cell.videoItem = nil; 
       //     [cell.videoPlayer pause]; 
       //    } 
      } 
     }} 

    else{ 

     cell.videoActivity.hidden = YES; 
     cell.videoPlayer = nil; 
     [cell.avLayer removeFromSuperlayer]; 
     cell.videoItem = nil; 
     [cell.videoPlayer pause]; 

    } 
+0

können Sie http://StackOverflow.com/Questions/34767717/Tableview-Cell-Video-Autoplay beantworten? –

+0

@nNthin M Keloth - Was ist das für eine vollwertige bool? –

+0

@Nitin Was ist dieser voll sichtbare && Index? Wo erhöhen wir den Index? –

8

Sie laden Ihre Videoelemente im Hauptthread synonym. Das bedeutet, dass Ihre Videoelemente gleichzeitig mit den Zellen der Tabellenansicht heruntergeladen und in Tabellenansichtszellen geladen werden. Das verursacht das Problem und macht das Scrollen sehr verzögert und langsam. Um das Problem zu beheben, müssen Sie Ihre Videos in einem separaten Thread asynchron laden.

Daher müssen Sie das Laden von Bildern synchron zu vermeiden, aber asynchron stattdessen einen anderen Thread anders als der Hauptthread verwenden, so dass das Scrollen und Laden Anzeige von Bildern + abhängig gemacht werden können, um jede Art von Verzögerung zu vermeiden.

Dies ist möglicherweise eine doppelte Frage, da es bereits gefragt wurde und es gibt Tutorials da draußen, aber da ich selbst immer ein Problem mit diesem hatte (aber für Bilder) auf meiner ersten iOS App und fand es sehr verwirrend, ich Ich schreibe hier die Antwort und hoffe, dass es hilfreich ist.

Versuchen Sie, alle Linien, die mit dem Laden/Anzeigen des Videos zu tun haben, insbesondere playerItemWithURL in Ihrem - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath: in einen separaten Block zu verschieben. Suchen und lesen Sie auch einen anderen Post über "asynchrones Laden von Videos in Tabellenansichtszellen". Es gibt viele eingehende Tutorials und Q/As dazu.

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 

dispatch_async(queue, ^{ 
cell.videoItem = [AVPlayerItem playerItemWithURL:url]; 

dispatch_sync(dispatch_get_main_queue(), ^{ 
    cell.videoPlayer = [AVPlayer playerWithPlayerItem:cell.videoItem]; 
     cell.avLayer = [AVPlayerLayer playerLayerWithPlayer:cell.videoPlayer]; 
     cell.videoPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone; 
     [cell.videoItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil]; 
     [cell.videoItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil]; 

     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidBufferPlaying:) name:AVPlayerItemPlaybackStalledNotification object:nil]; 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil]; 

     cell.avLayer.frame = CGRectMake(5, 9, 310, 310); 
     [cell.contentView.layer addSublayer: cell.avLayer]; 
     [ cell.videoPlayer play]; 
     [cell.contentView addSubview:cell.videoActivity]; 
    }); 
}); 
+0

Würde es Ihnen etwas ausmachen, wie Sie das Entfernen Ihres View-Controllers als Beobachter für cell.VideoItem für playbackufferEmpty und playbackLikelyToKeepUp behandeln? – user3344977

+0

Das war sehr hilfreich! Danke für das Posten dieses Codes :) – Elad

+0

Wow ... das funktioniert als Charme !!!! Danke Mann !! Guter Job – Anita

0

Vermeiden Sie es, die Tabellenansicht jedes Mal neu zu laden, wenn Sie ein Video wiedergeben möchten. Sie können Ihren Videoabspielcode in der sichtbaren Zelle ausführen, ohne die gesamte Tabellenansicht neu laden zu müssen.

Außerdem vermute ich, dass Sie das Video erst dann wirklich wiedergeben möchten, nachdem die Tabellenansicht nicht mehr gescrollt hat. Siehe How to detect when a UIScrollView has finished scrolling (erkennen, wenn ein UIScrollView ist das Scrollen beendet ist überraschend nicht intuitiv).

Wenn Sie wirklich das Video abspielen möchten, bevor der Bildlauf nicht mehr läuft, ändern Sie zumindest Ihren Code, um zu prüfen, ob die sichtbare Zelle bereits abgespielt wird, und tun Sie nichts. Im Moment wird Ihr tableView:cellForRowAtIndexPath: Code, der ein Video abspielt, oft ausgeführt, wann immer eine Zelle voll sichtbar ist (was vermutlich viel passiert!).

Verwandte Themen