重构项目,调整了项目结构
This commit is contained in:
parent
5f49bde3ae
commit
c9b1b38c03
11 changed files with 456 additions and 386 deletions
173
srt.go
Normal file
173
srt.go
Normal file
|
@ -0,0 +1,173 @@
|
|||
package lrc2srt
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"github.com/Hami-Lemon/lrc2srt/glist"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type SRTMergeMode int
|
||||
|
||||
const (
|
||||
SRT_MERGE_MODE_STACK SRTMergeMode = iota
|
||||
SRT_MERGE_MODE_UP
|
||||
SRT_MERGE_MODE_BOTTOM
|
||||
)
|
||||
|
||||
type SRTContent struct {
|
||||
//序号,从1开始
|
||||
Index int
|
||||
//开始时间,单位毫秒
|
||||
Start int
|
||||
//结束时间,单位毫秒
|
||||
End int
|
||||
//歌词内容
|
||||
Text string
|
||||
}
|
||||
|
||||
/**
|
||||
1
|
||||
00:00:01,111 --> 00:00:10,111
|
||||
字幕
|
||||
|
||||
*/
|
||||
//返回SRT文件中,一句字幕的字符串表示形式
|
||||
func (s *SRTContent) String() string {
|
||||
builder := strings.Builder{}
|
||||
builder.WriteString(strconv.Itoa(s.Index))
|
||||
builder.WriteByte('\n')
|
||||
sh, sm, ss, sms := millisecond2Time(s.Start)
|
||||
eh, em, es, ems := millisecond2Time(s.End)
|
||||
builder.WriteString(fmt.Sprintf("%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n",
|
||||
sh, sm, ss, sms, eh, em, es, ems))
|
||||
builder.WriteString(s.Text)
|
||||
builder.WriteString("\n\n")
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
type SRT struct {
|
||||
//歌曲名
|
||||
Title string
|
||||
//歌手名 未指定文件名是,文件名格式为:歌曲名-歌手名.srt
|
||||
Artist string
|
||||
Content glist.Queue[*SRTContent]
|
||||
}
|
||||
|
||||
// LrcToSrt LRC对象转换成SRT对象
|
||||
func LrcToSrt(lrc *LRC) *SRT {
|
||||
if lrc == nil {
|
||||
return nil
|
||||
}
|
||||
srt := &SRT{
|
||||
Title: lrc.Title,
|
||||
Artist: lrc.Artist,
|
||||
Content: glist.NewLinkedList[*SRTContent](),
|
||||
}
|
||||
index := 1
|
||||
//上一条srt信息
|
||||
var prevSRT *SRTContent
|
||||
for it := lrc.LrcList.Iterator(); it.Has(); {
|
||||
lrcNode := it.Next()
|
||||
srtContent := &SRTContent{
|
||||
Index: index,
|
||||
Start: lrcNode.time,
|
||||
Text: lrcNode.content,
|
||||
}
|
||||
if index != 1 {
|
||||
//上一条歌词的结束时间设置为当前歌词的开始时间
|
||||
prevSRT.End = srtContent.Start
|
||||
}
|
||||
srt.Content.PushBack(srtContent)
|
||||
index++
|
||||
prevSRT = srtContent
|
||||
}
|
||||
//最后一条歌词
|
||||
if prevSRT != nil {
|
||||
//结束时间是为其 开始时间+10 秒
|
||||
prevSRT.End = prevSRT.Start + 1000
|
||||
}
|
||||
return srt
|
||||
}
|
||||
|
||||
// Merge 将另一个srt信息合并到当前srt中,有三种合并模式
|
||||
//1. SRT_MERGE_MODE_STACK: 按照开始时间对两个srt信息进行排序,交错合并
|
||||
//2. SRT_MERGE_MODE_UP: 当前srt信息排列在上,另一个排列在下,即 other 追加到后面
|
||||
//3. SRT_MERGE_MODE_BOTTOM: 当前srt信息排列在下,另一个排列在上,即 other 添加到前面
|
||||
func (s *SRT) Merge(other *SRT, mode SRTMergeMode) {
|
||||
switch mode {
|
||||
case SRT_MERGE_MODE_STACK:
|
||||
s.mergeStack(other)
|
||||
case SRT_MERGE_MODE_UP:
|
||||
s.mergeUp(other)
|
||||
case SRT_MERGE_MODE_BOTTOM:
|
||||
s.mergeBottom(other)
|
||||
}
|
||||
}
|
||||
|
||||
//todo 改进算法,现在的算法太慢了
|
||||
func (s *SRT) mergeStack(other *SRT) {
|
||||
size := s.Content.Size() + other.Content.Size()
|
||||
temp := make([]*SRTContent, size, size)
|
||||
index := 0
|
||||
for it := s.Content.Iterator(); it.Has(); {
|
||||
temp[index] = it.Next()
|
||||
index++
|
||||
}
|
||||
for it := other.Content.Iterator(); it.Has(); {
|
||||
temp[index] = it.Next()
|
||||
index++
|
||||
}
|
||||
sort.SliceStable(temp, func(i, j int) bool {
|
||||
return temp[i].Start < temp[j].Start
|
||||
})
|
||||
list := glist.NewLinkedList[*SRTContent]()
|
||||
for _, v := range temp {
|
||||
list.Append(v)
|
||||
}
|
||||
s.Content = list
|
||||
}
|
||||
|
||||
func (s *SRT) mergeUp(other *SRT) {
|
||||
if other.Content.IsNotEmpty() {
|
||||
for it := other.Content.Iterator(); it.Has(); {
|
||||
s.Content.Append(it.Next())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SRT) mergeBottom(other *SRT) {
|
||||
oq := other.Content
|
||||
if oq.IsNotEmpty() {
|
||||
s.Content.PushFront(*(oq.PullBack()))
|
||||
}
|
||||
}
|
||||
|
||||
// WriteFile 将SRT格式的数据写入指定的文件中
|
||||
func (s *SRT) WriteFile(path string) error {
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = s.Write(f)
|
||||
err = f.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
// Write 将SRT格式的数据写入dst中
|
||||
func (s *SRT) Write(dst io.Writer) error {
|
||||
//6KB的缓冲
|
||||
bufSize := 1024 * 6
|
||||
writer := bufio.NewWriterSize(dst, bufSize)
|
||||
for it := s.Content.Iterator(); it.Has(); {
|
||||
_, err := writer.WriteString(it.Next().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return writer.Flush()
|
||||
}
|
Reference in a new issue