开发者

Subtitles for MPMoviePlayerController

Is it possible to configure MPMoviePlayerController to d开发者_C百科isplay subtitles? I tried looking in the documentation but can't find anything related to it there. Thanks


Subtitles/Closed Caption can be directly baked into the media file itself using assortment of applications like QuickTime Pro or Handbrake. Closed Captioning then needs to be turned on in Settings>>Video in order for the MPMoviePlayerController to enable CC for media files with CC baked in.

http://www.3playmedia.com/2011/09/01/how-to-add-closed-captions-or-subtitles-for-iphone-ipad-ipod-itunes-and-apple-ios-using-quicktime-pro/


I know this is late answer, But Valid Answer. Check this MPMoviePlayerController-Subtitles link. i'm updating about this To help others in Future.

MPMoviePlayerController+Subtitles.h

//
//  MPMoviePlayerController+Subtitles.h
//  MPMoviePlayerControllerSubtitles
//
//  Created by mhergon on 03/12/13.
//  Copyright (c) 2013 mhergon. All rights reserved.
//

#import <MediaPlayer/MediaPlayer.h>

@interface MPMoviePlayerController (Subtitles)


#pragma mark - Methods
- (void)openSRTFileAtPath:(NSString *)localFile completion:(void (^)(BOOL finished))success failure:(void (^)(NSError *error))failure;
- (void)showSubtitles;
- (void)hideSubtitles;
@end

MPMoviePlayerController+Subtitles.m

//
//  MPMoviePlayerController+Subtitles.m
//  MPMoviePlayerControllerSubtitles
//
//  Created by mhergon on 03/12/13.
//  Copyright (c) 2013 mhergon. All rights reserved.
//

#import "MPMoviePlayerController+Subtitles.h"
#import <objc/runtime.h>

static NSString *const kIndex = @"kIndex";
static NSString *const kStart = @"kStart";
static NSString *const kEnd = @"kEnd";
static NSString *const kText = @"kText";


@interface MPMoviePlayerViewController ()

#pragma mark - Properties
@property (strong, nonatomic) NSMutableDictionary *subtitlesParts;
@property (strong, nonatomic) NSTimer *subtitleTimer;
@property (strong, nonatomic) UILabel *subtitleLabel;

#pragma mark - Private methods
- (void)showSubtitles:(BOOL)show;
- (void)parseString:(NSString *)string parsed:(void (^)(BOOL parsed, NSError *error))completion;
- (NSTimeInterval)timeFromString:(NSString *)yimeString;
- (void)searchAndShowSubtitle;

#pragma mark - Notifications
- (void)playbackStateDidChange:(NSNotification *)notification;
- (void)orientationWillChange:(NSNotification *)notification;
- (void)orientationDidChange:(NSNotification *)notification;


@end

@implementation MPMoviePlayerController (Subtitles)

#pragma mark - Methods
- (void)openSRTFileAtPath:(NSString *)localFile completion:(void (^)(BOOL finished))success failure:(void (^)(NSError *error))failure {

    // Error
    NSError *error = nil;

    // File to string
    NSString *subtitleString = [NSString stringWithContentsOfFile:localFile
                                                         encoding:NSUTF8StringEncoding
                                                            error:&error];
    if (error && failure != NULL) {
        failure(error);
        return;
    }

    // Parse and show text
    [self parseString:subtitleString
               parsed:^(BOOL parsed, NSError *error) {

                   if (!error && success != NULL) {

                       // Register for notifications
                       [[NSNotificationCenter defaultCenter] addObserver:self
                                                                selector:@selector(playbackStateDidChange:)
                                                                    name:MPMoviePlayerPlaybackStateDidChangeNotification
                                                                  object:nil];

                       [[NSNotificationCenter defaultCenter] addObserver:self
                                                                selector:@selector(orientationWillChange:)
                                                                    name:UIApplicationWillChangeStatusBarFrameNotification
                                                                  object:nil];

                       [[NSNotificationCenter defaultCenter] addObserver:self
                                                                selector:@selector(orientationDidChange:)
                                                                    name:UIDeviceOrientationDidChangeNotification
                                                                  object:nil];

                       success(YES);

                   } else if (error && failure != NULL) {

                       failure(error);

                   }

               }];

}

- (void)showSubtitles:(BOOL)show {

    // Hide label
    self.subtitleLabel.hidden = !show;

}

- (void)showSubtitles {

    [self showSubtitles:YES];

}

- (void)hideSubtitles {

    [self showSubtitles:NO];

}

#pragma mark - Private methods
- (void)parseString:(NSString *)string parsed:(void (^)(BOOL parsed, NSError *error))completion {

    // Create Scanner
    NSScanner *scanner = [NSScanner scannerWithString:string];

    // Subtitles parts
    self.subtitlesParts = [NSMutableDictionary dictionary];

    // Search for members
    while (!scanner.isAtEnd) {

        // Variables
        NSString *indexString;
        [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet]
                                intoString:&indexString];

        NSString *startString;
        [scanner scanUpToString:@" --> " intoString:&startString];
        [scanner scanString:@"-->" intoString:NULL];

        NSString *endString;
        [scanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet]
                                intoString:&endString];



        NSString *textString;
        [scanner scanUpToString:@"\r\n\r\n" intoString:&textString];
        textString = [textString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

        // Regular expression to replace tags
        NSError *error = nil;
        NSRegularExpression *regExp = [NSRegularExpression regularExpressionWithPattern:@"[<|\\{][^>|\\^}]*[>|\\}]"
                                                                                options:NSRegularExpressionCaseInsensitive
                                                                                  error:&error];
        if (error) {
            completion(NO, error);
            return;
        }

        textString = [regExp stringByReplacingMatchesInString:textString
                                                      options:0
                                                        range:NSMakeRange(0, textString.length)
                                                 withTemplate:@""];


        // Temp object
        NSTimeInterval startInterval = [self timeFromString:startString];
        NSTimeInterval endInterval = [self timeFromString:endString];
        NSDictionary *tempInterval = @{
                                       kIndex : indexString,
                                       kStart : @(startInterval),
                                       kEnd : @(endInterval),
                                       kText : textString ? textString : @""
                                       };
        [self.subtitlesParts setObject:tempInterval
                                forKey:indexString];

    }

    completion(YES, nil);

}

- (NSTimeInterval)timeFromString:(NSString *)timeString {

    NSScanner *scanner = [NSScanner scannerWithString:timeString];

    int h, m, s, c;
    [scanner scanInt:&h];
    [scanner scanString:@":" intoString:NULL];
    [scanner scanInt:&m];
    [scanner scanString:@":" intoString:NULL];
    [scanner scanInt:&s];
    [scanner scanString:@"," intoString:NULL];
    [scanner scanInt:&c];

    return (h * 3600) + (m * 60) + s + (c / 1000.0);

}

- (void)searchAndShowSubtitle {

    // Search for timeInterval
    NSPredicate *initialPredicate = [NSPredicate predicateWithFormat:@"(%@ >= %K) AND (%@ <= %K)", @(self.currentPlaybackTime), kStart, @(self.currentPlaybackTime), kEnd];
    NSArray *objectsFound = [[self.subtitlesParts allValues] filteredArrayUsingPredicate:initialPredicate];
    NSDictionary *lastFounded = (NSDictionary *)[objectsFound lastObject];

    // Show text
    if (lastFounded) {

        // Get text
        self.subtitleLabel.text = [lastFounded objectForKey:kText];


        // Label position
        CGSize size = [self.subtitleLabel.text sizeWithFont:self.subtitleLabel.font
                                          constrainedToSize:CGSizeMake(CGRectGetWidth(self.subtitleLabel.bounds), CGFLOAT_MAX)];
        self.subtitleLabel.frame = ({
            CGRect frame = self.subtitleLabel.frame;
            frame.size.height = size.height;
            frame;
        });
        self.subtitleLabel.center = CGPointMake(CGRectGetWidth(self.view.bounds) / 2.0, CGRectGetHeight(self.view.bounds) - (CGRectGetHeight(self.subtitleLabel.bounds) / 2.0) - 15.0);

    } else {

        self.subtitleLabel.text = @"";

    }

}

#pragma mark - Notifications
- (void)playbackStateDidChange:(NSNotification *)notification {

    switch (self.playbackState) {

        case MPMoviePlaybackStateStopped: {

            // Stop
            if (self.subtitleTimer.isValid) {
                [self.subtitleTimer invalidate];
            }

            break;
        }

        case MPMoviePlaybackStatePlaying: {

            // Start timer
            self.subtitleTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
                                                                  target:self
                                                                selector:@selector(searchAndShowSubtitle)
                                                                userInfo:nil
                                                                 repeats:YES];
            [self.subtitleTimer fire];


            // Add label
            if (!self.subtitleLabel) {

                // Add label
                CGFloat fontSize = 0.0;
                if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
                    fontSize = 40.0;
                } else {
                    fontSize = 20.0;
                }
                self.subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0.0, 0.0, CGRectGetWidth(self.view.bounds) - 30.0, 100.0)];
                self.subtitleLabel.center = CGPointMake(CGRectGetWidth(self.view.bounds) / 2.0, CGRectGetHeight(self.view.bounds) - (CGRectGetHeight(self.subtitleLabel.bounds) / 2.0) - 15.0);
                self.subtitleLabel.backgroundColor = [UIColor clearColor];
                self.subtitleLabel.font = [UIFont boldSystemFontOfSize:fontSize];
                self.subtitleLabel.textColor = [UIColor whiteColor];
                self.subtitleLabel.numberOfLines = 0;
                self.subtitleLabel.textAlignment = NSTextAlignmentCenter;
                self.subtitleLabel.layer.shadowColor = [UIColor blackColor].CGColor;
                self.subtitleLabel.layer.shadowOffset = CGSizeMake(6.0, 6.0);
                self.subtitleLabel.layer.shadowOpacity = 0.9;
                self.subtitleLabel.layer.shadowRadius = 4.0;
                self.subtitleLabel.layer.shouldRasterize = YES;
                self.subtitleLabel.layer.rasterizationScale = [[UIScreen mainScreen] scale];
                [self.view addSubview:self.subtitleLabel];

            }

            break;
        }

        default: {

            break;
        }

    }

}

- (void)orientationWillChange:(NSNotification *)notification {

    // Hidden label
    self.subtitleLabel.hidden = YES;

}

- (void)orientationDidChange:(NSNotification *)notification {

    // Label position
    CGSize size = [self.subtitleLabel.text sizeWithFont:self.subtitleLabel.font
                                      constrainedToSize:CGSizeMake(CGRectGetWidth(self.subtitleLabel.bounds), CGFLOAT_MAX)];
    self.subtitleLabel.frame = ({
        CGRect frame = self.subtitleLabel.frame;
        frame.size.height = size.height;
        frame;
    });
    self.subtitleLabel.center = CGPointMake(CGRectGetWidth(self.view.bounds) / 2.0, CGRectGetHeight(self.view.bounds) - (CGRectGetHeight(self.subtitleLabel.bounds) / 2.0) - 15.0);

    // Hidden label
    self.subtitleLabel.hidden = NO;

}

#pragma mark - Others
- (void)dealloc {

    [[NSNotificationCenter defaultCenter] removeObserver:self];

}

- (void)setSubtitlesParts:(NSMutableDictionary *)subtitlesParts {

    objc_setAssociatedObject(self, @"subtitlesParts", subtitlesParts, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (NSMutableDictionary *)subtitlesParts {

    return objc_getAssociatedObject(self, @"subtitlesParts");

}

- (void)setSubtitleTimer:(NSTimer *)timer {

    objc_setAssociatedObject(self, @"timer", timer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (NSTimer *)subtitleTimer {

    return objc_getAssociatedObject(self, @"timer");

}

- (void)setSubtitleLabel:(UILabel *)subtitleLabel {

    objc_setAssociatedObject(self, @"subtitleLabel", subtitleLabel, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (UILabel *)subtitleLabel {

    return objc_getAssociatedObject(self, @"subtitleLabel");

}


@end

Import above class and use following method:

- (IBAction)showVideoAction:(UIButton *)sender {

    // Video file
    NSString *filePathStr = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"mp4"];
    NSURL *fileURL = [NSURL fileURLWithPath:filePathStr];

    // Subtitles file
    NSString *subtitlesPathStr = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"srt"];

    // Create MoviePlayer
    MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc] initWithContentURL:fileURL];
    [player.moviePlayer openSRTFileAtPath:subtitlesPathStr
                               completion:^(BOOL finished) {

                                   // Activate subtitles
                                   [player.moviePlayer showSubtitles];

                                   // Show video
                                   [self presentMoviePlayerViewControllerAnimated:player];

                               } failure:^(NSError *error) {

                                   NSLog(@"Error: %@", error.description);

                               }];

}


I don't think you can port subtitles to it, BUT you can use a UILabel and add it as a subview, and maybe with a little work, set the label text to the specific text at the specific time and act as a subtitle.


Actually, there is built-in functionality for subtitles. You can use iSubtitle to encode soft subs into a video file.

See here: http://www.bitfield.se/isubtitle

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜