Skip to content

Commit ffae2a1

Browse files
committed
Add srt validation and preview
1 parent abf404c commit ffae2a1

File tree

5 files changed

+84
-12
lines changed

5 files changed

+84
-12
lines changed

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
"dependencies": {
1414
"@vuikit/icons": "^0.8.1",
1515
"@vuikit/theme": "^0.8.1",
16+
"plyr": "^3.5.10",
1617
"pug": "^2.0.4",
18+
"srt-webvtt": "^1.0.1",
1719
"stylus": "^0.54.7",
1820
"stylus-loader": "^3.0.2",
1921
"vue": "^2.5.2",

src/App.vue

+38-12
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@
4141
| {{ $t("startReviewing") }}
4242
div(v-if="stage === 'review'")
4343
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") }}
4650
a.hidden(ref="download", href="")
4751
.panel
4852
input.hidden(
@@ -52,14 +56,16 @@
5256
@change="readVideo")
5357
vk-button(@click="loadVideo", v-if="stage === 'prepare'")
5458
| {{ $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")
5962
shortcut(v-show="stage === 'edit'")
6063
</template>
6164

6265
<script>
66+
import VTTConverter from 'srt-webvtt';
67+
import Plyr from 'plyr'; // Firefox CC is buggy.
68+
6369
import Navbar from './components/Navbar';
6470
import Shortcut from './components/Shortcut';
6571
@@ -73,6 +79,7 @@ export default {
7379
return {
7480
modalShow: false,
7581
modalText: '',
82+
player: new Plyr('#player'),
7683
stage: 'prepare',
7784
subtitleText: '',
7885
subtitles: [],
@@ -115,7 +122,7 @@ export default {
115122
readVideo(evt) {
116123
const filename = evt.target.files[0];
117124
const url = URL.createObjectURL(filename);
118-
this.$refs.video.src = url;
125+
this.$refs.source.src = url;
119126
this.$refs.video.load();
120127
},
121128
startEdit() {
@@ -133,7 +140,9 @@ export default {
133140
startReview() {
134141
window.removeEventListener('keypress', this.keyHandler);
135142
this.stage = 'review';
143+
this.$refs.video.currentTime = 0;
136144
this.generateSubtitle();
145+
this.updatePreview();
137146
},
138147
keyHandler(e) {
139148
const pressed = String.fromCharCode(e.keyCode).toLowerCase();
@@ -192,12 +201,12 @@ export default {
192201
},
193202
timeFormat(secs) {
194203
if (secs === null) {
195-
return '0:0:0,0';
204+
return '00:00:00,000';
196205
}
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');
201210
return `${hour}:${min}:${sec},${mil}`;
202211
},
203212
generateSubtitle() {
@@ -208,6 +217,23 @@ export default {
208217
this.subtitleReview += `${this.subtitles[i]}\n\n`;
209218
}
210219
},
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+
},
211237
saveFile() {
212238
const a = this.$refs.download;
213239
const file = new Blob([this.subtitleReview], { type: 'text/plain' });

src/main.js

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import VuikitIcons from '@vuikit/icons';
66
import VueI18n from 'vue-i18n';
77

88
import '@vuikit/theme';
9+
import 'plyr/dist/plyr.css';
10+
911
import App from './App';
1012
import messages from './i18n';
1113

static/empty.vtt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
WEBVTT FILE

yarn.lock

+41
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,11 @@ core-js@^2.4.0, core-js@^2.5.0:
18731873
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c"
18741874
integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==
18751875

1876+
core-js@^3.6.4:
1877+
version "3.6.4"
1878+
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.4.tgz#440a83536b458114b9cb2ac1580ba377dc470647"
1879+
integrity sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==
1880+
18761881
core-util-is@~1.0.0:
18771882
version "1.0.2"
18781883
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -2198,6 +2203,11 @@ currently-unhandled@^0.4.1:
21982203
dependencies:
21992204
array-find-index "^1.0.1"
22002205

2206+
custom-event-polyfill@^1.0.7:
2207+
version "1.0.7"
2208+
resolved "https://registry.yarnpkg.com/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz#9bc993ddda937c1a30ccd335614c6c58c4f87aee"
2209+
integrity sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==
2210+
22012211
cyclist@^1.0.1:
22022212
version "1.0.1"
22032213
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
@@ -4317,6 +4327,11 @@ loader-utils@^1.0.2, loader-utils@^1.1.0:
43174327
emojis-list "^3.0.0"
43184328
json5 "^1.0.1"
43194329

4330+
loadjs@^4.2.0:
4331+
version "4.2.0"
4332+
resolved "https://registry.yarnpkg.com/loadjs/-/loadjs-4.2.0.tgz#2a0336376397a6a43edf98c9ec3229ddd5abb6f6"
4333+
integrity sha512-AgQGZisAlTPbTEzrHPb6q+NYBMD+DP9uvGSIjSUM5uG+0jG15cb8axWpxuOIqrmQjn6scaaH8JwloiP27b2KXA==
4334+
43204335
locate-path@^2.0.0:
43214336
version "2.0.0"
43224337
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
@@ -5234,6 +5249,17 @@ pluralize@^7.0.0:
52345249
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777"
52355250
integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==
52365251

5252+
plyr@^3.5.10:
5253+
version "3.5.10"
5254+
resolved "https://registry.yarnpkg.com/plyr/-/plyr-3.5.10.tgz#631fb379135abd17ea822817db3046b484c8166c"
5255+
integrity sha512-wbbSuzk3yKVOmYWQUnxG1bxikqZNkxZmL3OjS1DFVU0D2Uko1evGY72LuD9rm/HnNCNzcTuc0c6MCn7bRRpUTA==
5256+
dependencies:
5257+
core-js "^3.6.4"
5258+
custom-event-polyfill "^1.0.7"
5259+
loadjs "^4.2.0"
5260+
rangetouch "^2.0.0"
5261+
url-polyfill "^1.1.8"
5262+
52375263
portfinder@^1.0.13, portfinder@^1.0.9:
52385264
version "1.0.25"
52395265
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.25.tgz#254fd337ffba869f4b9d37edc298059cb4d35eca"
@@ -6146,6 +6172,11 @@ range-parser@^1.0.3, range-parser@~1.2.1:
61466172
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
61476173
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
61486174

6175+
rangetouch@^2.0.0:
6176+
version "2.0.1"
6177+
resolved "https://registry.yarnpkg.com/rangetouch/-/rangetouch-2.0.1.tgz#c01105110fd3afca2adcb1a580692837d883cb70"
6178+
integrity sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==
6179+
61496180
61506181
version "2.4.0"
61516182
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332"
@@ -6884,6 +6915,11 @@ sprintf-js@~1.0.2:
68846915
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
68856916
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
68866917

6918+
srt-webvtt@^1.0.1:
6919+
version "1.0.1"
6920+
resolved "https://registry.yarnpkg.com/srt-webvtt/-/srt-webvtt-1.0.1.tgz#0842a9f4ac07679948de47c5d6d7f13151cfba97"
6921+
integrity sha1-CEKp9KwHZ5lI3kfF1tfxMVHPupc=
6922+
68876923
ssri@^5.2.4:
68886924
version "5.3.0"
68896925
resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06"
@@ -7484,6 +7520,11 @@ url-parse@^1.1.8, url-parse@^1.4.3:
74847520
querystringify "^2.1.1"
74857521
requires-port "^1.0.0"
74867522

7523+
url-polyfill@^1.1.8:
7524+
version "1.1.8"
7525+
resolved "https://registry.yarnpkg.com/url-polyfill/-/url-polyfill-1.1.8.tgz#21eb58ad61192f52b77dcac8ab5293ae7bc67060"
7526+
integrity sha512-Ey61F4FEqhcu1vHSOMmjl0Vd/RPRLEjMj402qszD/dhMBrVfoUsnIj8KSZo2yj+eIlxJGKFdnm6ES+7UzMgZ3Q==
7527+
74877528
url@^0.11.0:
74887529
version "0.11.0"
74897530
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"

0 commit comments

Comments
 (0)