Search code examples
objective-cuitableviewvideompmovieplayercontrollervine

Vine like table view cells starts playing video always slowly


I'm developing an app having similar feeds like Vine app. I used MPMoviePlayerController for playing the video in the UITableviewcells. I have created a custom tableview cell with MPMoviePlayerController and now loading a sample test video from the bundle. For playing the video automatically when the cell is visible I used the following code.

- (FMVideoTableViewCell *)detectCenterCell
{
    // Returns the FMVideoTableViewCell at the center of the screen.
    // Assuming the center point to be (width/2,height/2).

    return (FMVideoTableViewCell *)[self.tableView cellForRowAtIndexPath:[self findIndexPathForCellAtLocation:self.tableView.frame.size.width / 2 and:self.tableView.frame.size.height / 2]];
}

The above function returns the current visible cell and I called this function in the following scrollview delegate.

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;

Along with that I'm stopping the video playing in the non visible cells of the UITableview using the following methods.

- (FMVideoTableViewCell *)detectTopCell
{
    // Returns the FMVideoTableViewCell which touches the top frame of the TableView.
    // Assuming the top point to be (10,10).

    return (FMVideoTableViewCell *)[self.tableView cellForRowAtIndexPath:[self findIndexPathForCellAtLocation:10 and:10]];
}

- (FMVideoTableViewCell *)detectBottomCell
{
    // Returns the FMVideoTableViewCell which touches the bottom frame of the TableView.
    // Assuming the bottom point to be (width/2,height).

    return (FMVideoTableViewCell *)[self.tableView cellForRowAtIndexPath:[self findIndexPathForCellAtLocation:self.tableView.frame.size.width / 2 and:self.tableView.frame.size.height]];
}

Everything is working fine as I expected without any stuck while scrolling the Tableview. The only one issue that I'm facing now is there is a delay for MPMovieplayer to start playing the video. I tried prepareToPlay property to remove this initial latency. But this causes some black screens in the Tableview cells while scrolling and also reduces the smoothness of Tableview scroll. Then I go for alternative solution to start playing video when the velocity of the tableview drops, without waiting for the Scrollview delegates to fire. I used the following codes for that.

    static double prevCallTime = 0;
    static double prevCallOffset = 0;

    //Simple velocity calculation
    double curCallTime = CACurrentMediaTime();
    double timeDelta = curCallTime - prevCallTime;
    double curCallOffset = self.tableView.contentOffset.y;
    double offsetDelta = curCallOffset - prevCallOffset;
    double velocity = fabs(offsetDelta / timeDelta);
    NSLog(@"Velocity: %f", velocity);

    if(velocity < 500 && velocity > 50)
    {
        [self preLoadVideo];
    }

    prevCallTime = curCallTime;
    prevCallOffset = curCallOffset;

scrollViewDidEndDragging will be fired only after ending the tableview scroll. So to start the video play without waiting for the tableview scroll to end, I tried the same action inside scrollViewWillEndDragging. But the time difference between scrollViewWillEndDragging and scrollViewDidEndDragging is negotiable. So I tried the alternative method to call the video play action inside the tableview willDisplayCell delegate.

But this also did't helped me to reduce the initial time for the player to start playing. Please help me to solve this issue. Thanks in advance.


Solution

  • At last I implemented vine like video listing successfully by replacing MPMoviePlayer with AVPlayer. I think AVPlayer is a light weighted player when compared to MPMoviePlayer. Also it allows us to play multiple videos simultaneously.