Search code examples
iosuitableviewmpmovieplayercontroller

display thumbnails of video in tableviewcell


This is my code which is working perfectly . Here i m accessing array of videos in my tableview.....

This is my array of videos and videos are in my bundle...

        - (void)viewDidLoad {
            [super viewDidLoad];
             videos = [[NSMutableArray alloc] initWithObjects:
                         @"video 1",
                         @"video 2",

                         nil];
        }

Accessing videos in tableview .....

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

            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        }
        NSIndexPath *index ;

        index = [self.table indexPathForCell:cell];
        NSLog(@"%@----hello",indexPath);

// taking path of video from bundle 
        NSString *filePath = [[NSBundle mainBundle]pathForResource:[videos objectAtIndex:indexPath.row] ofType:@"mp4"];

//declare nsurl and mpmoviplayer globally..
        movieURL = [NSURL fileURLWithPath:filePath];


  // <converting image in thumbnail...
        AVAsset* videoAsset = [AVAsset assetWithURL:movieURL];

        AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:videoAsset];

        Float64 durationSeconds = CMTimeGetSeconds([videoAsset duration]);
        CMTime midpoint = CMTimeMakeWithSeconds(durationSeconds/2.0, 600);
        NSError* error = nil;
        CMTime actualTime;

        //generating image...
        CGImageRef halfWayImage = [imageGenerator copyCGImageAtTime:midpoint actualTime:&actualTime error:&error];


   // show image in uiimage of tableviewcell....
        cell.imageView.image=[UIImage imageWithCGImage:halfWayImage];
        cell.textLabel.text= [videos objectAtIndex:indexPath.row];


        return cell;

        }

Accessing videos in other view through Segue......

        - (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
                if ([segue.identifier isEqualToString:@"showDetailsSeg"]) {

//playing video in other view controller....

                    [[player view] setFrame: self.view.frame];
                    [self.view addSubview: [player view]];

                    [self presentMoviePlayerViewControllerAnimated:player];

//using sequel for destination controller
                    [segue destinationViewController] ;
               }
        }

Done....


Solution

  • If "video" it is instance of ALAsset, then you can use - (CGImageRef)thumbnail method:

    UIImage* thumb = [UIImage imageWithCGImage:[video thumbnail]];
    

    If you use AVAsset to present video objects, you can use AVAssetImageGenerator to get image at specific time and use this image to generate thumb.

    You can do something like this:

    dispatch_async(dispatch_get_main_queue(), ^{
        NSURL* urlToVideo = [NSURL URLWithString:@"file://localPathToVideo"];
        AVAsset* videoAsset = [AVAsset assetWithURL:urlToVideo];
    
        AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:videoAsset];
    
        Float64 durationSeconds = CMTimeGetSeconds([videoAsset duration]);
        CMTime midpoint = CMTimeMakeWithSeconds(durationSeconds/2.0, 600);
        NSError* error = nil;
        CMTime actualTime;
    
        CGImageRef halfWayImage = [imageGenerator copyCGImageAtTime:midpoint actualTime:&actualTime error:&error];
    
        UIImage* resultUIImage = nil;
        if (halfWayImage != NULL) {
            resultUIImage = [UIImage imageWithCGImage:halfWayImage];
    
            CGImageRelease(halfWayImage);
    
            //resize image (use some code for resize)
            //<>
            //TODO: call some method to resize image
            UIImage* resizedImage = resultUIImage;
            //<>
    
            dispatch_async(dispatch_get_main_queue(), ^{
                //TODO: set resized image to destination
                //if(cell.asset == videoAsset)
                //{
                //   cell.thumb.image = resizedImage
                //}
            });         
        }
        else
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                //TODO: do something if you can't generate preview.
            });
        }
    });
    

    UPD


    Explanation, why developer should use ALAsset or AVAsset to present video in application. Video it is binary file with complex structure, to access to video data you can wright your own library, and generate thumbs from video with your methods. But iOS SDK provide some methods to working with video. The SDK contain ALFoundation framework, it framework let to work with video at any path (in your opinion in Documents directory), you have to know only video URL (or local path). If you get video from AssetsLibrary (photos), then you have ALAsset (presents some item from Library), ALAsset has type property and thumb property, and URL to asset.


    To use ALFoundation you should import this library:

    @import AVFoundation;
    

    To use AssetsLibrary you should import this library:

    @import AssetsLibrary;
    

    Also I think you should read presented links, before write code.