YTPlayerView inside UITableViewCell

2019-02-17 16:02发布

问题:

I have a YTPlayerView inside of my subclass of UITableViewCell. In my UIViewController I call [cell.youtubeView loadWithVideoId:f.videoID]; from my tableViewDelagate willDisplayCell method. The problem is that when I have many cells in my tableView some of them stay white instead of the YouTube content!

Youtube API recommends when reusing the YTPlayerView to load the content by calling [cell.youtubeView cueVideoById:f.videoID startSeconds:0 suggestedQuality:kYTPlaybackQualityHighRes]; instead. Unfortunately, this method doesn't load YouTube content at all.

Anybody came across the same issue? Any known solution?

I was thinking to load first time the content with loadWithVideoId and then cueVideoById but that didn't work.

回答1:

I had this problem using YTPlayerView instances in UIColectionViewCell instances. Ultimately what I had to do was stop the video in didEndDisplayingCell ([self.playerView stopVideo]). Then in prepareForReuse (or optionally in cellForRowAtIndexPath), nil out your playerView, and in cellForRowAtIndexPath re-init the player and load the video by id.



回答2:

I used YTPlayerView in UICollectionView(Similar to your case).

In my case, YTPlayerView got black when it was drawn in reused UICollectionViewCell(load properly on firstly initiated cell).

YTPlayerView got black is because -loadWithVideoId:playerVars: is called twice before the firstly invoked method is complete.

I checked white YTPlayerView is for not loaded video, so I recommend checking -loadWithVideoId: or similar methods called properly in somewhere.



回答3:

Swift 3

I had the same issue. My problem was that the method load(withVideoId: videoId) was called several times (because of the cellForRow called several times while scrolling).

I solved this by creating a Boolean and making sure the load(withVideoId: videoId) is called only once :

1) In the cell class, create a global Boolean

var isAlreadyPlaying : Bool = false

2) When you want to play your video, we set our boolean to avoid playing it several times :

func loadVideo() {

    //Making sure we are not playing the video several time
    if isAlreadyPlaying == false {

        //Creating vars (optional)
        let playerVars = ["playsinline": 1, "autoplay": 1, "autohide": 1, "controls" : 1, "showinfo" : 0, "modestbranding" : 1, "rel" : 0]

        // Launching the video 
        youtTubeView?.load(withVideoId: videoId, playerVars : playerVars)

        // Force to not play the video again
        isAlreadyPlaying = true
    }

}


回答4:

Here is another approach, purists won't like it, but I couldn't find out how to properly free/re-init the YTPlayerView created in my custom UICollectionViewCell.

Considering you will only play one video at time, because two several instances of YTPlayer won't play simultaneously, you just have to hide reused cells with video's thumbnail. Simply put an UIImageView above the YTplayerView in your sublclass of UICollectionViewCell xib, and set the thumbnail in it:

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

   //... load customcell xib, manage cellId etc. 

   // set video id that will be read by the custom cell 
   [cell setVideoId:cellVideoId];

   // set above UIImage 
   NSData * thumbnailData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: videoThumbnailURL]];
   UIImage * videoThumbnail = [UIImage imageWithData: thumbnailData];
   [cell.thumbnailImage setImage:videoThumbnail];
   return cell;
}

There, in custom UICollectionViewCell .m file you just need to implement a button that launch the video when clicked ...

- (IBAction)clickPlay:(id)sender {
    if (videoId != nil){        
        [ccellYTPlayerView loadWithVideoId:videoId playerVars:playerVars];

        // Hide thumbnail image to reveal the YTPlayerView
        [thumbnailImage setHidden:true];
    }
}

... and configure reusability of this custom cell, which works flawlessly for native obvjects :

-(void) prepareForReuse{
    [super prepareForReuse];

    // preparing UIImage to host another thumbnail
    thumbnailImage.image = nil;
    [thumbnailImage setHidden:false];
}

This way, YTplayers can appear in other cells, no one will see it because hidden by the thumbnail, and the sound produced is not a problem because user will assume that it comes from the original cell (which is not on screen anymore because of scrolling).

I know that's not really clean, but it helped me so far, YTPlayer instance is not so easy to recycle.