From 3a9f6eed2786f05ed544f7cf4e249ebd9a34bd10 Mon Sep 17 00:00:00 2001 From: Nicolas DEROUINEAU Date: Thu, 20 Aug 2020 09:22:04 +0200 Subject: [PATCH 1/5] Add custom subtitle track in frontend --- frontend/package-lock.json | 208 +++++++++++++++++-- frontend/package.json | 3 +- frontend/src/components/Video/VideoDetail.js | 45 ++++ 3 files changed, 236 insertions(+), 20 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a838b07f..8a29833f 100755 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1179,6 +1179,35 @@ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, + "@fortawesome/fontawesome-common-types": { + "version": "0.2.30", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.30.tgz", + "integrity": "sha512-TsRwpTuKwFNiPhk1UfKgw7zNPeV5RhNp2Uw3pws+9gDAkPGKrtjR1y2lI3SYn7+YzyfuNknflpBA1LRKjt7hMg==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "1.2.30", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.30.tgz", + "integrity": "sha512-E3sAXATKCSVnT17HYmZjjbcmwihrNOCkoU7dVMlasrcwiJAHxSKeZ+4WN5O+ElgO/FaYgJmASl8p9N7/B/RttA==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.30" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "5.14.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.14.0.tgz", + "integrity": "sha512-M933RDM8cecaKMWDSk3FRYdnzWGW7kBBlGNGfvqLVwcwhUPNj9gcw+xZMrqBdRqxnSXdl3zWzTCNNGEtFUq67Q==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.30" + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.11.tgz", + "integrity": "sha512-sClfojasRifQKI0OPqTy8Ln8iIhnxR/Pv/hukBhWnBz9kQRmqi6JSH3nghlhAY7SUeIIM7B5/D2G8WjX0iepVg==", + "requires": { + "prop-types": "^15.7.2" + } + }, "@hapi/address": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", @@ -1633,9 +1662,9 @@ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==" }, "@popperjs/core": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.4.0.tgz", - "integrity": "sha512-NMrDy6EWh9TPdSRiHmHH2ye1v5U0gBD7pRYwSwJvomx7Bm4GG04vu63dYiVzebLOx2obPpJugew06xVP0Nk7hA==" + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.4.4.tgz", + "integrity": "sha512-1oO6+dN5kdIA3sKPZhRGJTfGVP4SWV6KqlMOwry4J3HfyD68sl/3KmG7DeYUzvN+RbhXDnv/D8vNNB8168tAMg==" }, "@restart/context": { "version": "2.1.4", @@ -1651,6 +1680,63 @@ "lodash-es": "^4.17.15" } }, + "@sentry/browser": { + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.21.1.tgz", + "integrity": "sha512-sUxsW545klZxJE4iBAYQ8SuVS85HTOGNmIIIZWFUogB5oW3O0L+nJluXEqf/pHU82LnjDIzqsWCYQ0cRUaeYow==", + "requires": { + "@sentry/core": "5.21.1", + "@sentry/types": "5.21.1", + "@sentry/utils": "5.21.1", + "tslib": "^1.9.3" + } + }, + "@sentry/core": { + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.21.1.tgz", + "integrity": "sha512-Luulwx3GLUiY0gmHOhU+4eSga28Ce8DwoBcRq9GkGuhPu9r80057d5urxrDLp/leIZBXVvpY7tvmSN/rMtvF9w==", + "requires": { + "@sentry/hub": "5.21.1", + "@sentry/minimal": "5.21.1", + "@sentry/types": "5.21.1", + "@sentry/utils": "5.21.1", + "tslib": "^1.9.3" + } + }, + "@sentry/hub": { + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.21.1.tgz", + "integrity": "sha512-x5i9Ggi5ZYMhBYL5kyTu2fUJ6owjKH2tgJL3UExoZdRyZkbLAFZb+DtfSnteWgQ6wriGfgPD3r/hAIEdaomk2A==", + "requires": { + "@sentry/types": "5.21.1", + "@sentry/utils": "5.21.1", + "tslib": "^1.9.3" + } + }, + "@sentry/minimal": { + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.21.1.tgz", + "integrity": "sha512-OBVPASZ+mcXMKajvJon9RjEZ+ny3+VGhOI66acoP1hmYxKvji1OC2bYEuP1r4qtHxWVLAdV7qFj3EQ9ckErZmQ==", + "requires": { + "@sentry/hub": "5.21.1", + "@sentry/types": "5.21.1", + "tslib": "^1.9.3" + } + }, + "@sentry/types": { + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.21.1.tgz", + "integrity": "sha512-hFN4aDduMpjj6vZSIIp+9kSr8MglcKO/UmbuUXN6hKLewhxt+Zj2wjXN7ulSs5OK5mjXP9QLA5YJvVQsl2//qw==" + }, + "@sentry/utils": { + "version": "5.21.1", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.21.1.tgz", + "integrity": "sha512-p5vPuc7+GfOmW8CXxWd0samS77Q00YrN8q5TC/ztF8nBhEF18GiMeWAdQnlSwt3iWal3q3gSSrbF4c9guIugng==", + "requires": { + "@sentry/types": "5.21.1", + "tslib": "^1.9.3" + } + }, "@svgr/babel-plugin-add-jsx-attribute": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-4.2.0.tgz", @@ -1847,6 +1933,16 @@ "@babel/types": "^7.3.0" } }, + "@types/classnames": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.10.tgz", + "integrity": "sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ==" + }, + "@types/invariant": { + "version": "2.2.33", + "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.33.tgz", + "integrity": "sha512-/jUNmS8d4bCKdqslfxW6dg/9Gksfzxz67IYfqApHn+HvHlMVXwYv2zpTDnS/yaK9BB0i0GlBTaYci0EFE62Hmw==" + }, "@types/istanbul-lib-coverage": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz", @@ -2728,9 +2824,9 @@ "integrity": "sha512-1aGDUfL1qOOIoqk9QKGIo2lANk+C7ko/fqH0uIyC71x3PEGz0uVP8ISgfEsFuG+FKmjHTvFK/nNM8dowpmUxLA==" }, "babel-plugin-styled-components": { - "version": "1.10.7", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.7.tgz", - "integrity": "sha512-MBMHGcIA22996n9hZRf/UJLVVgkEOITuR2SvjHLb5dSTUyR4ZRGn+ngITapes36FI3WLxZHfRhkA1ffHxihOrg==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.11.1.tgz", + "integrity": "sha512-YwrInHyKUk1PU3avIRdiLyCpM++18Rs1NgyMXEAQC33rIXs/vro0A+stf4sT0Gf22Got+xRWB8Cm0tw+qkRzBA==", "requires": { "@babel/helper-annotate-as-pure": "^7.0.0", "@babel/helper-module-imports": "^7.0.0", @@ -4009,6 +4105,15 @@ "sha.js": "^2.4.8" } }, + "create-react-context": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz", + "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==", + "requires": { + "gud": "^1.0.0", + "warning": "^4.0.3" + } + }, "cross-spawn": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", @@ -6280,6 +6385,11 @@ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" + }, "gzip-size": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", @@ -9821,8 +9931,7 @@ "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "optional": true + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" }, "pify": { "version": "2.3.0", @@ -11095,21 +11204,26 @@ } }, "react-bootstrap": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.0.1.tgz", - "integrity": "sha512-xMHwsvDN7sIv26P9wWiosWjITZije2dRCjEJHVfV2KFoSJY+8uv2zttEw0XMB7xviQcW3zuIGLJXuj8vf6lYEg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-1.3.0.tgz", + "integrity": "sha512-GYj0c6FO9mx7DaO8Xyz2zs0IcQ6CGCtM3O6/feIoCaG4N8B0+l4eqL7stlMcLpqO4d8NG2PoMO/AbUOD+MO7mg==", "requires": { "@babel/runtime": "^7.4.2", "@restart/context": "^2.1.4", "@restart/hooks": "^0.3.21", - "@types/react": "^16.9.23", + "@types/classnames": "^2.2.10", + "@types/invariant": "^2.2.33", + "@types/prop-types": "^15.7.3", + "@types/react": "^16.9.35", + "@types/react-transition-group": "^4.4.0", + "@types/warning": "^3.0.0", "classnames": "^2.2.6", "dom-helpers": "^5.1.2", "invariant": "^2.2.4", "prop-types": "^15.7.2", "prop-types-extra": "^1.1.0", - "react-overlays": "^3.1.2", - "react-transition-group": "^4.0.0", + "react-overlays": "^4.1.0", + "react-transition-group": "^4.4.1", "uncontrollable": "^7.0.0", "warning": "^4.0.3" } @@ -11326,9 +11440,9 @@ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "react-overlays": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-3.2.0.tgz", - "integrity": "sha512-YTgCmw6l4uBOYylSnc3V8WLX+A0EoGnzDrqkYz0K7MUKbMBZFpaxLXH4EF9eZbspd+syZHQ5XAABI7n/zak1EA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-4.1.0.tgz", + "integrity": "sha512-vdRpnKe0ckWOOD9uWdqykLUPHLPndIiUV7XfEKsi5008xiyHCfL8bxsx4LbMrfnxW1LzRthLyfy50XYRFNQqqw==", "requires": { "@babel/runtime": "^7.4.5", "@popperjs/core": "^2.0.0", @@ -11340,6 +11454,20 @@ "warning": "^4.0.3" } }, + "react-popper": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.7.tgz", + "integrity": "sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww==", + "requires": { + "@babel/runtime": "^7.1.2", + "create-react-context": "^0.3.0", + "deep-equal": "^1.1.1", + "popper.js": "^1.14.4", + "prop-types": "^15.6.1", + "typed-styles": "^0.0.7", + "warning": "^4.0.2" + } + }, "react-router": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", @@ -11633,6 +11761,39 @@ "prop-types": "^15.6.2" } }, + "reactstrap": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-8.5.1.tgz", + "integrity": "sha512-igpdw8DiW48ZtwGOo2unwlsILFlF7deiqFUAqc3wrsX/0H0OkvmezJdkjJx2X9jaHfjGdPpm0vu5VN/kk7tv+A==", + "requires": { + "@babel/runtime": "^7.2.0", + "classnames": "^2.2.3", + "prop-types": "^15.5.8", + "react-popper": "^1.3.6", + "react-transition-group": "^2.3.1" + }, + "dependencies": { + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + } + } + }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", @@ -12770,6 +12931,11 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, + "srt-webvtt": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/srt-webvtt/-/srt-webvtt-1.0.1.tgz", + "integrity": "sha1-CEKp9KwHZ5lI3kfF1tfxMVHPupc=" + }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -13525,6 +13691,11 @@ "mime-types": "~2.1.24" } }, + "typed-styles": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", + "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -13950,8 +14121,7 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "optional": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "readdirp": { "version": "3.4.0", diff --git a/frontend/package.json b/frontend/package.json index eb0d512e..1af27794 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -22,7 +22,8 @@ "react-scripts": "3.0.1", "react-slick": "^0.25.2", "reactstrap": "^8.4.1", - "styled-components": "latest" + "styled-components": "latest", + "srt-webvtt": "1.0.1" }, "scripts": { "prestart": "if [ ! -d node_modules ]; then npm install; fi", diff --git a/frontend/src/components/Video/VideoDetail.js b/frontend/src/components/Video/VideoDetail.js index 4815b107..2cca937d 100644 --- a/frontend/src/components/Video/VideoDetail.js +++ b/frontend/src/components/Video/VideoDetail.js @@ -2,6 +2,9 @@ import React, {useEffect, useState} from 'react'; import { client } from '../../api/djangoAPI'; import Button from "@material-ui/core/Button"; import './VideoDetail.css' +import VTTConverter from 'srt-webvtt'; + + @@ -10,12 +13,46 @@ function VideoDetail ({ video, handleVideoSelect, authTokens, setHistoryPager } const [timer, setTimer] = useState(false); const [count, setCount] = useState(0); + //const [customsub, setCustomSub] = useState(''); async function HandleNextEpisode(handleVideoSelect, nextEpisodeID) { const video = await client.getVideoById(nextEpisodeID); handleVideoSelect(video); } + const handleChange = event => { + let customsub = event.target.value; + var ext = customsub.substr(customsub.lastIndexOf('.') + 1); + console.log(ext); + if(ext != "srt"){ + alert("Only .srt files are supported \n"); + return; + } + console.log(event.target.files[0]); + const vttConverter = new VTTConverter(event.target.files[0]); + let track = document.createElement("track"); + track.id= "my-sub-track"; + track.kind = "captions"; + track.label = "Custom subtitle"; + track.srclang = "en"; + //track.src = "captions/sintel-en.vtt"; + let video = document.getElementById("myVideo"); + video.appendChild(track); + vttConverter + .getURL() + .then(function(url) { // Its a valid url that can be used further + var track = document.getElementById('my-sub-track'); // Track element (which is child of a video element) + var video = document.getElementById('myVideo'); // Main video element + track.src = url; // Set the converted URL to track's source + video.textTracks[0].mode = 'show'; // Start showing subtitle to your track + }) + .catch(function(err) { + console.error(err); + }) + + }; + + function startVideo() { setTimer(true); @@ -75,6 +112,14 @@ function VideoDetail ({ video, handleVideoSelect, authTokens, setHistoryPager } } +
+
+ +
+
); }; From 98a825db0a396025b5b3a018451af28e9f38b813 Mon Sep 17 00:00:00 2001 From: Nicolas DEROUINEAU Date: Thu, 20 Aug 2020 11:24:25 +0200 Subject: [PATCH 2/5] use customsub tag for debug --- docker-compose-prod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index 209ab15c..e66045af 100644 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -15,7 +15,7 @@ services: volumes: - dbvolume:/var/lib/postgresql/data/ web: - image: webmultimedia/http-streaming-server:master + image: webmultimedia/http-streaming-server:customsub build: context: . dockerfile: ./backend/Dockerfile.prod From c07defa4d0272c333b102240ff5927587b280b79 Mon Sep 17 00:00:00 2001 From: Nicolas DEROUINEAU Date: Thu, 20 Aug 2020 12:10:59 +0200 Subject: [PATCH 3/5] code cleaning --- frontend/src/components/Video/VideoDetail.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/frontend/src/components/Video/VideoDetail.js b/frontend/src/components/Video/VideoDetail.js index 2cca937d..ee526232 100644 --- a/frontend/src/components/Video/VideoDetail.js +++ b/frontend/src/components/Video/VideoDetail.js @@ -5,15 +5,10 @@ import './VideoDetail.css' import VTTConverter from 'srt-webvtt'; - - - - function VideoDetail ({ video, handleVideoSelect, authTokens, setHistoryPager }) { const [timer, setTimer] = useState(false); const [count, setCount] = useState(0); - //const [customsub, setCustomSub] = useState(''); async function HandleNextEpisode(handleVideoSelect, nextEpisodeID) { const video = await client.getVideoById(nextEpisodeID); @@ -23,19 +18,16 @@ function VideoDetail ({ video, handleVideoSelect, authTokens, setHistoryPager } const handleChange = event => { let customsub = event.target.value; var ext = customsub.substr(customsub.lastIndexOf('.') + 1); - console.log(ext); if(ext != "srt"){ alert("Only .srt files are supported \n"); return; } - console.log(event.target.files[0]); const vttConverter = new VTTConverter(event.target.files[0]); let track = document.createElement("track"); track.id= "my-sub-track"; track.kind = "captions"; track.label = "Custom subtitle"; track.srclang = "en"; - //track.src = "captions/sintel-en.vtt"; let video = document.getElementById("myVideo"); video.appendChild(track); vttConverter From 9fc8b8dc1a30be84ad127a07222c66a53d2f2a09 Mon Sep 17 00:00:00 2001 From: Nicolas DEROUINEAU Date: Sun, 23 Aug 2020 17:24:18 +0200 Subject: [PATCH 4/5] Use dedicated Subtitle Form component --- .../src/components/Video/SubtitlesForm.js | 60 +++++++++++++++++++ frontend/src/components/Video/VideoDetail.js | 43 ++----------- 2 files changed, 65 insertions(+), 38 deletions(-) create mode 100644 frontend/src/components/Video/SubtitlesForm.js diff --git a/frontend/src/components/Video/SubtitlesForm.js b/frontend/src/components/Video/SubtitlesForm.js new file mode 100644 index 00000000..08099284 --- /dev/null +++ b/frontend/src/components/Video/SubtitlesForm.js @@ -0,0 +1,60 @@ + +import React, {useEffect, useState} from 'react'; + +import VTTConverter from 'srt-webvtt'; + + +function SubtitleForm (){ + + const [selectedFiles, setSelectedFiles] = useState(undefined); + const [subtitleName, setSubtitleName] = useState("Custom Subtitle"); + + const handleSubtitleChange = event => { + let customsub = event.target.value; + var ext = customsub.substr(customsub.lastIndexOf('.') + 1); + if(ext != "srt"){ + alert("Only .srt files are supported \n"); + return; + } + const vttConverter = new VTTConverter(event.target.files[0]); + let track = document.createElement("track"); + track.id= "my-sub-track"; + track.kind = "captions"; + track.label = subtitleName; + let videoElement = document.getElementById("myVideo"); + videoElement.appendChild(track); + vttConverter + .getURL() + .then(function(url) { // Its a valid url that can be used further + track.src = url; // Set the converted URL to track's source + videoElement.textTracks[0].mode = 'show'; // Start showing subtitle to your track + }) + .catch(function(err) { + alert(err); + }) + setSelectedFiles(event.target.files); + }; + + const handleSubtitleNameChange = event => { + setSubtitleName(event.target.value); + }; + + const handleSubmit = event => { + event.preventDefault() + }; + + return ( +
+
{ e.preventDefault(); }} > + +
+
+ ) +} + +export default SubtitleForm; + diff --git a/frontend/src/components/Video/VideoDetail.js b/frontend/src/components/Video/VideoDetail.js index ee526232..208de737 100644 --- a/frontend/src/components/Video/VideoDetail.js +++ b/frontend/src/components/Video/VideoDetail.js @@ -2,7 +2,8 @@ import React, {useEffect, useState} from 'react'; import { client } from '../../api/djangoAPI'; import Button from "@material-ui/core/Button"; import './VideoDetail.css' -import VTTConverter from 'srt-webvtt'; +import SubtitleForm from "./SubtitlesForm" + function VideoDetail ({ video, handleVideoSelect, authTokens, setHistoryPager }) { @@ -15,35 +16,6 @@ function VideoDetail ({ video, handleVideoSelect, authTokens, setHistoryPager } handleVideoSelect(video); } - const handleChange = event => { - let customsub = event.target.value; - var ext = customsub.substr(customsub.lastIndexOf('.') + 1); - if(ext != "srt"){ - alert("Only .srt files are supported \n"); - return; - } - const vttConverter = new VTTConverter(event.target.files[0]); - let track = document.createElement("track"); - track.id= "my-sub-track"; - track.kind = "captions"; - track.label = "Custom subtitle"; - track.srclang = "en"; - let video = document.getElementById("myVideo"); - video.appendChild(track); - vttConverter - .getURL() - .then(function(url) { // Its a valid url that can be used further - var track = document.getElementById('my-sub-track'); // Track element (which is child of a video element) - var video = document.getElementById('myVideo'); // Main video element - track.src = url; // Set the converted URL to track's source - video.textTracks[0].mode = 'show'; // Start showing subtitle to your track - }) - .catch(function(err) { - console.error(err); - }) - - }; - function startVideo() { setTimer(true); @@ -104,14 +76,9 @@ function VideoDetail ({ video, handleVideoSelect, authTokens, setHistoryPager } } -
-
- -
-
+ + ); }; From 63a01480854a913fd950e58d9367b61ba77dd076 Mon Sep 17 00:00:00 2001 From: Nicolas DEROUINEAU Date: Wed, 26 Aug 2020 10:36:36 +0200 Subject: [PATCH 5/5] Prepare for merge --- docker-compose-prod.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index e66045af..d96d0256 100644 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -15,7 +15,7 @@ services: volumes: - dbvolume:/var/lib/postgresql/data/ web: - image: webmultimedia/http-streaming-server:customsub + image: webmultimedia/http-streaming-server:master build: context: . dockerfile: ./backend/Dockerfile.prod @@ -27,7 +27,6 @@ services: environment: - DEPLOY_ENV=production volumes: - - ./backend/:/usr/src/app/ - ./Videos/:/usr/src/app/Videos - /static/ - ipython:/root/.ipython