How to custom a IOS movie player control bar

How to custom a IOS movie player control bar


To custom a ISO player control bar, you should create a subclass of MPMoviePlayerViewController. If you use MPMoviePlayerController, there is no root view to add a custome view layer. Also, if you want to set movie player’s initial orientation, you must use a subclass of MPMoviePlayerViewController.

The first step is removing the original control bar, you can use

[self.movieplayer setControlStyle:MPMovieControleStyleNone];

and create a custom control bar. the structure is shown as below:

enter image description here

Design

Create a good User-experience player control bar, you should consider following components and functional features:

Components

movie title Label

show movie basic information such as title.

Play/Pause Button

play or stop playing movies.

Back Button

return to previous page

Player Slider

show current play rate, and can seek to specified position.

Current/full Time Label

show playing movie status.

setting selector

give options for user to change movie related characters such as “audio”, “subtitle”, “resolution”.

Note: Because player control bar‘s position should not hinder watching movie. we separate all components into top and bottom of the view to show control bar.

Top Bar

back button | movie title label | setting button(optional)

Bottom Bar

player Slider | current/full time label

Note: Play/pause button was shown in center of the view.

Component Declaration

@interface MyMoviePlayerViewController()
{
    UIButton *centerButton; // play|pause button.
    UIButton *backButton;
    UIButton *settingButton; // optional
    UISlider *playerSlider;
    UIView *playerControlView; // trigger control bar show and hide
    UIView *playerSettingView; // optional,refer to settng button.
    UILabel *currentTimeLabel; 
    UILabel *endTimeLabel;
    float landScapeScreenWidth;
    float landScapeScreenHeight;
    NSTimer *timer ; // this timer is used for updating "current Time" and "player slider".
    NSTimer *subtitleTimer;
    NSTimer *autohide; // auto hide control bar after losing user focus.
    UIView *topbarBG;
    UIView *bottombarBG;
    UIImageView *subtitleView;
    UIActivityIndicatorView *loadingButton;
    BOOL isinit;
    NSMutableDictionary *subtitleArray;
    NSMutableArray *currentSubtitle;
    double lastControlTime; 
    UITapGestureRecognizer *tapGesture; // detect touch event on player control
    UITapGestureRecognizer *tapGesture2; // detect touch event on player slider bar
    NSString *subtitleLanguage;
    NSTimeInterval lastViewTime;
    int initX;
    int initY;

}

Features

control bar show/hide

control bar can auto hide in 5 seconds after losing user’s focus

source Code:

autohide = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(autoHidePlayerControl) userInfo:nil repeats:YES];

-(void)autoHidePlayerControl
{
    float duration = CFAbsoluteTimeGetCurrent() - lastControlTime; // lastControlTime records latest operation time
    NSLog(@"%f",duration);
    if(isControlViewShowed && duration> 5){ // 5 seconds remain time before hiding it
        [UIView animateWithDuration:0.5 animations:^{
            [self hidePlayerControl];
            isControlViewShowed = NO;
        }];
    }
}

current play Time update

update real playing time per second.

source code:

timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(updateSlider) userInfo:nil repeats:YES];

-(void)updateSlider {

    if(!isSilderTouched){
        float value = self.moviePlayer.currentPlaybackTime/self.moviePlayer.duration;
        [playerSlider setValue: value animated:YES]; 
        currentTimeLabel.text = [self secondsToMMSS:self.moviePlayer.currentPlaybackTime];
    }
}

-(NSString *)secondsToMMSS:(double)seconds  //transfor min-seconds to H:MM:SS
{
    NSInteger time = floor(seconds);
    NSInteger hh = time / 3600;
    NSInteger mm = (time / 60) % 60;
    NSInteger ss = time % 60;
    if(hh > 0)
        return  [NSString stringWithFormat:@"%d:%02i:%02i",hh,mm,ss];
    else
        return  [NSString stringWithFormat:@"%02i:%02i",mm,ss];


}

player slider control

playerSlider = [[UISlider alloc] init];
[playerSlider setContinuous:YES];
[playerSlider setHighlighted:YES];
// remove the slider filling default blue color
[playerSlider setMaximumTrackTintColor:[UIColor colorWithRed:193.0f/255.0f green:193.0f/255.0f blue:193.0f/255.0f alpha:1]];
[playerSlider setMinimumTrackTintColor:[UIColor colorWithRed:11.0f/255.0f green:156.0f/255.0f blue:231.0f/255.0f alpha:1]];
playerSlider.frame = CGRectMake(landScapeScreenWidth*0.1f, 0, landScapeScreenWidth*0.8f , 22);

Two ways to seek movies:

A. draging slider bar’s thumb

[playerSlider addTarget:self action:@selector(sliderMoveStart) forControlEvents:UIControlEventTouchDown];
[playerSlider addTarget:self action:@selector(sliderMoving) forControlEvents:UIControlEventTouchDragInside];
[playerSlider addTarget:self action:@selector(sliderMoveEnd) forControlEvents:UIControlEventTouchUpInside];

-(void)sliderMoveStart{

    isSilderTouched = YES;

}
-(void)sliderMoving{
    lastControlTime = CFAbsoluteTimeGetCurrent();
    isSilderTouched = YES;
    double time = self.moviePlayer.duration * playerSlider.value;
    currentTimeLabel.text = [self secondsToMMSS:time]; //
}
-(void)sliderMoveEnd
{
    self.moviePlayer.currentPlaybackTime = self.moviePlayer.duration * playerSlider.value;
}

B. click slider bar

-(void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
    NSLog(@"%@",recognizer.view.class.description);
    if(recognizer.view == playerControlView){
        NSLog(@"CONTROLVIEW CLICKED");
        if(isControlViewShowed){
            [UIView animateWithDuration:0.5 animations:^{
                [self hidePlayerControl];
            }];
        }
        else{
            lastControlTime = CFAbsoluteTimeGetCurrent();
            [UIView animateWithDuration:0.5 animations:^{
                [self showPlayerControl];
            }];
        }

    }else if(recognizer.view == playerSlider){
        isSilderTouched = YES;
        lastControlTime = CFAbsoluteTimeGetCurrent();
        CGPoint translation = [recognizer locationInView:recognizer.view]; // obtain touch location
        float rate = translation.x / (landScapeScreenWidth*0.8f); // calculate corresponded playback Rate
        playerSlider.value = rate; // update player slider value
        self.moviePlayer.currentPlaybackTime = self.moviePlayer.duration * rate; // seek movie
        currentTimeLabel.text = [self secondsToMMSS:self.moviePlayer.currentPlaybackTime]; //update current play time
        NSLog(@"%f",translation.x);
        NSLog(@"click outside");
    }

}

For full version source code, please click here

留下评论