Statistics
| Revision:

ccc / projets / TRS2SRT-standalone / src / org / txm / importer / transcriber / TRS2SRT.groovy @ 4

History | View | Annotate | Download (5.6 kB)

1
package org.txm.importer.transcriber
2
/**
3
 * Converts a file from Transcriber XML to STR subtitle file
4
 * 
5
 * @author mdecorde
6
 *
7
 */
8

    
9

    
10
import java.util.ArrayList
11

    
12
import javax.xml.parsers.*
13
import javax.xml.stream.*
14

    
15
import java.net.URL
16

    
17
class TRS2SRT {
18

    
19
        private def url
20
        private def inputData
21
        private def factory
22
        private XMLStreamReader parser
23
        def writer
24

    
25
        def colors = ["white", "red", "blue", "green", "yellow", "grey", "violet", "pink", "orange", "brown"];
26
        def icolor = 0;
27

    
28
        File trsFile;
29
        boolean debug = false
30

    
31
        public TRS2SRT(File trsFile) {
32
                inputData = trsFile.toURI().toURL().openStream()
33
                factory = XMLInputFactory.newInstance()
34
                parser = factory.createXMLStreamReader(inputData)
35

    
36
                this.trsFile = trsFile
37
        }
38

    
39
        /**
40
         * Transform the trsFile to STR format
41
         * 
42
         * @param srtFile: result file
43
         */
44
        public void process(File srtFile) {
45
                writer = srtFile.newWriter("UTF-8")
46
                for (int event = parser.next(); event != XMLStreamConstants.END_DOCUMENT; event = parser.next()) {
47
                        switch (event) {
48
                                case XMLStreamConstants.START_ELEMENT:
49
                                        processStartElement()
50
                                        break;
51
                                case XMLStreamConstants.END_ELEMENT:
52
                                        processEndElement()
53
                                        break;
54
                                case XMLStreamConstants.CHARACTERS:
55
                                        processText()
56
                                        break;
57
                        }
58
                }
59
                writer.close()
60
        }
61

    
62
        def speakers = [:]
63
        def currentSpeakers = []
64
        def currentSpeaker = "";
65
        def currentSpeach = ""
66
        def currentStartTime = ""
67
        def currentEndTime = ""
68
        def inTurn = false
69
        def nTurn = 1
70
        def syncCounter = 0;
71
        def whoCounter = 0;
72

    
73
        protected void processStartElement() {
74
                String localname = parser.getLocalName()
75
                switch (localname) {
76
                        case "Speaker":
77
                                def info = [:]
78
                                speakers[parser.getAttributeValue(null, "id")] = info
79
                                info["name"] = parser.getAttributeValue(null, "name")
80
                                info["color"] = colors[icolor]
81
                                info["count"] = 0;
82
                                icolor++;
83
                                break;
84
                        case "Episode":
85
                                if (debug) println "speakers $speakers"
86
                                break;
87
                        case "Turn":
88
                                if (debug) println "Turn!"
89
                                currentSpeakers = parser.getAttributeValue(null, "speaker").split(" ")
90
                                currentSpeaker = currentSpeakers[0]
91
                                currentSpeach = ""
92
                                String s = parser.getAttributeValue(null, "startTime")
93
                                String e = parser.getAttributeValue(null, "endTime")
94
                                currentStartTime = Float.parseFloat(s)
95
                                if (e != null) currentEndTime = Float.parseFloat(e)
96
                                else currentEndTime = currentStartTime+3.0; // temporary fix
97
                                inTurn = true
98
                                syncCounter = 0;
99
                                whoCounter = 0;
100
                                break;
101
                        case "Event":
102
                        if (debug) println "Event!"
103
                                currentSpeach += " ["+parser.getAttributeValue(null, "desc")+"] "
104
                                break;
105
                        case "Sync": // cut a Turn, the Turn@endTime must be replace with Sync@time
106
                                if (debug) println "Sync!"
107
                                syncCounter++; 
108
                                if (syncCounter > 1) { // ignore first 'Sync', there is no speech to write
109
                                        def end = currentEndTime
110
                                        currentEndTime = Float.parseFloat(parser.getAttributeValue(null, "time"))
111
                                        writeSRTTurn() // write previous Turn, so currentEndTime is the Sync@time
112
                                        currentEndTime = end; // restore Turn@endTime
113
                                }
114
                                break;
115
                        case "Who":
116
                                if (debug) println "Who!"
117
                                whoCounter++;
118
                                if (whoCounter > 1) { // ignore first 'Who', there is no speach to write
119
                                        int n = Integer.parseInt(parser.getAttributeValue(null, "nb")) - 1
120
                                        if (currentSpeakers.size() <= n) {
121
                                                println "'Who@nb' Error at "+parser.getLocation()
122
                                                break;
123
                                        }
124
                                        
125
                                        writeSRTTurn() // write previous speach                
126
                                        // switch current speaker
127
                                        currentSpeaker = currentSpeakers[Integer.parseInt(parser.getAttributeValue(null, "nb")) - 1]
128
                                }
129
                                break;
130
                }
131
        }
132

    
133
        protected void processEndElement() {
134
                String localname = parser.getLocalName()
135
                switch (localname) {
136
                        case "Speaker":
137
                                break;
138
                        case "Turn":
139
                                inTurn = false
140
                                writeSRTTurn()
141
                                break;
142
                        case "Sync":
143
                                break;
144
                        case "Who":
145
                                break;
146
                }
147
        }
148

    
149
        protected writeSRTTurn() {
150
                currentSpeach = currentSpeach.trim()
151

    
152
                if (currentSpeach.length() == 0) return; // nothing to write
153

    
154
                //println "Writing Turn of '$currentSpeaker': "+speakers[currentSpeaker]
155
                def color = speakers[currentSpeaker]["color"]
156

    
157
                if (speakers[currentSpeaker]["count"] < 2) {
158
                        speakers[currentSpeaker]["count"] = speakers[currentSpeaker]["count"] + 1;
159
                        currentSpeach = speakers[currentSpeaker]["name"]+"\t"+currentSpeach
160
                }
161

    
162
                currentSpeach = "<font color=\"$color\">$currentSpeach</font>".replaceAll("\n", " ")
163

    
164
                def s = formatTime(currentStartTime)
165
                def e = formatTime(currentEndTime)
166
                currentStartTime = currentEndTime
167
                writer.println """
168
$nTurn
169
$s --> $e
170
$currentSpeach"""
171
                nTurn++
172
                currentSpeach = "" // reset speach
173
        }
174

    
175
        protected void processText() {
176
                String txt = parser.getText();
177
                if (inTurn) {
178
                        currentSpeach += txt
179
                }
180
        }
181

    
182
        private String formatTime(float time) {
183
                String rez = " ";
184

    
185
                int ms = (time - (int)time) * 1000
186

    
187
                float h = time / 3600;
188
                time = time%3600;
189

    
190
                float min = (time%3600) / 60;
191
                int sec = (int)time%60
192

    
193
                if (min < 10)
194
                        rez = ""+(int)h+":0"+(int)min;//+":"+time%60;
195
                else
196
                        rez = ""+(int)h+":"+(int)min;//+":"+time%60;
197

    
198
                if (sec >= 10)
199
                        rez += ":"+sec;
200
                else
201
                        rez += ":0"+sec;
202

    
203
                rez += "."+ms
204
                return rez;
205
        }
206

    
207
        public static void main(String[] args) {
208
                if (args.length == 0) {
209
                        println "Usage:"
210
                        println "java -jar TRS2SRT.jar file1 file2 file3"
211
                        println "\nResult files are saved in the save directory as fileN files."
212
                }
213
        //        args = ["/home/mdecorde/CCC/RECETTE/TRS2SRT/victor/pazinterior_ok.trs"]
214
                for (String path : args) {
215
                        println "Processing path=$path ..."
216
                        
217
                        File trsFile = new File(path)
218
                        String name = trsFile.getName()
219
                        name = name.substring(0, name.indexOf("."))
220
                        File srtFile = new File(trsFile.getParentFile(), name+".srt")
221
                        TRS2SRT t = new TRS2SRT(trsFile)
222
                        t.process(srtFile)
223
                }
224
        }
225
}