Skip to content

Instantly share code, notes, and snippets.

@kumo
Last active May 5, 2020 05:50
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kumo/adbede0c0c092683b5c2 to your computer and use it in GitHub Desktop.
Save kumo/adbede0c0c092683b5c2 to your computer and use it in GitHub Desktop.
// Playground - noun: a place where people can play
import UIKit
enum SubtitleType {
case SubRip, SubStationAlpha, LRC, SAMI, YouTube, SubViewer, MicroDVD, WebVTT, TTML, Unknown
func description() -> String {
switch self {
case .SubRip:
return "SubRip subtitle (.srt)"
case .SubStationAlpha:
return "Advanced Sub Station subtitle (.ass/.ssa)"
case .LRC:
return "LRC lyrics (.lrc)"
case .SAMI:
return "SAMI subtitle (.smi)"
case .YouTube:
return "YouTube Captions/SubViewer subtitle (.sbv/.sub)"
case .SubViewer:
return "SubViewer subtitle (.sub)"
case .MicroDVD:
return "MicroDVD subtitle (.sub)"
case .WebVTT:
return "WebVTT subtitle (.vtt)"
case .TTML:
return "TTML subtitle (.xml)"
case .Unknown:
return "text / unknown"
}
}
}
func identifyText(text: String) -> SubtitleType? {
let scanner = NSScanner(string: text)
// check if the subtitle starts with the specified text
if scanner.scanString("<sami>", intoString: nil) {
return .SAMI
}
// check if the subtitle starts with the specified text
if scanner.scanString("WEBVTT", intoString: nil) {
return .WebVTT
}
// check if the subtitle contains at some point the specified text
if scanner.scanUpToString("[Events]", intoString: nil) {
// if the scanner is not at the end then we found the text
if !scanner.atEnd {
return .SubStationAlpha
}
// reset the scanner
scanner.scanLocation = 0
}
// check if the subtitle contains at some point the specified text
if scanner.scanUpToString("[SUBTITLE]", intoString: nil) {
// if the scanner is not at the end then we found the text
if !scanner.atEnd {
return .SubViewer
}
// reset the scanner
scanner.scanLocation = 0
}
if scanner.scanInt(nil) {
var timeLine:NSString?
if scanner.scanCharactersFromSet(NSCharacterSet(charactersInString: "0123456789:.,-> "), intoString: &timeLine) {
if let timeLine = timeLine {
if timeLine.componentsSeparatedByString(" --> ").count == 2 {
return .SubRip
} else if timeLine.componentsSeparatedByString(",").count == 2 {
return .YouTube
}
}
}
// reset the scanner
scanner.scanLocation = 0
}
// check if the subtitle starts with square brackets
if scanner.scanString("[", intoString: nil) {
// check if the subtitle contains text inside square brackets
if scanner.scanUpToString("]", intoString: nil) {
// if the scanner is not at the end then we found the text
if !scanner.atEnd {
return .LRC
}
}
// reset the scanner
scanner.scanLocation = 0
}
// check if the subtitle contains at some point the specified text
if scanner.scanUpToString("[0", intoString: nil) {
// check if the subtitle contains text inside square brackets
if scanner.scanUpToString("]", intoString: nil) {
// if the scanner is not at the end then we found the text
if !scanner.atEnd {
return .LRC
}
}
// reset the scanner
scanner.scanLocation = 0
}
// NOTE: this seems to work, but surely it could be tricked by a badly formed .SubRip or .YouTube ?
// if scanner.scanCharactersFromSet(NSCharacterSet(charactersInString: "0123456789{}"), intoString: nil) {
// return .MicroDVD
// }
// check if the subtitle starts with curly braces
if scanner.scanString("{", intoString: nil) {
// check if the subtitle contains text inside curly braces
if scanner.scanUpToString("}", intoString: nil) {
// if the scanner is not at the end then we found the text
if !scanner.atEnd {
return .MicroDVD
}
// reset the scanner
scanner.scanLocation = 0
}
}
// check if the subtitle contains at some point the specified text
if scanner.scanUpToString("<tt xmlns=\"http://www.w3.org/ns/ttml\">", intoString: nil) {
// if the scanner is not at the end then we found the text
if !scanner.atEnd {
return .TTML
}
}
return .Unknown
}
if let type = identifyText("[al:title]\n[00:12]some words") {
type.description()
}
if let type = identifyText("Hello there!\n[00:00]some words") {
type.description()
}
if let type = identifyText("<SAMI><HEAD>") {
type.description()
}
if let type = identifyText("[Script Info]\n; This is a Sub Station Alpha v4 script.\n\n[Events]") {
type.description()
}
if let type = identifyText("1\n00:00:12,000 --> 00:00:15,123\nSome text") {
type.description()
}
if let type = identifyText("0:00:00.599,0:00:04.160\n>> ALICE: Hi, my name is Alice Miller and this is John Brown\n\n0:00:04.160,0:00:06.770\n>> JOHN: and we're the owners of Miller Bakery.") {
type.description()
}
if let type = identifyText("{0}{15}Hello!") {
type.description()
}
if let type = identifyText("[INFORMATION]\n[TITLE]\n[AUTHOR]andycat\n[SOURCE]\n[FILEPATH]\n[DELAY]0\n[COMMENT]Edited with Jubler subtitle editor\n[END INFORMATION]\n[SUBTITLE]\n[COLF]&HFFFFFF,[STYLE]bd,[SIZE]18,[FONT]Arial\n00:00:00.00,00:00:10.00\nThis is my first subtitle!") {
type.description()
}
if let type = identifyText("WEBVTT\n\n1\n00:00:01.000 --> 00:00:10.000\nThis is the first line of text, displaying from 1-10 seconds\n\n2\n00:00:15.000 --> 00:00:20.000\nAnd the second line of text\nseparated over two lines") {
type.description()
}
if let type = identifyText("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<tt xmlns=\"http://www.w3.org/ns/ttml\">\n<head>\n<metadata xmlns:ttm=\"http://www.w3.org/ns/ttml#metadata\">\n<ttm:title>Timed Text TTML Example</ttm:title>\n<ttm:copyright>The Authors (c) 2006</ttm:copyright>\n</metadata>") {
type.description()
}
if let type = identifyText("asdfa sddfs f jsdkf asljdfl") {
type.description()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment