41
41
| {{ $t("startReviewing") }}
42
42
div( v-if ="stage === 'review'" )
43
43
textarea.uk-textarea ( rows ="20" , v-model ="subtitleReview" )
44
- vk-button.uk-margin ( type ="primary" , @click ="saveFile" )
45
- | {{ $t("saveFile") }}
44
+ .uk-margin
45
+ vk-button( @click ="updatePreview" )
46
+ | Update Preview
47
+ .uk-margin
48
+ vk-button( type ="primary" , @click ="saveFile" )
49
+ | {{ $t("saveFile") }}
46
50
a.hidden ( ref ="download" , href ="" )
47
51
.panel
48
52
input.hidden (
52
56
@change ="readVideo" )
53
57
vk-button( @click ="loadVideo" , v-if ="stage === 'prepare'" )
54
58
| {{ $t("loadVideo") }}
55
- video.video.uk-margin (
56
- ref ="video" ,
57
- src ="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" ,
58
- controls )
59
+ video.video #player .uk-margin ( ref ="video" , controls )
60
+ source( type ="video/mp4" , ref ="source" , src ="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" )
61
+ track( default , kind ="subtitles" , label ="Default" , ref ="caption" , src ="/static/empty.vtt" )
59
62
shortcut( v-show ="stage === 'edit'" )
60
63
</template >
61
64
62
65
<script >
66
+ import VTTConverter from ' srt-webvtt' ;
67
+ import Plyr from ' plyr' ; // Firefox CC is buggy.
68
+
63
69
import Navbar from ' ./components/Navbar' ;
64
70
import Shortcut from ' ./components/Shortcut' ;
65
71
@@ -73,6 +79,7 @@ export default {
73
79
return {
74
80
modalShow: false ,
75
81
modalText: ' ' ,
82
+ player: new Plyr (' #player' ),
76
83
stage: ' prepare' ,
77
84
subtitleText: ' ' ,
78
85
subtitles: [],
@@ -115,7 +122,7 @@ export default {
115
122
readVideo (evt ) {
116
123
const filename = evt .target .files [0 ];
117
124
const url = URL .createObjectURL (filename);
118
- this .$refs .video .src = url;
125
+ this .$refs .source .src = url;
119
126
this .$refs .video .load ();
120
127
},
121
128
startEdit () {
@@ -133,7 +140,9 @@ export default {
133
140
startReview () {
134
141
window .removeEventListener (' keypress' , this .keyHandler );
135
142
this .stage = ' review' ;
143
+ this .$refs .video .currentTime = 0 ;
136
144
this .generateSubtitle ();
145
+ this .updatePreview ();
137
146
},
138
147
keyHandler (e ) {
139
148
const pressed = String .fromCharCode (e .keyCode ).toLowerCase ();
@@ -192,12 +201,12 @@ export default {
192
201
},
193
202
timeFormat (secs ) {
194
203
if (secs === null ) {
195
- return ' 0:0:0,0 ' ;
204
+ return ' 00:00:00,000 ' ;
196
205
}
197
- const hour = Math .floor (secs / 60 / 60 );
198
- const min = Math .floor ((secs / 60 ) % 60 );
199
- const sec = Math .floor (secs % 60 );
200
- const mil = Math .floor ((secs * 1000 ) % 1000 );
206
+ const hour = ` ${ Math .floor (secs / 60 / 60 ) } ` . padStart ( 2 , ' 0 ' );
207
+ const min = ` ${ Math .floor ((secs / 60 ) % 60 ) } ` . padStart ( 2 , ' 0 ' );
208
+ const sec = ` ${ Math .floor (secs % 60 ) } ` . padStart ( 2 , ' 0 ' );
209
+ const mil = ` ${ Math .floor ((secs * 1000 ) % 1000 ) } ` . padStart ( 3 , ' 0 ' );
201
210
return ` ${ hour} :${ min} :${ sec} ,${ mil} ` ;
202
211
},
203
212
generateSubtitle () {
@@ -208,6 +217,23 @@ export default {
208
217
this .subtitleReview += ` ${ this .subtitles [i]} \n\n ` ;
209
218
}
210
219
},
220
+ async updatePreview () {
221
+ const blob = new Blob (
222
+ [this .subtitleReview ],
223
+ {
224
+ type: ' text/plain;charset=utf-8' ,
225
+ },
226
+ );
227
+ try {
228
+ const converter = new VTTConverter (blob);
229
+ const url = await converter .getURL ();
230
+ this .$refs .caption .setAttribute (' src' , url);
231
+ this .$refs .video .load ();
232
+ } catch (_e) {
233
+ this .modalShow = true ;
234
+ this .modalText = ' SRT file is invalid.' ;
235
+ }
236
+ },
211
237
saveFile () {
212
238
const a = this .$refs .download ;
213
239
const file = new Blob ([this .subtitleReview ], { type: ' text/plain' });
0 commit comments