11

I have read several posts here about live streaming video/audio. Unfortunately it seems that there is not any "good" solution.

I want same functionality for video which is provided SDWebImageView for images.

Right now, I am using following code:-

NSURL *url=[[NSURL alloc] initWithString:@"http://www.ebookfrenzy.com/ios_book/movie/movie.mov"];
MPMoviePlayerController *moviePlayer=[[MPMoviePlayerController alloc] initWithContentURL:url];
moviePlayer.controlStyle=MPMovieControlStyleDefault;
moviePlayer.shouldAutoplay=YES;

But when I scrolled tableview, all videos download again and again. So How can I stop that downloading?

Is there any better solution for playing video into UITableView? Same Facebook, Instagram, and Vine Apps doing?

JAL
  • 41,701
  • 23
  • 172
  • 300
Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
  • 3
    MPMoviePlayerController and MPMoviePlayerViewController are deprecated since iOS 9 onwards. You should use some other player controller. Refer https://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/MPMoviePlayerController_Class/ and https://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/MPMoviePlayerViewController_class/index.html#//apple_ref/occ/cl/MPMoviePlayerViewController – Skywalker Dec 30 '15 at 09:09
  • Ok. Then I will be use AVPlayerViewController . But my issue is how can I stop that again and again downloading that video due to tableview.. – Meet Doshi Dec 30 '15 at 09:19
  • 1
    I think this answer will help..http://stackoverflow.com/a/14961854/5316422 – Skywalker Dec 30 '15 at 09:25
  • MPMoviePlayerController is deprecated in iOS 9. Use AVPlayerViewController instead. – Nilesh Dec 30 '15 at 11:23
  • I know that. I also used this http://stackoverflow.com/a/31277658/3908884. But my issue is how can I stop downloading video every time when I scrolled that cell. – Meet Doshi Dec 30 '15 at 11:26
  • Where have you implemented this code ? – Niko Feb 08 '16 at 09:53
  • Into my app. I want to make feeds Listing screen with video functionality. Still I am not getting exact solution.. If you have, please help me.. – Meet Doshi Feb 08 '16 at 12:43

3 Answers3

9

Don't use MPMoviePlayerController, use AVFoundation's AVPlayer.

Additionally, don't couple the downloading of your asset to your UITableViewCell subclass. Use an additional data source to download and manage the video assets.

There are a few ways you can do this.

  1. Keep a data source array of AVPlayerItem objects initialized by URL. Instead of loading the asset each time you scroll to a cell, just load the AVPlayerItem into the cell's player, and remove it when you scroll away.

  2. If you need to persist the video data, consider downloading each video to a temporary file in your Documents directory. When the file has finished downloading, load that data into an AVAsset using its initWithURL: method and point the URL to your local file. When ready, you can load your asset into an AVPlayerItem using initWithAsset: and play the video.

JAL
  • 41,701
  • 23
  • 172
  • 300
7

When you scroll table view then method -tableView:cellForRowAtIndexPath: is fired (actually every time when cell will be visible this method is called). I believe that you are allocating and initializing yours MediaPlayer in this method and that's why video is downloaded again. You could try to add array and store already created cells in it (some kind of cache). Then your -tableView:cellForRowAtIndexPath should check if it has sth cached for actual index. If yes then show cached cell. If no then it should create cell, alloc, and init player and then store cell in cache.

My ViewController has property: NSMutableDictionary *cache; and in ViewDidLoad I have: cache = [[NSMutableDictionary alloc] init]; My -tableView:cellForRowAtIndexPath: looks like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellId = @"myCellId";

    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];

    if ([cache objectForKey:[NSString stringWithFormat:@"key%lu", indexPath.row]] != nil) {
        cell = [cache objectForKey:[NSString stringWithFormat:@"key%lu", indexPath.row]];
    } else {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"MyTableViewCell" owner:self options:nil];
        cell = [nib objectAtIndex:0];

        AVPlayerViewController *playerViewController = [[AVPlayerViewController alloc] init];
        playerViewController.player = [AVPlayer playerWithURL:[[NSURL alloc] initWithString:@"http://www.ebookfrenzy.com/ios_book/movie/movie.mov"]];
        [cell addSubview:playerViewController.view];
        [cache setValue:cell forKey:[NSString stringWithFormat:@"key%lu", indexPath.row]];
    }

    return cell; 
}

It works for me. Of course you need to use your own datasource etc.

JAL
  • 41,701
  • 23
  • 172
  • 300
owocki
  • 71
  • 7
  • 1
    I already tried this. But not working like I want.. If you have sample code for this, then Please Provide. Its better for me.. Check comment of @Meharoof Najeeb under question.. – Meet Doshi Feb 02 '16 at 11:09
3

Swift 3

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
    let videoURL = NSURL(string: "http://www.ebookfrenzy.com/ios_book/movie/movie.mov")
    let player = AVPlayer(url: videoURL! as URL)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = cell.bounds
    cell.layer.addSublayer(playerLayer)
    player.play()
    return cell
}
Aayushi
  • 787
  • 10
  • 14