1

I'm looking for the best way to play back video files in my iOS App. My app is currently in development and there will be around 50 videos (each 30 seconds long) with short tutorials. If possible I want them all local, so users can watch the videos when they do not have an internet connection. I could not find a similar question on stack overflow (maybe I'm looking in the wrong section, please correct me if I'm wrong).

So I was thinking about 2 different options:

  • User downloads app from store, including videos
  • User downloads app without the videos, and has to download the videos first when using the app for the first time and save them locally (forever)

If there are better options, I would also like to know them! So if anyone has experience with this, I would really appreciate some help! Thanks

Colinch
  • 243
  • 2
  • 6
  • 22
  • let me know if down answer is not what you are looking for. will be happy to change or delete. – rahul_send89 Oct 05 '14 at 14:24
  • @rahul_send89 Thank you so much for your answer! I will try to implement this in my app and see if this really is what I was looking for, if so I will accept your answer. – Colinch Oct 06 '14 at 07:17

1 Answers1

3

as per the user point of view people prefer offline mode . and want app size to be as low as possible when they download the app from the Appstore. so my recommendation is to build a video player which have both option to stream file while user is online and play offline downloadable or cached files ..

one way is to:

use a webserver

simple java server example :
https://github.com/mooncatventures-group/StreamX
check : http://www.onlinevideo.net/2011/05/streaming-vs-progressive-download-vs-adaptive-streaming/

its better to build a app which give user the power to download and store app content after the app is been downloaded from app store . app should have option to delete app downloaded videos or to clear cache .

down is an example of video player which can play both offline and online video .

Make a custom Movie Player ..


//CustomMoviePlayerViewController.h File 
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>

@interface CustomMoviePlayerViewController : UIViewController 
{
    MPMoviePlayerController *mp;
    NSURL *movieURL;
}

- (id)initWithPath:(NSString *)moviePath;
- (id)initWithURL:(NSString *)moviePath;
- (void)readyPlayer;

@end

CustomMoviePlayerViewController.m File

#import "CustomMoviePlayerViewController.h"

#pragma mark -
#pragma mark Compiler Directives & Static Variables

@implementation CustomMoviePlayerViewController

/*---------------------------------------------------------------------------
* 
*--------------------------------------------------------------------------*/
- (id)initWithPath:(NSString *)moviePath
{
    // Initialize and create movie URL
  if (self = [super init])
  {
      movieURL = [NSURL fileURLWithPath:moviePath];    
    [movieURL retain];
  }
    return self;
}
- (id)initWithURL:(NSString *)moviePath{
    // Initialize and create movie URL
    if (self = [super init])
    {
        movieURL = [NSURL URLWithString:moviePath];    
        [movieURL retain];
    }
    return self;

}

/*---------------------------------------------------------------------------
* For 3.2 and 4.x devices
* For 3.1.x devices see moviePreloadDidFinish:
*--------------------------------------------------------------------------*/
- (void) moviePlayerLoadStateChanged:(NSNotification*)notification 
{
    // Unless state is unknown, start playback
    if ([mp loadState] != MPMovieLoadStateUnknown)
  {
    // Remove observer
    [[NSNotificationCenter  defaultCenter] 
                                                    removeObserver:self
                                name:MPMoviePlayerLoadStateDidChangeNotification 
                                object:nil];

    // When tapping movie, status bar will appear, it shows up
    // in portrait mode by default. Set orientation to landscape
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight animated:NO];

        // Rotate the view for landscape playback
      [[self view] setBounds:CGRectMake(0, 0, 480, 320)];
        [[self view] setCenter:CGPointMake(160, 240)];
        [[self view] setTransform:CGAffineTransformMakeRotation(M_PI / 2)]; 

        // Set frame of movieplayer
        [[mp view] setFrame:CGRectMake(0, 0, 480, 320)];

    // Add movie player as subview
      [[self view] addSubview:[mp view]];   

        // Play the movie
        [mp play];
    }
}

/*---------------------------------------------------------------------------
* For 3.1.x devices
* For 3.2 and 4.x see moviePlayerLoadStateChanged: 
*--------------------------------------------------------------------------*/
- (void) moviePreloadDidFinish:(NSNotification*)notification 
{
    // Remove observer
    [[NSNotificationCenter  defaultCenter] 
                                                    removeObserver:self
                            name:MPMoviePlayerContentPreloadDidFinishNotification
                            object:nil];

    // Play the movie
    [mp play];
}

/*---------------------------------------------------------------------------
* 
*--------------------------------------------------------------------------*/
- (void) moviePlayBackDidFinish:(NSNotification*)notification 
{    
  [[UIApplication sharedApplication] setStatusBarHidden:YES];

    // Remove observer
  [[NSNotificationCenter    defaultCenter] 
                                                removeObserver:self
                            name:MPMoviePlayerPlaybackDidFinishNotification 
                            object:nil];

    [self dismissModalViewControllerAnimated:YES];  
}

/*---------------------------------------------------------------------------
*
*--------------------------------------------------------------------------*/
- (void) readyPlayer
{
    mp =  [[MPMoviePlayerController alloc] initWithContentURL:movieURL];

  if ([mp respondsToSelector:@selector(loadState)]) 
  {
    [mp setMovieSourceType:MPMovieSourceTypeFile];
    // Set movie player layout
    [mp setControlStyle:MPMovieControlStyleFullscreen];
    [mp setFullscreen:YES];

        // May help to reduce latency
        [mp prepareToPlay];

        // Register that the load state changed (movie is ready)
        [[NSNotificationCenter defaultCenter] addObserver:self 
                       selector:@selector(moviePlayerLoadStateChanged:) 
                       name:MPMoviePlayerLoadStateDidChangeNotification 
                       object:nil];
    }  
  else
  {
    // Register to receive a notification when the movie is in memory and ready to play.
    [[NSNotificationCenter defaultCenter] addObserver:self 
                         selector:@selector(moviePreloadDidFinish:) 
                         name:MPMoviePlayerContentPreloadDidFinishNotification
                         object:nil];
  }

  // Register to receive a notification when the movie has finished playing. 
  [[NSNotificationCenter defaultCenter] addObserver:self 
                        selector:@selector(moviePlayBackDidFinish:) 
                        name:MPMoviePlayerPlaybackDidFinishNotification 
                        object:nil];
}

/*---------------------------------------------------------------------------
* 
*--------------------------------------------------------------------------*/
- (void) loadView
{
  [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]];
    [[self view] setBackgroundColor:[UIColor blackColor]];
}

/*---------------------------------------------------------------------------
*  
*--------------------------------------------------------------------------*/
- (void)dealloc 
{
    [mp release];
  [movieURL release];
    [super dealloc];
}

@end

Make your player View visible when u click TableListView cell.

//- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *filePath = [NSString stringWithFormat:@"%@",[documentsDirectory stringByAppendingPathComponent:[item valueForKey:@"URL"]]];
        bool b=[[NSFileManager defaultManager] fileExistsAtPath:filePath];

CustomMoviePlayerViewController *moviePlayer;

if (b) {
    moviePlayer = [[[CustomMoviePlayerViewController alloc] initWithPath:filePath] autorelease];
    [self presentModalViewController:moviePlayer animated:YES];
    [moviePlayer readyPlayer];
}else{
    NSDictionary *item = [tableData objectAtIndex:[indexPath row]];
    NSString *strURL = [NSString stringWithFormat:[item valueForKey:@"URL"]];
    moviePlayer = [[[CustomMoviePlayerViewController alloc] initWithURL:strURL] autorelease];
    [self presentModalViewController:moviePlayer animated:YES];
    [moviePlayer readyPlayer];
}

Make A URL Downloader. save file in .

https://github.com/AFNetworking/AFNetworking

-(void)downloadFile:(NSString *)UrlAddress
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:UrlAddress]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSString *fileName = UrlAddress;

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:fileName];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Successfully downloaded file to %@", path);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {

    NSLog(@"Download = %f", (float)totalBytesRead / totalBytesExpectedToRead);

}];
[operation start];
}

So this will allow you to save File and play + play preloaded files which are already present within your app.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
rahul_send89
  • 943
  • 8
  • 19