forked from BrikerMan/BMPlayer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BMSubtitles.swift
120 lines (101 loc) · 3.9 KB
/
BMSubtitles.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//
// BMSubtitles.swift
// Pods
//
// Created by BrikerMan on 2017/4/2.
//
//
import Foundation
public class BMSubtitles {
public var groups: [Group] = []
public struct Group: CustomStringConvertible {
var index: Int
var start: TimeInterval
var end : TimeInterval
var text : String
init(_ index: Int, _ start: NSString, _ end: NSString, _ text: NSString) {
self.index = index
self.start = Group.parseDuration(start as String)
self.end = Group.parseDuration(end as String)
self.text = text as String
}
static func parseDuration(_ fromStr:String) -> TimeInterval {
var h: TimeInterval = 0.0, m: TimeInterval = 0.0, s: TimeInterval = 0.0, c: TimeInterval = 0.0
let 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)
return (h * 3600.0) + (m * 60.0) + s + (c / 1000.0)
}
public var description: String {
return "Subtile Group ==========\nindex : \(index),\nstart : \(start)\nend :\(end)\ntext :\(text)"
}
}
public init(url: URL, encoding: String.Encoding? = nil) {
DispatchQueue.global(qos: .background).async {[weak self] in
do {
let string: String
if let encoding = encoding {
string = try String(contentsOf: url, encoding: encoding)
} else {
string = try String(contentsOf: url)
}
self?.groups = BMSubtitles.parseSubRip(string) ?? []
} catch {
print("| BMPlayer | [Error] failed to load \(url.absoluteString) \(error.localizedDescription)")
}
}
}
/**
Search for target group for time
- parameter time: target time
- returns: result group or nil
*/
public func search(for time: TimeInterval) -> Group? {
let result = groups.first(where: { group -> Bool in
if group.start <= time && group.end >= time {
return true
}
return false
})
return result
}
/**
Parse str string into Group Array
- parameter payload: target string
- returns: result group
*/
fileprivate static func parseSubRip(_ payload: String) -> [Group]? {
var groups: [Group] = []
let scanner = Scanner(string: payload)
while !scanner.isAtEnd {
var indexString: NSString?
scanner.scanUpToCharacters(from: .newlines, into: &indexString)
var startString: NSString?
scanner.scanUpTo(" --> ", into: &startString)
// skip spaces and newlines by default.
scanner.scanString("-->", into: nil)
var endString: NSString?
scanner.scanUpToCharacters(from: .newlines, into: &endString)
var textString: NSString?
scanner.scanUpTo("\r\n\r\n", into: &textString)
if let text = textString {
textString = text.trimmingCharacters(in: .whitespaces) as NSString
textString = text.replacingOccurrences(of: "\r", with: "") as NSString
}
if let indexString = indexString,
let index = Int(indexString as String),
let start = startString,
let end = endString,
let text = textString {
let group = Group(index, start, end, text)
groups.append(group)
}
}
return groups
}
}