Skip to content

Commit

Permalink
正在改进 GetOffsetTimeV2
Browse files Browse the repository at this point in the history
Signed-off-by: allan716 <525223688@qq.com>
  • Loading branch information
allanpk716 committed Nov 10, 2021
1 parent f7eb68c commit 5b96918
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 51 deletions.
5 changes: 3 additions & 2 deletions internal/common/constvalue.go
Expand Up @@ -32,8 +32,9 @@ const (
)

const (
TimeFormatAss = "15:04:05.00"
TimeFormatSrt = "15:04:05,000"
TimeFormatPoint2 = "15:04:05.00"
TimeFormatPoint3 = "15:04:05,000"
TimeFormatPoint4 = "15:04:05,0000"
)

const Ignore = ".ignore"
13 changes: 7 additions & 6 deletions internal/pkg/sub_helper/sub_helper.go
Expand Up @@ -17,7 +17,6 @@ import (
"regexp"
"strconv"
"strings"
"time"
)

// OrganizeDlSubFiles 需要从汇总来是网站字幕中,解压对应的压缩包中的字幕出来
Expand Down Expand Up @@ -373,29 +372,30 @@ func MergeMultiDialogue4EngSubtitle(inSubParser *subparser.FileInfo) {
这里的字幕要求是完整的一个字幕
1. 抽取字幕的时间片段的时候,暂定,前 15% 和后 15% 要避开,前奏、主题曲、结尾曲
2. 将整个字幕,抽取连续 5 句对话为一个单元,提取时间片段信息
3. 可能还有一个需求,默认的模式是每五句话一个单元,还有一种模式是每一句话向后找到连续的四句话组成一个单元,允许重叠
目前看到的情况是前者的抽样率太低,需要使用后者的逻辑
*/
func GetVADINfoFromSub(infoSrc *subparser.FileInfo, FrontAndEndPer float64, SubUnitMaxCount int) ([]SubUnit, error) {
if SubUnitMaxCount < 0 {
SubUnitMaxCount = 0
}
srcSubUnitList := make([]SubUnit, 0)
srcOneSubUnit := NewSubUnit()
srcTimeFormat := infoSrc.GetTimeFormat()

// srcDuration
lastDialogueExTimeEnd, err := time.Parse(srcTimeFormat, infoSrc.DialoguesEx[len(infoSrc.DialoguesEx)-1].EndTime)
lastDialogueExTimeEnd, err := infoSrc.ParseTime(infoSrc.DialoguesEx[len(infoSrc.DialoguesEx)-1].EndTime)
if err != nil {
return nil, err
}
srcDuration := my_util.Time2SecendNumber(lastDialogueExTimeEnd)

for i := 0; i < len(infoSrc.DialoguesEx); i++ {

oneDialogueExTimeStart, err := time.Parse(srcTimeFormat, infoSrc.DialoguesEx[i].StartTime)
oneDialogueExTimeStart, err := infoSrc.ParseTime(infoSrc.DialoguesEx[i].StartTime)
if err != nil {
return nil, err
}
oneDialogueExTimeEnd, err := time.Parse(srcTimeFormat, infoSrc.DialoguesEx[i].EndTime)
oneDialogueExTimeEnd, err := infoSrc.ParseTime(infoSrc.DialoguesEx[i].EndTime)
if err != nil {
return nil, err
}
Expand All @@ -414,10 +414,11 @@ func GetVADINfoFromSub(infoSrc *subparser.FileInfo, FrontAndEndPer float64, SubU
}
// 低于 5句对白,则添加
if srcOneSubUnit.GetDialogueCount() < SubUnitMaxCount {
srcOneSubUnit.AddAndInsert(oneDialogueExTimeStart, oneDialogueExTimeEnd)
srcOneSubUnit.AddAndInsert(oneDialogueExTimeStart, oneDialogueExTimeEnd, i)
} else {
srcSubUnitList = append(srcSubUnitList, *srcOneSubUnit)
srcOneSubUnit = NewSubUnit()
i = i - SubUnitMaxCount + SubUnitMaxCount/5
}
}
if srcOneSubUnit.GetDialogueCount() > 0 {
Expand Down
88 changes: 82 additions & 6 deletions internal/pkg/sub_helper/sub_unit.go
Expand Up @@ -16,6 +16,7 @@ type SubUnit struct {
subCount int
firstAdd bool
outVADBytes []byte
outVADFloats []float64
}

func NewSubUnit() *SubUnit {
Expand All @@ -28,7 +29,7 @@ func NewSubUnit() *SubUnit {
}

// AddAndInsert 添加一句对白进来,并且填充中间的空白,间隔 10ms
func (s *SubUnit) AddAndInsert(oneSubStartTime, oneSubEndTime time.Time) {
func (s *SubUnit) AddAndInsert(oneSubStartTime, oneSubEndTime time.Time, index int) {

/*
这里有个比较有意思的细节,字幕拆分到 dialogue 的时候,可能连续的多个 dialogue 是时间轴连续的
Expand All @@ -38,7 +39,6 @@ func (s *SubUnit) AddAndInsert(oneSubStartTime, oneSubEndTime time.Time) {
1. 前后各 0.001 秒即可
2. 后面这一句向后 0.002 秒(暂时优先考虑这个,容易实现)
*/
const perWindows = float64(vad.FrameDuration) / 1000

// 不是第一次添加,那么就需要把两句对白中间间隔的 active == false 的插入,插入间隙
if len(s.VADList) > 0 {
Expand Down Expand Up @@ -93,8 +93,8 @@ func (s SubUnit) GetDialogueCount() int {
return s.subCount
}

// GetVADSlice 获取 VAD 的 byte 数组信息
func (s *SubUnit) GetVADSlice() []byte {
// GetVADByteSlice 获取 VAD 的 byte 数组信息
func (s *SubUnit) GetVADByteSlice() []byte {

if len(s.outVADBytes) != len(s.VADList) {
s.outVADBytes = make([]byte, len(s.VADList))
Expand All @@ -110,6 +110,23 @@ func (s *SubUnit) GetVADSlice() []byte {
return s.outVADBytes
}

// GetVADFloatSlice 获取 VAD 的 float64 数组信息
func (s *SubUnit) GetVADFloatSlice() []float64 {

if len(s.outVADFloats) != len(s.VADList) {
s.outVADFloats = make([]float64, len(s.VADList))
for i := 0; i < len(s.VADList); i++ {
if s.VADList[i].Active == true {
s.outVADFloats[i] = 1
} else {
s.outVADFloats[i] = 0
}
}
}

return s.outVADFloats
}

// GetStartTimeNumber 获取这个单元的起始时间,单位是秒
func (s SubUnit) GetStartTimeNumber(realOrOffsetTime bool) float64 {
return my_util.Time2SecendNumber(s.GetStartTime(realOrOffsetTime))
Expand Down Expand Up @@ -139,6 +156,31 @@ func (s SubUnit) GetEndTime(realOrOffsetTime bool) time.Time {
}
}

// GetIndexTime 当前 Index 的时间
func (s SubUnit) GetIndexTime(index int, realOrOffsetTime bool) (bool, time.Time) {

if index >= len(s.VADList) {
return false, time.Time{}
}

if realOrOffsetTime == true {
return true, time.Time{}.Add(s.VADList[index].Time).Add(my_util.Time2Duration(s.baseTime))
} else {
return true, time.Time{}.Add(s.VADList[index].Time)
}
}

// GetIndexTimeNumber 当前 Index 的时间
func (s SubUnit) GetIndexTimeNumber(index int, realOrOffsetTime bool) (bool, float64) {

bok, outTime := s.GetIndexTime(index, realOrOffsetTime)
if bok == false {
return false, 0
}

return true, my_util.Time2SecendNumber(outTime)
}

// GetTimelineRange 开始到结束的时间长度,单位是秒
func (s SubUnit) GetTimelineRange() float64 {
return s.GetEndTimeNumber(false) - s.GetStartTimeNumber(false)
Expand All @@ -149,8 +191,9 @@ func (s SubUnit) GetOffsetTimeNumber() float64 {
return my_util.Time2SecendNumber(s.baseTime)
}

// GetFFMPEGCutRange 这里会生成导出 FFMPEG 的参数字段,起始时间和结束的时间长度
func (s SubUnit) GetFFMPEGCutRange(expandTimeRange float64) (string, string) {
// GetFFMPEGCutRangeString 这里会生成导出 FFMPEG 的参数字段,起始时间和结束的时间长度
// 以当前的 VAD 信息为基准,正负 expandTimeRange(秒为单位) 来生成截取的片段时间轴信息
func (s SubUnit) GetFFMPEGCutRangeString(expandTimeRange float64) (string, string) {

var tmpStartTime time.Time
if s.GetStartTimeNumber(true)-expandTimeRange < 0 {
Expand All @@ -165,8 +208,41 @@ func (s SubUnit) GetFFMPEGCutRange(expandTimeRange float64) (string, string) {
fmt.Sprintf("%f", s.GetTimelineRange()+expandTimeRange)
}

// GetExpandRangeIndex 导出扩展的起始时间和结束的时间,整个多出的参数只适用于整体的字幕范围,局部不试用
// 以当前的 VAD 信息为基准,正负 expandTimeRange(秒为单位) 来生成截取的片段时间轴信息
// 向左偏移的时候是可知有多少可以移动的,越界就置为 0
// 向右移动的时候,总长度是未知的,所以返回的值需要在外部重新 Check 是否会越界
func (s SubUnit) GetExpandRangeIndex(expandTimeRange float64) (int, int) {

var tmpStartTimeIndex int
var tmpEndTimeIndex int
// 起始时间 -> Index
if s.GetStartTimeNumber(true)-expandTimeRange < 0 {
// 向左偏移的时候是可知有多少可以移动的,越界就置为 0
tmpStartTimeIndex = 0
} else {
// 没有越界就直接用得到的毫秒差值去推算 index 的偏移位置
startTime := s.GetStartTime(true)
subTime := time.Duration(expandTimeRange) * time.Second
tmpStartTime := startTime.Add(-subTime)
// 需要从秒换算到偏移的 Index 数值,一共多少份
tmpStartTimeIndex = int(my_util.Time2SecendNumber(tmpStartTime) / perWindows)
}
// 结束时间 -> Index
// 向右移动的时候,总长度是未知的,所以返回的值需要在外部重新 Check 是否会越界
endTime := s.GetEndTime(true)
subTime := time.Duration(expandTimeRange) * time.Second
tmpEndTime := endTime.Add(subTime)
// 需要从秒换算到偏移的 Index 数值,一共多少份
tmpEndTimeIndex = int(my_util.Time2SecendNumber(tmpEndTime) / perWindows)

return tmpStartTimeIndex, tmpEndTimeIndex
}

// RealTimeToOffsetTime 真实时间转偏移时间
func (s SubUnit) RealTimeToOffsetTime(realTime time.Time) time.Time {
dd := my_util.Time2Duration(s.baseTime)
return realTime.Add(-dd)
}

const perWindows = float64(vad.FrameDuration) / 1000

0 comments on commit 5b96918

Please sign in to comment.