2014-07-18 13 views
7

Tôi có một Mảng chứa URL video, tôi muốn phát những video đó trên UITableviewcell khi nó được hiển thị đầy đủ.Phát video trên UITableViewCell khi hiển thị hoàn toàn

Tôi đã cố gắng này

- (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]; 
    } 
} 

này hoạt động tốt - nhưng nó khủng khiếp làm chậm di chuyển của xem bảng. Vui lòng đề xuất cho tôi một số phương pháp tốt hơn khác.

+5

videoActivity là gì? –

+0

@MitulNakum Đây là chỉ số hoạt động. –

Trả lời

9

Bạn có thể sử dụng

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

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

Và trong 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

bạn có thể trả lời http://stackoverflow.com/questions/34767717/tableview-cell-video-autoplay? –

+0

@nNthin M Keloth - Bool đầy đủ này là gì? –

+0

@Nitin Fullvisible && index này là gì? Nơi chúng tôi tăng chỉ mục? –

8

Bạn đang tải các mục video của mình một cách đồng thời trong chuỗi chính; điều đó có nghĩa là các mục video của bạn đang được tải xuống và tải trong các ô xem bảng cùng lúc với các ô xem bảng đang được tạo. Điều đó gây ra vấn đề và làm cho việc di chuyển rất chậm và chậm. Để khắc phục sự cố bạn cần tải video của mình một cách không đồng bộ, trong một chuỗi riêng biệt.

Vì vậy, bạn phải tránh tải hình ảnh một cách đồng bộ, nhưng thay vì không đồng bộ, sử dụng một chuỗi khác với chuỗi chính, sao cho cuộn và tải + hiển thị hình ảnh có thể được thực hiện một cách phụ thuộc, tránh bất kỳ sự chậm trễ nào. Đây có thể là một câu hỏi trùng lặp, vì nó đã được hỏi và có hướng dẫn ở đó, nhưng vì bản thân tôi luôn gặp vấn đề với điều này (nhưng đối với hình ảnh) trên ứng dụng iOS đầu tiên của tôi và thấy nó rất khó hiểu, tôi đang đăng câu trả lời ở đây, hy vọng nó hữu ích.

Thử di chuyển tất cả các dòng liên quan đến tải/hiển thị video, đặc biệt là playerItemWithURL trong số - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath: của bạn thành một khối riêng biệt. Ngoài ra, hãy tìm kiếm và đọc bài đăng khác về "tải video không đồng bộ trong các ô xem bảng". Có rất nhiều hướng dẫn chuyên sâu và Q/As về điều này.

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

Bạn có nhớ chia sẻ cách bạn xử lý việc xóa bộ điều khiển xem của bạn với tư cách là người quan sát cho ô. VideoItem để phát lạiBufferEmpty và playbackLikelyToKeepUp? – user3344977

+0

Điều này rất hữu ích! Cảm ơn bạn đã đăng mã này :) – Elad

+0

Wow ... công trình này như quyến rũ !!!! Cảm ơn người đàn ông !! Công việc tốt – Anita

0

Tránh tải lại chế độ xem bảng mỗi lần bạn muốn phát video. Bạn có thể thực hiện mã video đang phát trên ô hiển thị mà không phải tải lại toàn bộ tableview.

Ngoài ra, tôi nghi ngờ bạn không thực sự muốn phát video cho đến sau khi chế độ xem bảng đã ngừng cuộn. Xem How to detect when a UIScrollView has finished scrolling (phát hiện khi UIScrollView cuộn xong là đáng ngạc nhiên không trực quan).

Nếu bạn thực sự muốn bắt đầu phát video trước khi chế độ xem cuộn ngừng cuộn, ít nhất hãy sửa đổi mã của bạn để kiểm tra xem ô hiển thị đã phát chưa, không làm gì cả. Hiện tại, mã tableView:cellForRowAtIndexPath: phát video của bạn được thực thi nhiều lần, nhiều lần bất cứ khi nào một ô hiển thị đầy đủ (điều tôi nghi ngờ xảy ra rất nhiều!).

Các vấn đề liên quan