iOS视频字幕SRT解析工具 JKCaptionsHelper

  最近做视频类App,需要给视频添加字幕,做到同步播放,我这边针对这个需求用swift将SRT解析封装成了一个类库:JKCaptionsHelper,对OC和Swift都支持,注:对OC提供部分支持,但可以满足使用。
下载地址:https://github.com/xindizhiyin2014/JKCaptionsHelper

集成命令:

pod 'JKCaptionsHelper'

源码如下:

//
//  JKSRTHelper.swift
//  JKCaptionsHelper
//
//  Created by JackLee on 2019/4/29.
//
import Foundation

public enum JKSubTitleType {
    case oneLanguage          // 单语言字幕模式
    case twoLanguage          // 双语言字幕模式
}

@objcMembers public class JKSRTHelper :NSObject {
    
    private var beginTimes:[Float]?         // 字幕开始时间
    private var endTimes:[Float]?           // 字幕结束时间
    private var firstSubTitles:[String]?    // 第一语言字幕
    private var secondSubTitles:[String]?   // 第二语言字幕
    private var progressIndex = 0           // 字幕播放进度索引
    
    
    public class func initWithFilePath(filePath:String!,subTitleType:JKSubTitleType!) -> JKSRTHelper{
        let data = NSData.init(contentsOfFile: filePath as String)
       return self.initWithData(data: data,subTitleType: subTitleType)
    }
    
    public class func initWithString(content:String!,subTitleType:JKSubTitleType!) ->JKSRTHelper{
        let data = content.data(using: .utf8, allowLossyConversion: true)
        return self.initWithData(data: data as NSData?,subTitleType: subTitleType)
    }
    
    public class func initWithData(data:NSData?,subTitleType:JKSubTitleType!) -> JKSRTHelper{
        let content = String(data: data! as Data, encoding: .utf8)
        let array = content?.components(separatedBy: "\n")
        var beginTimes = [Float]()
        var endTimes = [Float]()
        var firstSubTitles = [String]()
        var secondSubTitles:[String]?

        var unitLineCount = 4    //单位行数
        if subTitleType == .twoLanguage{
            unitLineCount = 5
            secondSubTitles = [String]()
        }
    
        for i in 0 ..< array!.count {
            
            if i%unitLineCount == 0 {   //不做处理
              
            }
            else if i%unitLineCount == 1 { //时间处理
                let timeStr = array![i]
                let range:Range = timeStr.range(of: " --> ")!
                if range.isEmpty == false {
                    let beginStr = String(timeStr[..<range.lowerBound])
                    let endStr = String(timeStr[range.upperBound...])
                    let arr1 = beginStr.components(separatedBy:":")
                    let arr2 = arr1[2].components(separatedBy:",")
                    //将开始时间数组中的时间转换为秒为单位的
                    let beginHour:Float = Float(arr1[0])! * Float(60) * Float(60)
                    let beginMinute:Float = Float(arr1[1])! * Float(60)
                    let beginSecond:Float = Float(arr2[0])! + Float(arr2[1])!/Float(1000)
                    let beginTime = beginHour + beginMinute + beginSecond
                    beginTimes.append(beginTime)

                    let arr3 = endStr.components(separatedBy: ":")
                    let arr4 = arr3[2].components(separatedBy: ",")
                    //将结束时间数组中的时间转换为秒为单位的
                    let endHour:Float = Float(arr3[0])! * Float(60) * Float(60)
                    let endMinute:Float = Float(arr3[1])! * Float(60)
                    let endSecond:Float = Float(arr4[0])! + Float(arr4[1])!/Float(1000)
                    let endTime = endHour + endMinute + endSecond
                    endTimes.append(endTime)
                    
                }
                
            }
            else{
                
                if i%unitLineCount == 2 {  //第一语言字幕
                    firstSubTitles.append(array![i])
                }
                else if i%unitLineCount == 3{ //第二语言字幕
                   secondSubTitles!.append(array![i])
                }
                
            }
            
        }
        let srtHelper:JKSRTHelper = JKSRTHelper.init()
        srtHelper.beginTimes = beginTimes
        srtHelper.endTimes = endTimes
        srtHelper.firstSubTitles = firstSubTitles
        srtHelper.secondSubTitles = secondSubTitles
        return srtHelper
    
    }
    
    public class func initWithArray(array:[NSDictionary]) -> JKSRTHelper{
        var beginTimes = [Float]()
        var endTimes = [Float]()
        var firstSubTitles = [String]()
        
        for dic:NSDictionary in array {
            let timeStr:String = dic["duration"] as! String
            let lines:String = dic["lines"] as! String
            firstSubTitles.append(lines)
            
            let range:Range = timeStr.range(of: " --> ")!
            if range.isEmpty == false {
                let beginStr = String(timeStr[..<range.lowerBound])
                let endStr = String(timeStr[range.upperBound...])
                let arr1 = beginStr.components(separatedBy:":")
                let arr2 = arr1[2].components(separatedBy:",")
                //将开始时间数组中的时间转换为秒为单位的
                let beginHour:Float = Float(arr1[0])! * Float(60) * Float(60)
                let beginMinute:Float = Float(arr1[1])! * Float(60)
                let beginSecond:Float = Float(arr2[0])! + Float(arr2[1])!/Float(1000)
                let beginTime = beginHour + beginMinute + beginSecond
                beginTimes.append(beginTime)
                
                let arr3 = endStr.components(separatedBy: ":")
                let arr4 = arr3[2].components(separatedBy: ",")
                //将结束时间数组中的时间转换为秒为单位的
                let endHour:Float = Float(arr3[0])! * Float(60) * Float(60)
                let endMinute:Float = Float(arr3[1])! * Float(60)
                let endSecond:Float = Float(arr4[0])! + Float(arr4[1])!/Float(1000)
                let endTime = endHour + endMinute + endSecond
                endTimes.append(endTime)
                
            }
        }
        
        let srtHelper:JKSRTHelper = JKSRTHelper.init()
        srtHelper.beginTimes = beginTimes
        srtHelper.endTimes = endTimes
        srtHelper.firstSubTitles = firstSubTitles
        return srtHelper
    }
    
    public func playSRTWithTime(currentTime:CGFloat,content:((_ firstSubTitle:String?,_ secondSubTitle:String?)->Void)!) -> Void {
        let time:Float = Float(currentTime)
        for i in self.progressIndex ..< self.beginTimes!.count {
            let beiginTime = self.beginTimes![i]
            let endTime = self.endTimes![i]
            if time >= beiginTime && time <= endTime {
                if let content = content {
                    let firstSubTitle = self.firstSubTitles![i]
                    if self.secondSubTitles != nil {
                       let secondSubTitle = self.secondSubTitles![i]
                        content(firstSubTitle,secondSubTitle)
                    }else{
                     content(firstSubTitle,nil)
                    }
                   
                }
                self.progressIndex = i
                break
            }
            
        }
    }
    
    public func resetProgressIndex() -> Void{
        self.progressIndex = 0
    }
    
    
}

如果有什么bug,或者不够好的,欢迎大家多多指教。

更多优质文章,可以微信扫码关注:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/HHL110120/article/details/89735435