Skip to content

Commit 7ad0eac

Browse files
authored
Merge pull request #4 from Nigh/time-selection
Add time selection
2 parents e1aa520 + 51fb42b commit 7ad0eac

4 files changed

Lines changed: 134 additions & 26 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
VERSION?=v0.0.0-test
2+
VERSION?=v1.1.0
33

44
DIR = dist
55
EXECUTABLE = ass-shifter

Makefile_windows

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
VERSION?=v0.0.0-test
2+
VERSION?=v1.1.0
33

44
DIR = dist
55
EXECUTABLE = ass-shifter

README.md

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Shift Subtitle of [`.ass`, `.srt`] format
33

44
> [!CAUTION]
5-
> It will replace your subtitle, **backup** before run.
5+
> It will replace your subtitle, **backup** your subtitle files before run.
66
77

88
## Usage
@@ -15,19 +15,31 @@ ass-shifter [path] -t [shift ms]
1515
--version Displays the program version string.
1616
-h --help Displays help with available flag, subcommand, and positional value parameters.
1717
-t --shift shift ms (default: 0)
18+
-s --start start from HH:MM:SS
19+
-e --end end at HH:MM:SS
1820
```
1921

2022
## Example
23+
The `start` and `end` parameters are optional. They can also be used together.
2124
```bash
22-
ass-shifter ../BCS -t -1002
23-
[SUCCESS] Shifted -1002ms -> Better Call Saul - 1x01 - Uno.HDTV.KILLERS.en.srt
24-
[SUCCESS] Shifted -1002ms -> Better Call Saul - 1x02 - Mijo.HDTV.LOL.en.srt
25-
[SUCCESS] Shifted -1002ms -> Better Call Saul - 1x03 - Nacho.HDTV.x264-LOL.en.srt
26-
[SUCCESS] Shifted -1002ms -> Better Call Saul - 1x04 - Hero.HDTV.LOL.en.srt
27-
[SUCCESS] Shifted -1002ms -> Better Call Saul - 1x05 - Alpine Shepherd Boy.HDTV.x264-LOL.en.srt
28-
[SUCCESS] Shifted -1002ms -> Better.Call.Saul.S05E06.2020.1080p.BluRay.x265.10bit.ass
29-
[SUCCESS] Shifted -1002ms -> Better.Call.Saul.S05E07.2020.1080p.BluRay.x265.10bit.ass
30-
[SUCCESS] Shifted -1002ms -> Better.Call.Saul.S05E08.2020.1080p.BluRay.x265.10bit.ass
31-
[SUCCESS] Shifted -1002ms -> Better.Call.Saul.S05E09.2020.1080p.BluRay.x265.10bit.ass
32-
[SUCCESS] Shifted -1002ms -> Better.Call.Saul.S05E10.2020.1080p.BluRay.x265.10bit.ass
25+
ass-shifter ../Better.Call.Saul/S03 -t -3200
26+
ass-shifter ../Better.Call.Saul/S03 -t -3200 -s 0:06:13
27+
ass-shifter ../Better.Call.Saul/S03 -t -3200 -s 0:06:13 -e 0:24:12
28+
```
29+
30+
The program prints the result of the execution like the following.
31+
```bash
32+
ass-shifter ../Better.Call.Saul/S03 -t -3200 -s 0:06:13
33+
34+
[SUCCESS] Better.Call.Saul.S03E01.2017.1080p.BluRay.x265.10bit.ass
35+
[SUCCESS] Better.Call.Saul.S03E02.2017.1080p.BluRay.x265.10bit.ass
36+
[SUCCESS] Better.Call.Saul.S03E03.2017.1080p.BluRay.x265.10bit.ass
37+
[SUCCESS] Better.Call.Saul.S03E04.2017.1080p.BluRay.x265.10bit.ass
38+
[SUCCESS] Better.Call.Saul.S03E05.2017.1080p.BluRay.x265.10bit.ass
39+
[SUCCESS] Better.Call.Saul.S03E06.2017.1080p.BluRay.x265.10bit.ass
40+
[SUCCESS] Better.Call.Saul.S03E07.2017.1080p.BluRay.x265.10bit.ass
41+
[SUCCESS] Better.Call.Saul.S03E08.2017.1080p.BluRay.x265.10bit.ass
42+
[SUCCESS] Better.Call.Saul.S03E09.2017.1080p.BluRay.x265.10bit.ass
43+
[SUCCESS] Better.Call.Saul.S03E10.2017.1080p.BluRay.x265.10bit.ass
44+
Total 10 files shifted -3200ms from 0:06:13 to end
3345
```

main.go

Lines changed: 108 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,13 @@ import (
1212
)
1313

1414
var (
15-
inputPath string
16-
shift int32
15+
inputPath string
16+
shift int
17+
from int
18+
to int
19+
fromStr string
20+
toStr string
21+
fileShifted int
1722
)
1823

1924
var version = "1.0.0"
@@ -24,25 +29,108 @@ func init() {
2429
flaggy.DefaultParser.ShowHelpOnUnexpected = true
2530
flaggy.DefaultParser.AdditionalHelpPrepend = "https://github.com/Nigh/subtitle-ass-shifter"
2631
flaggy.AddPositionalValue(&inputPath, "path", 1, true, "the subtitle path to shift")
27-
flaggy.Int32(&shift, "t", "shift", "shift ms")
32+
flaggy.Int(&shift, "t", "shift", "shift ms")
33+
flaggy.String(&fromStr, "s", "start", "start from HH:MM:SS")
34+
flaggy.String(&toStr, "e", "end", "end at HH:MM:SS")
2835
flaggy.SetVersion(version)
2936
flaggy.Parse()
3037
}
38+
39+
func parseFromTo() error {
40+
re := regexp.MustCompile(`(-?\d+):(\d\d):(\d\d)`)
41+
42+
if fromStr != "" {
43+
matches := re.FindStringSubmatch(fromStr)
44+
if matches == nil {
45+
return fmt.Errorf("invalid start time format, expected HH:MM:SS, example: 0:23:45")
46+
}
47+
48+
hours, _ := strconv.Atoi(matches[1])
49+
minutes, _ := strconv.Atoi(matches[2])
50+
seconds, _ := strconv.Atoi(matches[3])
51+
52+
sign := 1
53+
if hours < 0 {
54+
sign = -1
55+
}
56+
from = (hours*3600 + minutes*60 + seconds) * 1000 * sign
57+
}
58+
59+
if toStr != "" {
60+
matches := re.FindStringSubmatch(toStr)
61+
62+
if matches == nil {
63+
return fmt.Errorf("invalid end time format, expected HH:MM:SS, example: 1:32:54")
64+
}
65+
hours, _ := strconv.Atoi(matches[1])
66+
minutes, _ := strconv.Atoi(matches[2])
67+
seconds, _ := strconv.Atoi(matches[3])
68+
69+
sign := 1
70+
if hours < 0 {
71+
sign = -1
72+
}
73+
to = (hours*3600 + minutes*60 + seconds) * 1000 * sign
74+
}
75+
76+
return nil
77+
}
78+
79+
func timeInclude(t int) bool {
80+
if from == 0 && to == 0 {
81+
return true
82+
}
83+
if from != 0 && t < from {
84+
return false
85+
}
86+
if to != 0 && t > to {
87+
return false
88+
}
89+
return true
90+
}
91+
3192
func main() {
3293
if shift == 0 {
33-
fmt.Println("0ms shift means nothing to do.")
94+
fmt.Println("shift 0ms means nothing to do.")
3495
return
3596
}
97+
if err := parseFromTo(); err != nil {
98+
fmt.Println(err)
99+
return
100+
}
101+
if to != 0 && from != 0 {
102+
if from > to {
103+
fmt.Println("end must be greater than start")
104+
return
105+
}
106+
}
36107
inputPath, _ = filepath.Abs(inputPath)
37108
_, err := os.Stat(inputPath)
38109
if err != nil {
39110
fmt.Println(err)
40111
return
41112
}
42113
filepath.Walk(inputPath, walker)
114+
115+
if fileShifted > 0 {
116+
fmt.Print("Total " + strconv.Itoa(fileShifted) + " files shifted " + strconv.Itoa(shift) + "ms ")
117+
if from != 0 || to != 0 {
118+
if from != 0 {
119+
fmt.Print("from " + fromStr)
120+
} else {
121+
fmt.Print("from start")
122+
}
123+
if to != 0 {
124+
fmt.Print(" to " + toStr)
125+
} else {
126+
fmt.Print(" to end")
127+
}
128+
}
129+
fmt.Println()
130+
}
43131
}
44132

45-
func srtShift(realPath string, shift int32) {
133+
func srtShift(realPath string) {
46134
srtFile, err := os.ReadFile(realPath)
47135
if err != nil {
48136
fmt.Println(err)
@@ -73,7 +161,10 @@ func srtShift(realPath string, shift int32) {
73161
milliseconds *= sign
74162

75163
totalMs := (hours*3600+minutes*60+seconds)*1000 + milliseconds
76-
totalMs += int(shift)
164+
if !timeInclude(totalMs) {
165+
continue
166+
}
167+
totalMs += shift
77168

78169
if totalMs < 0 {
79170
sign = -1
@@ -98,10 +189,11 @@ func srtShift(realPath string, shift int32) {
98189
fmt.Println("[ERROR] "+filepath.Base(realPath), err)
99190
return
100191
}
101-
fmt.Println("[SUCCESS] Shifted " + strconv.Itoa(int(shift)) + "ms -> " + filepath.Base(realPath))
192+
fmt.Println("[SUCCESS] " + filepath.Base(realPath))
193+
fileShifted++
102194
}
103195

104-
func assShift(realPath string, shift int32) {
196+
func assShift(realPath string) {
105197
assFile, err := os.ReadFile(realPath)
106198
if err != nil {
107199
fmt.Println(err)
@@ -132,7 +224,10 @@ func assShift(realPath string, shift int32) {
132224
milliseconds *= sign
133225

134226
totalMs := (hours*3600+minutes*60+seconds)*1000 + milliseconds
135-
totalMs += int(shift)
227+
if !timeInclude(totalMs) {
228+
continue
229+
}
230+
totalMs += shift
136231

137232
if totalMs < 0 {
138233
sign = -1
@@ -157,7 +252,8 @@ func assShift(realPath string, shift int32) {
157252
fmt.Println("[ERROR] "+filepath.Base(realPath), err)
158253
return
159254
}
160-
fmt.Println("[SUCCESS] Shifted " + strconv.Itoa(int(shift)) + "ms -> " + filepath.Base(realPath))
255+
fmt.Println("[SUCCESS] " + filepath.Base(realPath))
256+
fileShifted++
161257
}
162258

163259
func walker(realPath string, f os.FileInfo, err error) error {
@@ -167,9 +263,9 @@ func walker(realPath string, f os.FileInfo, err error) error {
167263
}
168264
switch strings.ToLower(ext) {
169265
case ".srt":
170-
srtShift(realPath, shift)
266+
srtShift(realPath)
171267
case ".ass":
172-
assShift(realPath, shift)
268+
assShift(realPath)
173269
default:
174270
return nil
175271
}

0 commit comments

Comments
 (0)