From e8f97527d91e5f6635328f58404527771e06dbb8 Mon Sep 17 00:00:00 2001 From: mhergon Date: Wed, 18 Nov 2015 17:38:30 +0100 Subject: [PATCH] v2.0.1 --- .../project.pbxproj | 8 +- .../contents.xcworkspacedata | 7 + .../UserInterfaceState.xcuserstate | Bin 0 -> 11210 bytes ...MPMoviePlayerController-Subtitles.xcscheme | 91 ++++++ .../xcschemes/xcschememanagement.plist | 22 ++ .../MPMoviePlayerController-Subtitles.swift | 296 ------------------ MPMoviePlayerController-Subtitles.podspec | 4 +- MPMoviePlayerController-Subtitles.swift | 4 +- 8 files changed, 128 insertions(+), 304 deletions(-) create mode 100644 Example/MPMoviePlayerController-Subtitles.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 Example/MPMoviePlayerController-Subtitles.xcodeproj/project.xcworkspace/xcuserdata/mhergon.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 Example/MPMoviePlayerController-Subtitles.xcodeproj/xcuserdata/mhergon.xcuserdatad/xcschemes/MPMoviePlayerController-Subtitles.xcscheme create mode 100644 Example/MPMoviePlayerController-Subtitles.xcodeproj/xcuserdata/mhergon.xcuserdatad/xcschemes/xcschememanagement.plist delete mode 100644 Example/MPMoviePlayerController-Subtitles/MPMoviePlayerController-Subtitles.swift diff --git a/Example/MPMoviePlayerController-Subtitles.xcodeproj/project.pbxproj b/Example/MPMoviePlayerController-Subtitles.xcodeproj/project.pbxproj index df2009e..0631945 100644 --- a/Example/MPMoviePlayerController-Subtitles.xcodeproj/project.pbxproj +++ b/Example/MPMoviePlayerController-Subtitles.xcodeproj/project.pbxproj @@ -13,8 +13,8 @@ 4B4966481BF8F87E00CD6060 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B4966461BF8F87E00CD6060 /* Main.storyboard */; }; 4B49664A1BF8F87E00CD6060 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B4966491BF8F87E00CD6060 /* Assets.xcassets */; }; 4B49664D1BF8F87E00CD6060 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B49664B1BF8F87E00CD6060 /* LaunchScreen.storyboard */; }; + 4B607D561BFCE0C2001090B5 /* MPMoviePlayerController-Subtitles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B607D551BFCE0C2001090B5 /* MPMoviePlayerController-Subtitles.swift */; }; 4B711ABB1BF900530017C8DA /* trailer_720p.mov in Resources */ = {isa = PBXBuildFile; fileRef = 4B711ABA1BF900530017C8DA /* trailer_720p.mov */; }; - 4B711ABE1BF900D20017C8DA /* MPMoviePlayerController-Subtitles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B711ABD1BF900D20017C8DA /* MPMoviePlayerController-Subtitles.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -26,8 +26,8 @@ 4B4966491BF8F87E00CD6060 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 4B49664C1BF8F87E00CD6060 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 4B49664E1BF8F87E00CD6060 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4B607D551BFCE0C2001090B5 /* MPMoviePlayerController-Subtitles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "MPMoviePlayerController-Subtitles.swift"; path = "../../MPMoviePlayerController-Subtitles.swift"; sourceTree = ""; }; 4B711ABA1BF900530017C8DA /* trailer_720p.mov */ = {isa = PBXFileReference; lastKnownFileType = video.quicktime; path = trailer_720p.mov; sourceTree = ""; }; - 4B711ABD1BF900D20017C8DA /* MPMoviePlayerController-Subtitles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MPMoviePlayerController-Subtitles.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -84,7 +84,7 @@ 4B711ABC1BF900A90017C8DA /* MPMoviePlayerController-Subtitles */ = { isa = PBXGroup; children = ( - 4B711ABD1BF900D20017C8DA /* MPMoviePlayerController-Subtitles.swift */, + 4B607D551BFCE0C2001090B5 /* MPMoviePlayerController-Subtitles.swift */, ); name = "MPMoviePlayerController-Subtitles"; sourceTree = ""; @@ -162,7 +162,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4B711ABE1BF900D20017C8DA /* MPMoviePlayerController-Subtitles.swift in Sources */, + 4B607D561BFCE0C2001090B5 /* MPMoviePlayerController-Subtitles.swift in Sources */, 4B4966451BF8F87E00CD6060 /* ViewController.swift in Sources */, 4B4966431BF8F87E00CD6060 /* AppDelegate.swift in Sources */, ); diff --git a/Example/MPMoviePlayerController-Subtitles.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example/MPMoviePlayerController-Subtitles.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/Example/MPMoviePlayerController-Subtitles.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Example/MPMoviePlayerController-Subtitles.xcodeproj/project.xcworkspace/xcuserdata/mhergon.xcuserdatad/UserInterfaceState.xcuserstate b/Example/MPMoviePlayerController-Subtitles.xcodeproj/project.xcworkspace/xcuserdata/mhergon.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..9d0f87099806af17f279ee8c7e77b5deb7c39bc2 GIT binary patch literal 11210 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 N=`+G-_;1q9{|lEg3^4!z literal 0 HcmV?d00001 diff --git a/Example/MPMoviePlayerController-Subtitles.xcodeproj/xcuserdata/mhergon.xcuserdatad/xcschemes/MPMoviePlayerController-Subtitles.xcscheme b/Example/MPMoviePlayerController-Subtitles.xcodeproj/xcuserdata/mhergon.xcuserdatad/xcschemes/MPMoviePlayerController-Subtitles.xcscheme new file mode 100644 index 0000000..9850543 --- /dev/null +++ b/Example/MPMoviePlayerController-Subtitles.xcodeproj/xcuserdata/mhergon.xcuserdatad/xcschemes/MPMoviePlayerController-Subtitles.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/MPMoviePlayerController-Subtitles.xcodeproj/xcuserdata/mhergon.xcuserdatad/xcschemes/xcschememanagement.plist b/Example/MPMoviePlayerController-Subtitles.xcodeproj/xcuserdata/mhergon.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..5fa71e3 --- /dev/null +++ b/Example/MPMoviePlayerController-Subtitles.xcodeproj/xcuserdata/mhergon.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,22 @@ + + + + + SchemeUserState + + MPMoviePlayerController-Subtitles.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 4B49663E1BF8F87E00CD6060 + + primary + + + + + diff --git a/Example/MPMoviePlayerController-Subtitles/MPMoviePlayerController-Subtitles.swift b/Example/MPMoviePlayerController-Subtitles/MPMoviePlayerController-Subtitles.swift deleted file mode 100644 index 810283d..0000000 --- a/Example/MPMoviePlayerController-Subtitles/MPMoviePlayerController-Subtitles.swift +++ /dev/null @@ -1,296 +0,0 @@ -// -// MPMoviePlayerController-Subtitles.swift -// MPMoviePlayerController-Subtitles -// -// Created by mhergon on 15/11/15. -// Copyright © 2015 mhergon. All rights reserved. -// - -import ObjectiveC -import MediaPlayer - -private struct AssociatedKeys { - static var FontKey = "FontKey" - static var ColorKey = "FontKey" - static var ContainerKey = "ContainerKey" - static var SubtitleKey = "SubtitleKey" - static var SubtitleHeightKey = "SubtitleHeightKey" - static var PayloadKey = "PayloadKey" - static var TimerKey = "TimerKey" -} - -extension MPMoviePlayerController { - - //MARK:- Public properties - var subtitleLabel: UILabel? { - get { return objc_getAssociatedObject(self, &AssociatedKeys.SubtitleKey) as? UILabel } - set (value) { objc_setAssociatedObject(self, &AssociatedKeys.SubtitleKey, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } - } - - //MARK:- Private properties - private var subtitleContainer: UIView? { - get { return objc_getAssociatedObject(self, &AssociatedKeys.ContainerKey) as? UIView } - set (value) { objc_setAssociatedObject(self, &AssociatedKeys.ContainerKey, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } - } - private var subtitleLabelHeightConstraint: NSLayoutConstraint? { - get { return objc_getAssociatedObject(self, &AssociatedKeys.SubtitleHeightKey) as? NSLayoutConstraint } - set (value) { objc_setAssociatedObject(self, &AssociatedKeys.SubtitleHeightKey, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } - } - private var parsedPayload: NSDictionary? { - get { return objc_getAssociatedObject(self, &AssociatedKeys.PayloadKey) as? NSDictionary } - set (value) { objc_setAssociatedObject(self, &AssociatedKeys.PayloadKey, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } - } - private var timer: NSTimer? { - get { return objc_getAssociatedObject(self, &AssociatedKeys.TimerKey) as? NSTimer } - set (value) { objc_setAssociatedObject(self, &AssociatedKeys.TimerKey, value, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } - } - - //MARK:- Public methods - func addSubtitles() -> Self { - - // Get subtitle view - getContainer() - - // Create label - addSubtitleLabel() - - // Notifications - registerNotifications() - - return self - - } - - func open(file filePath: NSURL, encoding: NSStringEncoding = NSUTF8StringEncoding) { - - let contents = try! String(contentsOfURL: filePath, encoding: encoding) - show(subtitles: contents) - - } - - func show(subtitles string: String) { - - // Parse - parsedPayload = parseSubRip(string) - - // Timer - timer = NSTimer.schedule(repeatInterval: 0.5) { (timer) -> Void in self.searchSubtitles() } - - } - - //MARK:- Private methods - private func getContainer() { - - for a in view.subviews { - for b in a.subviews { - for c in b.subviews { - if c.tag == 1006 { - subtitleContainer = c - } - } - } - } - - } - - private func addSubtitleLabel() { - - guard let _ = subtitleLabel else { - - // Label - subtitleLabel = UILabel() - subtitleLabel?.translatesAutoresizingMaskIntoConstraints = false - subtitleLabel?.backgroundColor = UIColor.clearColor() - subtitleLabel?.textAlignment = .Center - subtitleLabel?.numberOfLines = 0 - subtitleLabel?.font = UIFont.boldSystemFontOfSize(UI_USER_INTERFACE_IDIOM() == .Pad ? 40.0 : 22.0) - subtitleLabel?.textColor = UIColor.whiteColor() - subtitleLabel?.numberOfLines = 0; - subtitleLabel?.layer.shadowColor = UIColor.blackColor().CGColor - subtitleLabel?.layer.shadowOffset = CGSizeMake(1.0, 1.0); - subtitleLabel?.layer.shadowOpacity = 0.9; - subtitleLabel?.layer.shadowRadius = 1.0; - subtitleLabel?.layer.shouldRasterize = true; - subtitleLabel?.layer.rasterizationScale = UIScreen.mainScreen().scale - subtitleContainer?.addSubview(subtitleLabel!) - - // Position - var constraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-(20)-[l]-(20)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["l" : subtitleLabel!]) - subtitleContainer?.addConstraints(constraints) - constraints = NSLayoutConstraint.constraintsWithVisualFormat("V:[l]-(30)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["l" : subtitleLabel!]) - subtitleContainer?.addConstraints(constraints) - subtitleLabelHeightConstraint = NSLayoutConstraint(item: subtitleLabel!, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 30.0) - subtitleContainer?.addConstraint(subtitleLabelHeightConstraint!) - - return - - } - - } - - private func registerNotifications() { - - // Finished - NSNotificationCenter.defaultCenter().addObserverForName( - MPMoviePlayerPlaybackDidFinishNotification, - object: self, - queue: NSOperationQueue.mainQueue()) { (notification) -> Void in - - self.subtitleLabel?.hidden = true - self.timer?.invalidate() - - } - - // Change - NSNotificationCenter.defaultCenter().addObserverForName( - MPMoviePlayerPlaybackStateDidChangeNotification, - object: self, - queue: NSOperationQueue.mainQueue()) { (notification) -> Void in - - switch self.playbackState { - - case .Playing: - - // Start timer - self.timer = NSTimer.schedule(repeatInterval: 0.5) { (timer) -> Void in self.searchSubtitles() } - - break - - default: - - // Stop timer - self.timer?.invalidate() - - break - - } - - } - - } - - private func parseSubRip(var payload: String) -> NSDictionary? { - - do { - - // Prepare payload - payload = payload.stringByReplacingOccurrencesOfString("\n\r\n", withString: "\n\n") - payload = payload.stringByReplacingOccurrencesOfString("\n\n\n", withString: "\n\n") - - // Parsed dict - let parsed = NSMutableDictionary() - - // Get groups - let regexStr = "(?m)(^[0-9]+)([\\s\\S]*?)(?=\n\n)" - let regex = try NSRegularExpression(pattern: regexStr, options: .CaseInsensitive) - let matches = regex.matchesInString(payload, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, payload.characters.count)) - for m in matches { - - let group = (payload as NSString).substringWithRange(m.range) - - // Get index - var regex = try NSRegularExpression(pattern: "^[0-9]+", options: .CaseInsensitive) - var match = regex.matchesInString(group, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, group.characters.count)) - guard let i = match.first else { - continue - } - let index = (group as NSString).substringWithRange(i.range) - - // Get "from" & "to" time - regex = try NSRegularExpression(pattern: "\\d{1,2}:\\d{1,2}:\\d{1,2},\\d{1,3}", options: .CaseInsensitive) - match = regex.matchesInString(group, options: NSMatchingOptions(rawValue: 0), range: NSMakeRange(0, group.characters.count)) - guard match.count == 2 else { - continue - } - guard let from = match.first, let to = match.last else { - continue - } - - var h: NSTimeInterval = 0.0, m: NSTimeInterval = 0.0, s: NSTimeInterval = 0.0, c: NSTimeInterval = 0.0 - - let fromStr = (group as NSString).substringWithRange(from.range) - var scanner = NSScanner(string: fromStr) - scanner.scanDouble(&h) - scanner.scanString(":", intoString: nil) - scanner.scanDouble(&m) - scanner.scanString(":", intoString: nil) - scanner.scanDouble(&s) - scanner.scanString(",", intoString: nil) - scanner.scanDouble(&c) - let fromTime = (h * 3600.0) + (m * 60.0) + s + (c / 1000.0) - - let toStr = (group as NSString).substringWithRange(to.range) - scanner = NSScanner(string: toStr) - scanner.scanDouble(&h) - scanner.scanString(":", intoString: nil) - scanner.scanDouble(&m) - scanner.scanString(":", intoString: nil) - scanner.scanDouble(&s) - scanner.scanString(",", intoString: nil) - scanner.scanDouble(&c) - let toTime = (h * 3600.0) + (m * 60.0) + s + (c / 1000.0) - - // Get text - let text = (group as NSString).stringByReplacingCharactersInRange(NSMakeRange(0, to.range.location + to.range.length + 1), withString: "") - - // Create final object - let final = NSMutableDictionary() - final["from"] = fromTime - final["to"] = toTime - final["text"] = text - parsed[index] = final - - } - - return parsed - - } catch { - - return nil - - } - - } - - private func searchSubtitles() { - - if playbackState == .Playing { - - let predicate = NSPredicate(format: "(%f >= %K) AND (%f <= %K)", currentPlaybackTime, "from", currentPlaybackTime, "to") - - guard let values = parsedPayload?.allValues else { - return - } - guard let result = (values as NSArray).filteredArrayUsingPredicate(predicate).first as? NSDictionary else { - subtitleLabel?.text = "" - return - } - guard let label = subtitleLabel else { - return - } - - // Set text - label.text = (result["text"] as! String).stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()) - - // Adjust size - let rect = (label.text! as NSString).boundingRectWithSize(CGSize(width: CGRectGetWidth(label.bounds), height: CGFloat.max), options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName : label.font!], context: nil) - subtitleLabelHeightConstraint?.constant = rect.size.height + 5.0 - subtitleContainer?.layoutIfNeeded() - - } - - } - -} - -// Others -extension NSTimer { - - class func schedule(repeatInterval interval: NSTimeInterval, handler: NSTimer! -> Void) -> NSTimer { - let fireDate = interval + CFAbsoluteTimeGetCurrent() - let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, fireDate, interval, 0, 0, handler) - CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes) - return timer - } - -} \ No newline at end of file diff --git a/MPMoviePlayerController-Subtitles.podspec b/MPMoviePlayerController-Subtitles.podspec index b411fa0..2f10a63 100644 --- a/MPMoviePlayerController-Subtitles.podspec +++ b/MPMoviePlayerController-Subtitles.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |spec| spec.name = 'MPMoviePlayerController-Subtitles' spec.platform = :ios, "8.0" - spec.version = '2.0' + spec.version = '2.0.1' spec.license = { :type => 'MIT' } spec.homepage = 'https://github.com/mhergon/MPMoviePlayerController-Subtitles' spec.authors = { 'Marc Hervera' => 'mhergon@gmail.com' } spec.summary = 'Subtitles made easy' - spec.source = { :git => 'https://github.com/mhergon/MPMoviePlayerController-Subtitles.git', :tag => 'v2.0' } + spec.source = { :git => 'https://github.com/mhergon/MPMoviePlayerController-Subtitles.git', :tag => 'v2.0.1' } spec.source_files = 'MPMoviePlayerController-Subtitles.swift' spec.requires_arc = true spec.module_name = 'MPMoviePlayerControllerSubtitles' diff --git a/MPMoviePlayerController-Subtitles.swift b/MPMoviePlayerController-Subtitles.swift index 810283d..79de2aa 100644 --- a/MPMoviePlayerController-Subtitles.swift +++ b/MPMoviePlayerController-Subtitles.swift @@ -19,7 +19,7 @@ private struct AssociatedKeys { static var TimerKey = "TimerKey" } -extension MPMoviePlayerController { +public extension MPMoviePlayerController { //MARK:- Public properties var subtitleLabel: UILabel? { @@ -284,7 +284,7 @@ extension MPMoviePlayerController { } // Others -extension NSTimer { +public extension NSTimer { class func schedule(repeatInterval interval: NSTimeInterval, handler: NSTimer! -> Void) -> NSTimer { let fireDate = interval + CFAbsoluteTimeGetCurrent()