@@ -13,12 +13,42 @@ import (
13
13
"path/filepath"
14
14
"strconv"
15
15
"strings"
16
+ "syscall"
16
17
)
17
18
18
19
type Conversion struct {
19
- StreamURLs []string
20
- Command * exec.Cmd
21
- OutputDirectory string
20
+ StreamURLs []string
21
+ mainCommand * exec.Cmd
22
+ SubtitleConversionCommands []SubtitleVariantConversion
23
+ OutputDirectory string
24
+ }
25
+
26
+ // Applies function f to all commands related to the conversion
27
+ func (c Conversion ) do (f func (cmd * exec.Cmd )) {
28
+ f (c .mainCommand )
29
+ for _ , subConv := range c .SubtitleConversionCommands {
30
+ f (subConv .commands .EncoderCommand )
31
+ }
32
+ }
33
+
34
+ func (c Conversion ) Signal (sig syscall.Signal ) {
35
+ c .do (func (cmd * exec.Cmd ) {
36
+ cmd .Process .Signal (sig )
37
+ })
38
+ }
39
+
40
+ func (c Conversion ) SigInt () {
41
+ c .Signal (syscall .SIGINT )
42
+ }
43
+
44
+ // Exit Kills all remaining ongoing conversion
45
+ func (c Conversion ) Exit () {
46
+ c .do (func (cmd * exec.Cmd ) {
47
+ if cmd .ProcessState == nil || ! cmd .ProcessState .Exited () {
48
+ // Process is not done
49
+ cmd .Process .Kill ()
50
+ }
51
+ })
22
52
}
23
53
24
54
var hlsSettings = []string {
@@ -32,6 +62,10 @@ var hlsSettings = []string{
32
62
"-hls_flags" , "split_by_time" ,
33
63
}
34
64
65
+ func ffmpegDefaultArguments () []string {
66
+ return []string {"-hide_banner" , "-y" , "-stats" , "-loglevel" , "warning" }
67
+ }
68
+
35
69
func ConvertFile (outputDir , masterPlaylistName , streamPlaylistName string , additionalSubtitleInputs []input.SubtitleInput , inputs ... string ) (* Conversion , error ) {
36
70
// Probe data
37
71
probeData , err := probe .GetProbeData (inputs ... )
@@ -42,35 +76,25 @@ func ConvertFile(outputDir, masterPlaylistName, streamPlaylistName string, addit
42
76
// Figure out variants
43
77
videoVariants := suggest .SuggestVideoVariants (probeData )
44
78
audioVariants := suggest .SuggestAudioVariants (probeData , false , true )
45
- subtitleVariants := suggest .SuggestSubtitlesVariants (probeData , additionalSubtitleInputs , true )
46
- maxSubs := len (videoVariants ) + len (audioVariants ) // FIXME
47
- if maxSubs < len (subtitleVariants ) {
48
- subtitleVariants = subtitleVariants [:maxSubs ]
49
- log .Println ("Warning: some subtitles won't be copied as you can't have " +
50
- "subtitle-only variants and there aren't enough other video and audio variants." )
51
- }
79
+ subtitleVariants := suggest .SuggestSubtitlesVariants (inputs , probeData , additionalSubtitleInputs , true )
52
80
53
81
// Generate FFMPEG command
54
- args := [] string { "-hide_banner" , "-y" , "-stats" , "-loglevel" , "warning" }
82
+ args := ffmpegDefaultArguments ()
55
83
// ... add inputs
56
84
for _ , input := range inputs {
57
85
args = append (args , "-i" , input )
58
86
}
59
- for _ , additionalSubtitleInput := range additionalSubtitleInputs {
60
- args = append (args , "-i" , additionalSubtitleInput .InputURL )
61
- }
87
+ // Additional subtitle inputs will be added later
62
88
63
- // ... add variants
89
+ // ... add video and audio variants
64
90
args = append (args , videoConversionArgs (videoVariants )... )
65
91
args = append (args , audioConversionArgs (audioVariants )... )
66
- args = append (args , subtitlesConversionArgs (subtitleVariants )... )
67
92
// ... add HLS options
68
93
args = append (args , hlsSettings ... )
69
94
// ... add HLS variants mapping
70
- args = append (args , "-var_stream_map" , variantsMapArg (videoVariants , audioVariants , subtitleVariants ))
95
+ args = append (args , "-var_stream_map" , variantsMapArg (videoVariants , audioVariants ))
71
96
72
97
// Create stream playlist
73
-
74
98
if err := os .MkdirAll (outputDir , 0700 ); err != nil {
75
99
log .Println ("Cannot create conversion dir at path '" + outputDir + "':" , err )
76
100
return nil , err // FIXME: return better error
@@ -80,7 +104,7 @@ func ConvertFile(outputDir, masterPlaylistName, streamPlaylistName string, addit
80
104
// HLS options
81
105
args = append (args , "-max_muxing_queue_size" , "1024" , outputFile )
82
106
83
- // Start conversion
107
+ // Start video and audio conversion
84
108
var cmd * exec.Cmd
85
109
masterCh := make (chan string )
86
110
cmd , err = callFFmpeg (filepath .Join (outputDir , "conversion.log" ), args , masterCh )
@@ -89,6 +113,9 @@ func ConvertFile(outputDir, masterPlaylistName, streamPlaylistName string, addit
89
113
return nil , err
90
114
}
91
115
116
+ // Start subtitles conversion
117
+ convertedSubtitles := convertSubtitles (subtitleVariants , outputDir )
118
+
92
119
// Generate master playlist
93
120
masterFilename := filepath .Join (outputDir , masterPlaylistName + ".m3u8" )
94
121
masterCh <- masterFilename
@@ -112,10 +139,10 @@ func ConvertFile(outputDir, masterPlaylistName, streamPlaylistName string, addit
112
139
}
113
140
}
114
141
// ... find subtitles groups
115
- if len (subtitleVariants ) > 0 {
142
+ if len (convertedSubtitles ) > 0 {
116
143
subtitlesGroup = & suggest .DefaultSubtitlesGroupID
117
- if subtitleVariants [0 ].GroupID != nil {
118
- subtitlesGroup = subtitleVariants [0 ].GroupID
144
+ if convertedSubtitles [0 ]. Variant .GroupID != nil {
145
+ subtitlesGroup = convertedSubtitles [0 ]. Variant .GroupID
119
146
}
120
147
}
121
148
// ... write audio
@@ -127,8 +154,9 @@ func ConvertFile(outputDir, masterPlaylistName, streamPlaylistName string, addit
127
154
f .WriteString ("\n " )
128
155
// ... write subtitles
129
156
streamIndex = 0 // Subtitle playlists restart at 0
130
- for _ , variant := range subtitleVariants {
131
- f .WriteString (variant .Stanza (playlistFilenameForSubtitlesStream (streamPlaylistName , streamIndex )) + "\n " )
157
+ for _ , c := range convertedSubtitles {
158
+ fmt .Printf ("DEBUG: Adding subtitle %q to Master\n " , c .Variant .Name )
159
+ f .WriteString (c .Variant .Stanza () + "\n " )
132
160
streamIndex += 1
133
161
}
134
162
f .WriteString ("\n \n " )
@@ -149,9 +177,10 @@ func ConvertFile(outputDir, masterPlaylistName, streamPlaylistName string, addit
149
177
f .Close ()
150
178
151
179
return & Conversion {
152
- StreamURLs : inputs ,
153
- Command : cmd ,
154
- OutputDirectory : outputDir ,
180
+ StreamURLs : inputs ,
181
+ mainCommand : cmd ,
182
+ SubtitleConversionCommands : convertedSubtitles ,
183
+ OutputDirectory : outputDir ,
155
184
}, nil
156
185
}
157
186
@@ -208,7 +237,3 @@ func callFFmpeg(logFilename string, args []string, masterCh <-chan string) (*exe
208
237
func playlistFilenameForStream (streamPlaylistName string , index int ) string {
209
238
return streamPlaylistName + "_" + strconv .Itoa (index ) + ".m3u8"
210
239
}
211
-
212
- func playlistFilenameForSubtitlesStream (streamPlaylistName string , index int ) string {
213
- return streamPlaylistName + "_" + strconv .Itoa (index ) + "_vtt.m3u8"
214
- }
0 commit comments