123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- import AVKit
- class NCSubtitles {
-
- private var parsedPayload: NSDictionary?
-
- public init(file filePath: URL, encoding: String.Encoding = .utf8) throws {
-
- let string = try String(contentsOf: filePath, encoding: encoding)
-
- parsedPayload = try NCSubtitles.parseSubRip(string)
- }
- public init(subtitles string: String) throws {
-
- parsedPayload = try NCSubtitles.parseSubRip(string)
- }
-
-
-
-
- public func searchSubtitles(at time: TimeInterval) -> String? {
- return NCSubtitles.searchSubtitles(parsedPayload, time)
- }
-
-
-
-
-
- static func parseSubRip(_ payload: String) throws -> NSDictionary? {
-
- var payload = payload.replacingOccurrences(of: "\n\r\n", with: "\n\n")
- payload = payload.replacingOccurrences(of: "\n\n\n", with: "\n\n")
- payload = payload.replacingOccurrences(of: "\r\n", with: "\n")
-
- let parsed = NSMutableDictionary()
-
- let regexStr = "(\\d+)\\n([\\d:,.]+)\\s+-{2}\\>\\s+([\\d:,.]+)\\n([\\s\\S]*?(?=\\n{2,}|$))"
- let regex = try NSRegularExpression(pattern: regexStr, options: .caseInsensitive)
- let matches = regex.matches(in: payload, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSRange(location: 0, length: payload.count))
- for m in matches {
- let group = (payload as NSString).substring(with: m.range)
-
- var regex = try NSRegularExpression(pattern: "^[0-9]+", options: .caseInsensitive)
- var match = regex.matches(in: group, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSRange(location: 0, length: group.count))
- guard let i = match.first else {
- continue
- }
- let index = (group as NSString).substring(with: i.range)
-
- regex = try NSRegularExpression(pattern: "\\d{1,2}:\\d{1,2}:\\d{1,2}[,.]\\d{1,3}", options: .caseInsensitive)
- match = regex.matches(in: group, options: NSRegularExpression.MatchingOptions(rawValue: 0), range: NSRange(location: 0, length: group.count))
- guard match.count == 2 else {
- continue
- }
- guard let from = match.first, let to = match.last else {
- continue
- }
- var h: TimeInterval = 0.0, m: TimeInterval = 0.0, s: TimeInterval = 0.0, c: TimeInterval = 0.0
- let fromStr = (group as NSString).substring(with: from.range)
- var scanner = Scanner(string: fromStr)
- scanner.scanDouble(&h)
- scanner.scanString(":", into: nil)
- scanner.scanDouble(&m)
- scanner.scanString(":", into: nil)
- scanner.scanDouble(&s)
- scanner.scanString(",", into: nil)
- scanner.scanDouble(&c)
- let fromTime = (h * 3600.0) + (m * 60.0) + s + (c / 1000.0)
- let toStr = (group as NSString).substring(with: to.range)
- scanner = Scanner(string: toStr)
- scanner.scanDouble(&h)
- scanner.scanString(":", into: nil)
- scanner.scanDouble(&m)
- scanner.scanString(":", into: nil)
- scanner.scanDouble(&s)
- scanner.scanString(",", into: nil)
- scanner.scanDouble(&c)
- let toTime = (h * 3600.0) + (m * 60.0) + s + (c / 1000.0)
-
- let range = NSRange(location: 0, length: to.range.location + to.range.length + 1)
- guard (group as NSString).length - range.length > 0 else {
- continue
- }
- let text = (group as NSString).replacingCharacters(in: range, with: "")
-
- let final = NSMutableDictionary()
- final["from"] = fromTime
- final["to"] = toTime
- final["text"] = text
- parsed[index] = final
- }
- return parsed
- }
-
-
-
-
-
-
- static func searchSubtitles(_ payload: NSDictionary?, _ time: TimeInterval) -> String? {
- let predicate = NSPredicate(format: "(%f >= %K) AND (%f <= %K)", time, "from", time, "to")
- guard let values = payload?.allValues, let result = (values as NSArray).filtered(using: predicate).first as? NSDictionary else {
- return nil
- }
- guard let text = result.value(forKey: "text") as? String else {
- return nil
- }
- return text.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
- }
- }
|