🚀 Initial commit!

This commit is contained in:
rzmk 2022-11-22 11:25:38 -05:00
parent d8079e5421
commit cccf993a91
13 changed files with 1124 additions and 100 deletions

View file

@ -1,70 +1,21 @@
# Getting Started with Create React App
# Custom YouTube Subtitles
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
A website showcasing the ability to overlay custom subtitles for multiple YouTube videos using `.vtt` files.
## Available Scripts
![Demo](demo.gif)
In the project directory, you can run:
## How to Use
### `npm start`
1. Create captions for a YouTube video and save them as a `.vtt` file.
1. One method is using online caption-making software or Adobe Premiere Pro, exporting as a `.srt` file and then converting it to a `.vtt` file using an online conversion tool.
2. Rename the `.vtt` file to the video ID of the YouTube video.
1. For example if the YouTube video you're captioning is at [https://www.youtube.com/watch?v=-JTq1BFBwmo](https://www.youtube.com/watch?v=-JTq1BFBwmo) then the video ID is after the `=` symbol as `-JTq1BFBwmo`.
3. Add the `.vtt` file to `/src/captions/` and add the video ID to the array in `captions.js`.
4. Build the React application and deploy it.
1. You can use tools like [Vercel](https://vercel.com/) or [Netlify](https://www.netlify.com/) to automate this process.
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
## Conclusions
The page will reload when you make changes.\
You may also see any lint errors in the console.
This was helpful in understanding how to work with the [Video.js](https://videojs.com/) player and adding my own custom subtitles.
### `npm test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
### Analyzing the Bundle Size
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
### Making a Progressive Web App
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
### Advanced Configuration
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
### Deployment
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
### `npm run build` fails to minify
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
There is a possible issue where adding more caption entries may result in a single row of selectable videos to become too crowded/long, so this could be fixed. Though I don't plan to as this isn't a production application and there are web applications such as [Captionfy](https://www.captionfy.com/) that are more fully featured.

BIN
demo.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 MiB

421
package-lock.json generated
View file

@ -14,6 +14,8 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"video.js": "^7.20.3",
"videojs-youtube": "^2.6.1",
"web-vitals": "^2.1.4"
}
},
@ -4396,6 +4398,52 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@videojs/http-streaming": {
"version": "2.14.3",
"resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.14.3.tgz",
"integrity": "sha512-2tFwxCaNbcEZzQugWf8EERwNMyNtspfHnvxRGRABQs09W/5SqmkWFuGWfUAm4wQKlXGfdPyAJ1338ASl459xAA==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "3.0.5",
"aes-decrypter": "3.1.3",
"global": "^4.4.0",
"m3u8-parser": "4.7.1",
"mpd-parser": "0.21.1",
"mux.js": "6.0.1",
"video.js": "^6 || ^7"
},
"engines": {
"node": ">=8",
"npm": ">=5"
},
"peerDependencies": {
"video.js": "^6 || ^7"
}
},
"node_modules/@videojs/vhs-utils": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz",
"integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"global": "^4.4.0",
"url-toolkit": "^2.2.1"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/@videojs/xhr": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.6.0.tgz",
"integrity": "sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==",
"dependencies": {
"@babel/runtime": "^7.5.5",
"global": "~4.4.0",
"is-function": "^1.0.1"
}
},
"node_modules/@webassemblyjs/ast": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
@ -4527,6 +4575,14 @@
"@xtuc/long": "4.2.2"
}
},
"node_modules/@xmldom/xmldom": {
"version": "0.7.9",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.9.tgz",
"integrity": "sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@ -4650,6 +4706,17 @@
"node": ">=8.9"
}
},
"node_modules/aes-decrypter": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-3.1.3.tgz",
"integrity": "sha512-VkG9g4BbhMBy+N5/XodDeV6F02chEk9IpgRTq/0bS80y4dzy79VH2Gtms02VXomf3HmyRe3yyJYkJ990ns+d6A==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"global": "^4.4.0",
"pkcs7": "^1.0.4"
}
},
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@ -6599,6 +6666,11 @@
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
@ -8381,6 +8453,15 @@
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
},
"node_modules/global": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"dependencies": {
"min-document": "^2.19.0",
"process": "^0.11.10"
}
},
"node_modules/global-modules": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
@ -8892,6 +8973,11 @@
"node": ">=8"
}
},
"node_modules/individual": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/individual/-/individual-2.0.0.tgz",
"integrity": "sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g=="
},
"node_modules/inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -9055,6 +9141,11 @@
"node": ">=8"
}
},
"node_modules/is-function": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz",
"integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="
},
"node_modules/is-generator-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
@ -11510,6 +11601,11 @@
"node": ">=4.0"
}
},
"node_modules/keycode": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.1.tgz",
"integrity": "sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg=="
},
"node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@ -11683,6 +11779,16 @@
"lz-string": "bin/bin.js"
}
},
"node_modules/m3u8-parser": {
"version": "4.7.1",
"resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-4.7.1.tgz",
"integrity": "sha512-pbrQwiMiq+MmI9bl7UjtPT3AK603PV9bogNlr83uC+X9IoxqL5E4k7kU7fMQ0dpRgxgeSMygqUa0IMLQNXLBNA==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"global": "^4.4.0"
}
},
"node_modules/magic-string": {
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
@ -11821,6 +11927,14 @@
"node": ">=6"
}
},
"node_modules/min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==",
"dependencies": {
"dom-walk": "^0.1.0"
}
},
"node_modules/min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
@ -11931,6 +12045,20 @@
"mkdirp": "bin/cmd.js"
}
},
"node_modules/mpd-parser": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.21.1.tgz",
"integrity": "sha512-BxlSXWbKE1n7eyEPBnTEkrzhS3PdmkkKdM1pgKbPnPOH0WFZIc0sPOWi7m0Uo3Wd2a4Or8Qf4ZbS7+ASqQ49fw==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"@xmldom/xmldom": "^0.7.2",
"global": "^4.4.0"
},
"bin": {
"mpd-to-m3u8-json": "bin/parse.js"
}
},
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -11948,6 +12076,22 @@
"multicast-dns": "cli.js"
}
},
"node_modules/mux.js": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/mux.js/-/mux.js-6.0.1.tgz",
"integrity": "sha512-22CHb59rH8pWGcPGW5Og7JngJ9s+z4XuSlYvnxhLuc58cA1WqGDQPzuG8I+sPm1/p0CdgpzVTaKW408k5DNn8w==",
"dependencies": {
"@babel/runtime": "^7.11.2",
"global": "^4.4.0"
},
"bin": {
"muxjs-transmux": "bin/transmux.js"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
@ -12465,6 +12609,17 @@
"node": ">= 6"
}
},
"node_modules/pkcs7": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/pkcs7/-/pkcs7-1.0.4.tgz",
"integrity": "sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==",
"dependencies": {
"@babel/runtime": "^7.5.5"
},
"bin": {
"pkcs7": "bin/cli.js"
}
},
"node_modules/pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@ -13807,6 +13962,14 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -14658,6 +14821,14 @@
"queue-microtask": "^1.2.2"
}
},
"node_modules/rust-result": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/rust-result/-/rust-result-1.0.0.tgz",
"integrity": "sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==",
"dependencies": {
"individual": "^2.0.0"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@ -14677,6 +14848,14 @@
}
]
},
"node_modules/safe-json-parse": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-4.0.0.tgz",
"integrity": "sha512-RjZPPHugjK0TOzFrLZ8inw44s9bKox99/0AZW9o/BEQVrJfhI+fIHMErnPyRa89/yRXUUr93q+tiN6zhoVV4wQ==",
"dependencies": {
"rust-result": "^1.0.0"
}
},
"node_modules/safe-regex-test": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
@ -15985,6 +16164,11 @@
"requires-port": "^1.0.0"
}
},
"node_modules/url-toolkit": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.2.5.tgz",
"integrity": "sha512-mtN6xk+Nac+oyJ/PrI7tzfmomRVNFIWKUbG8jdYFt52hxbiReFAXIjYskvu64/dvuW71IcB7lV8l0HvZMac6Jg=="
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@ -16046,6 +16230,50 @@
"node": ">= 0.8"
}
},
"node_modules/video.js": {
"version": "7.20.3",
"resolved": "https://registry.npmjs.org/video.js/-/video.js-7.20.3.tgz",
"integrity": "sha512-JMspxaK74LdfWcv69XWhX4rILywz/eInOVPdKefpQiZJSMD5O8xXYueqACP2Q5yqKstycgmmEKlJzZ+kVmDciw==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/http-streaming": "2.14.3",
"@videojs/vhs-utils": "^3.0.4",
"@videojs/xhr": "2.6.0",
"aes-decrypter": "3.1.3",
"global": "^4.4.0",
"keycode": "^2.2.0",
"m3u8-parser": "4.7.1",
"mpd-parser": "0.21.1",
"mux.js": "6.0.1",
"safe-json-parse": "4.0.0",
"videojs-font": "3.2.0",
"videojs-vtt.js": "^0.15.4"
}
},
"node_modules/videojs-font": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz",
"integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA=="
},
"node_modules/videojs-vtt.js": {
"version": "0.15.4",
"resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.4.tgz",
"integrity": "sha512-r6IhM325fcLb1D6pgsMkTQT1PpFdUdYZa1iqk7wJEu+QlibBwATPfPc9Bg8Jiym0GE5yP1AG2rMLu+QMVWkYtA==",
"dependencies": {
"global": "^4.3.1"
}
},
"node_modules/videojs-youtube": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/videojs-youtube/-/videojs-youtube-2.6.1.tgz",
"integrity": "sha512-qvwrkgXixbX8xzdkBa7o5r9KUITRISAy4bbyrpBgub3m0mhwz6WLXDIwJZ6/w4Z/JijWjLQqlg8W1jYhCEgHZw==",
"dependencies": {
"video.js": "^5.6.0 || ^6.2.8 || ^7.0.2"
},
"peerDependencies": {
"video.js": "5.x || 6.x || 7.x"
}
},
"node_modules/w3c-hr-time": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
@ -20024,6 +20252,41 @@
"eslint-visitor-keys": "^3.3.0"
}
},
"@videojs/http-streaming": {
"version": "2.14.3",
"resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-2.14.3.tgz",
"integrity": "sha512-2tFwxCaNbcEZzQugWf8EERwNMyNtspfHnvxRGRABQs09W/5SqmkWFuGWfUAm4wQKlXGfdPyAJ1338ASl459xAA==",
"requires": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "3.0.5",
"aes-decrypter": "3.1.3",
"global": "^4.4.0",
"m3u8-parser": "4.7.1",
"mpd-parser": "0.21.1",
"mux.js": "6.0.1",
"video.js": "^6 || ^7"
}
},
"@videojs/vhs-utils": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz",
"integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==",
"requires": {
"@babel/runtime": "^7.12.5",
"global": "^4.4.0",
"url-toolkit": "^2.2.1"
}
},
"@videojs/xhr": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/@videojs/xhr/-/xhr-2.6.0.tgz",
"integrity": "sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==",
"requires": {
"@babel/runtime": "^7.5.5",
"global": "~4.4.0",
"is-function": "^1.0.1"
}
},
"@webassemblyjs/ast": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz",
@ -20155,6 +20418,11 @@
"@xtuc/long": "4.2.2"
}
},
"@xmldom/xmldom": {
"version": "0.7.9",
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.9.tgz",
"integrity": "sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA=="
},
"@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@ -20248,6 +20516,17 @@
"regex-parser": "^2.2.11"
}
},
"aes-decrypter": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-3.1.3.tgz",
"integrity": "sha512-VkG9g4BbhMBy+N5/XodDeV6F02chEk9IpgRTq/0bS80y4dzy79VH2Gtms02VXomf3HmyRe3yyJYkJ990ns+d6A==",
"requires": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"global": "^4.4.0",
"pkcs7": "^1.0.4"
}
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@ -21671,6 +21950,11 @@
"entities": "^2.0.0"
}
},
"dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
"domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
@ -22969,6 +23253,15 @@
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
},
"global": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz",
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"requires": {
"min-document": "^2.19.0",
"process": "^0.11.10"
}
},
"global-modules": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
@ -23335,6 +23628,11 @@
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="
},
"individual": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/individual/-/individual-2.0.0.tgz",
"integrity": "sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g=="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -23444,6 +23742,11 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
},
"is-function": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz",
"integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ=="
},
"is-generator-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
@ -25223,6 +25526,11 @@
"object.assign": "^4.1.3"
}
},
"keycode": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.1.tgz",
"integrity": "sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg=="
},
"kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@ -25357,6 +25665,16 @@
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz",
"integrity": "sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ=="
},
"m3u8-parser": {
"version": "4.7.1",
"resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-4.7.1.tgz",
"integrity": "sha512-pbrQwiMiq+MmI9bl7UjtPT3AK603PV9bogNlr83uC+X9IoxqL5E4k7kU7fMQ0dpRgxgeSMygqUa0IMLQNXLBNA==",
"requires": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"global": "^4.4.0"
}
},
"magic-string": {
"version": "0.25.9",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz",
@ -25458,6 +25776,14 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
},
"min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==",
"requires": {
"dom-walk": "^0.1.0"
}
},
"min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
@ -25534,6 +25860,17 @@
"minimist": "^1.2.6"
}
},
"mpd-parser": {
"version": "0.21.1",
"resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.21.1.tgz",
"integrity": "sha512-BxlSXWbKE1n7eyEPBnTEkrzhS3PdmkkKdM1pgKbPnPOH0WFZIc0sPOWi7m0Uo3Wd2a4Or8Qf4ZbS7+ASqQ49fw==",
"requires": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"@xmldom/xmldom": "^0.7.2",
"global": "^4.4.0"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@ -25548,6 +25885,15 @@
"thunky": "^1.0.2"
}
},
"mux.js": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/mux.js/-/mux.js-6.0.1.tgz",
"integrity": "sha512-22CHb59rH8pWGcPGW5Og7JngJ9s+z4XuSlYvnxhLuc58cA1WqGDQPzuG8I+sPm1/p0CdgpzVTaKW408k5DNn8w==",
"requires": {
"@babel/runtime": "^7.11.2",
"global": "^4.4.0"
}
},
"nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
@ -25912,6 +26258,14 @@
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
"integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ=="
},
"pkcs7": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/pkcs7/-/pkcs7-1.0.4.tgz",
"integrity": "sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==",
"requires": {
"@babel/runtime": "^7.5.5"
}
},
"pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
@ -26692,6 +27046,11 @@
}
}
},
"process": {
"version": "0.11.10",
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="
},
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -27311,11 +27670,27 @@
"queue-microtask": "^1.2.2"
}
},
"rust-result": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/rust-result/-/rust-result-1.0.0.tgz",
"integrity": "sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==",
"requires": {
"individual": "^2.0.0"
}
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"safe-json-parse": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-4.0.0.tgz",
"integrity": "sha512-RjZPPHugjK0TOzFrLZ8inw44s9bKox99/0AZW9o/BEQVrJfhI+fIHMErnPyRa89/yRXUUr93q+tiN6zhoVV4wQ==",
"requires": {
"rust-result": "^1.0.0"
}
},
"safe-regex-test": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
@ -28294,6 +28669,11 @@
"requires-port": "^1.0.0"
}
},
"url-toolkit": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.2.5.tgz",
"integrity": "sha512-mtN6xk+Nac+oyJ/PrI7tzfmomRVNFIWKUbG8jdYFt52hxbiReFAXIjYskvu64/dvuW71IcB7lV8l0HvZMac6Jg=="
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@ -28340,6 +28720,47 @@
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
},
"video.js": {
"version": "7.20.3",
"resolved": "https://registry.npmjs.org/video.js/-/video.js-7.20.3.tgz",
"integrity": "sha512-JMspxaK74LdfWcv69XWhX4rILywz/eInOVPdKefpQiZJSMD5O8xXYueqACP2Q5yqKstycgmmEKlJzZ+kVmDciw==",
"requires": {
"@babel/runtime": "^7.12.5",
"@videojs/http-streaming": "2.14.3",
"@videojs/vhs-utils": "^3.0.4",
"@videojs/xhr": "2.6.0",
"aes-decrypter": "3.1.3",
"global": "^4.4.0",
"keycode": "^2.2.0",
"m3u8-parser": "4.7.1",
"mpd-parser": "0.21.1",
"mux.js": "6.0.1",
"safe-json-parse": "4.0.0",
"videojs-font": "3.2.0",
"videojs-vtt.js": "^0.15.4"
}
},
"videojs-font": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.2.0.tgz",
"integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA=="
},
"videojs-vtt.js": {
"version": "0.15.4",
"resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.15.4.tgz",
"integrity": "sha512-r6IhM325fcLb1D6pgsMkTQT1PpFdUdYZa1iqk7wJEu+QlibBwATPfPc9Bg8Jiym0GE5yP1AG2rMLu+QMVWkYtA==",
"requires": {
"global": "^4.3.1"
}
},
"videojs-youtube": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/videojs-youtube/-/videojs-youtube-2.6.1.tgz",
"integrity": "sha512-qvwrkgXixbX8xzdkBa7o5r9KUITRISAy4bbyrpBgub3m0mhwz6WLXDIwJZ6/w4Z/JijWjLQqlg8W1jYhCEgHZw==",
"requires": {
"video.js": "^5.6.0 || ^6.2.8 || ^7.0.2"
}
},
"w3c-hr-time": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",

View file

@ -9,6 +9,8 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"video.js": "^7.20.3",
"videojs-youtube": "^2.6.1",
"web-vitals": "^2.1.4"
},
"scripts": {

1
public/dist/Youtube.min.js vendored Normal file

File diff suppressed because one or more lines are too long

26
public/dist/video.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,21 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Custom YouTube Subtitles</title>
<meta name="description" content="A React web application that displays YouTube videos with custom subtitles.">
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
<meta name="theme-color" content="#000000" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
@ -24,12 +25,12 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
@ -39,5 +40,6 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
</body>
</html>

View file

@ -1,23 +1,98 @@
import logo from './logo.svg';
import './App.css';
import "./App.css";
import videojs from "video.js";
import VideoPage from "./pages/VideoPage";
import { useEffect, useState } from "react";
import captions_list from "./captions/captions.js";
function App() {
const [currentID, setCurrentID] = useState("-JTq1BFBwmo");
useEffect(() => {
// Default video displaying first
fetch(
`https://noembed.com/embed?dataType=json&url=https://www.youtube.com/watch?v=-JTq1BFBwmo`
)
.then((res) => res.json())
.then((data) => {
document.querySelector("#title").textContent = data.title;
});
// Add info for each captioned video in the selection grid
captions_list.forEach((caption) => {
fetch(
`https://noembed.com/embed?dataType=json&url=https://www.youtube.com/watch?v=${caption}`
)
.then((res) => res.json())
.then((data) => {
document.querySelector(`#${caption}-title`).textContent = data.title;
document.querySelector(`#${caption}-thumbnail`).src =
data.thumbnail_url;
});
});
}, []);
const handleClick = (captionID) => {
if (currentID === captionID) {
return;
}
setCurrentID(captionID);
fetch(
`https://noembed.com/embed?dataType=json&url=https://www.youtube.com/watch?v=${captionID}`
)
.then((res) => res.json())
.then((data) => {
document.querySelector("#title").textContent = data.title;
});
if (videojs.getAllPlayers().length > 0) {
videojs.getAllPlayers().forEach((player) => {
player.src({
type: "video/youtube",
src: `https://www.youtube.com/watch?v=${captionID}`,
});
// Update video thumbnail
const thumbnail = document.querySelector(".vjs-poster");
thumbnail.style = `background-image: url(https://img.youtube.com/vi/${captionID}/0.jpg)`;
// Remove current text tracks
player.textTracks().removeTrack(player.textTracks()[0]);
// Add new text track
const track = player.addRemoteTextTrack(
{
kind: "captions",
src: require(`./captions/${captionID}.vtt`),
srclang: "en",
label: "English",
mode: "showing",
},
false
);
track.mode = "showing";
// Load player with new source
player.load();
});
}
};
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
<VideoPage />
<h1 style={{ marginTop: "2rem" }}>Select a Subtitled Video</h1>
<div class="grid container" style={{ margin: "auto" }}>
{captions_list.map((caption) => (
<div>
<article>
<div
style={{ margin: "-40px", cursor: "pointer" }}
onClick={() => handleClick(caption)}
>
<header
id={`${caption}-title`}
style={{ padding: "1rem" }}
></header>
<img id={`${caption}-thumbnail`} src="" alt="Thumbnail" />
</div>
</article>
</div>
))}
</div>
</div>
);
}

View file

@ -0,0 +1,134 @@
WEBVTT
1
00:00:00.120 --> 00:00:04.404
Let us talk about priori analysis
and posteriori testing.
2
00:00:04.404 --> 00:00:09.929
These are the two terms that are used
for algorithms and programs.
3
00:00:09.929 --> 00:00:13.733
Priori analysis is done over the algorithm
so priori analysis means
4
00:00:13.733 --> 00:00:17.937
we will do the analysis of an algorithm
by studying it in greater detail,
5
00:00:18.218 --> 00:00:23.343
knowing how it is working,
and we get some results.
6
00:00:23.343 --> 00:00:24.424
The result of analysis.
7
00:00:24.424 --> 00:00:28.628
What is that? We will find out the time
and the space consumed by an algorithm.
8
00:00:29.629 --> 00:00:32.192
The result of analysis.
9
00:00:32.192 --> 00:00:34.554
And testing is done on the program.
10
00:00:34.554 --> 00:00:38.358
So we run and execute the program
and check it so we will know the
11
00:00:38.358 --> 00:00:41.921
watch time it is taking: how much, how
many seconds, milliseconds it is taking
12
00:00:42.402 --> 00:00:45.605
and also the amount of memory it is
consuming
13
00:00:45.845 --> 00:00:49.649
in terms of bytes.
14
00:00:49.649 --> 00:00:52.652
So this is priori analysis done on
algorithms
15
00:00:53.012 --> 00:00:55.895
and posteriori testing
is done on programs.
16
00:00:57.337 --> 00:01:00.019
Now when priori analysis is done
over an algorithm
17
00:01:00.019 --> 00:01:04.344
we know well that algorithms are not
written in a particular language.
18
00:01:04.464 --> 00:01:07.707
So they are language independent
and also they are
19
00:01:07.947 --> 00:01:09.749
hardware independent.
20
00:01:09.749 --> 00:01:13.273
They are not meant for a particular
hardware. But if it is a program
21
00:01:13.513 --> 00:01:16.636
we write a program that is hardware
22
00:01:16.636 --> 00:01:19.439
specific, as well as language specific,
23
00:01:20.039 --> 00:01:23.963
and as well as operating system
specific, and environment specific also.
24
00:01:24.484 --> 00:01:29.008
So they are dependent on the hardware
as well as the programming language used.
25
00:01:30.610 --> 00:01:32.612
And here the result of this one is
26
00:01:32.612 --> 00:01:35.855
how we get the time and the space.
We don't get
27
00:01:35.895 --> 00:01:40.140
watch time, 3 minutes, 10 minutes, 5
seconds or milliseconds.
28
00:01:40.180 --> 00:01:46.065
No, we will get the time function
and we get the space function.

View file

@ -0,0 +1,371 @@
WEBVTT
1
00:00:00.900 --> 00:00:04.800
We're getting ready to move on
from the topic of functions.
2
00:00:04.800 --> 00:00:08.233
But before we do, let's just make sure
that you're familiar with these
3
00:00:08.233 --> 00:00:13.633
very useful functions that you will see
throughout your mathematical study.
4
00:00:13.733 --> 00:00:17.066
So I want to talk to you first
about the floor and ceiling functions.
5
00:00:17.100 --> 00:00:18.633
Again, I am quite certain
6
00:00:18.633 --> 00:00:22.266
you've probably seen this before, but
if not, they're pretty straightforward.
7
00:00:22.766 --> 00:00:26.633
The floor function
essentially tells us to round down
8
00:00:27.000 --> 00:00:29.833
to the largest integer
less than or equal to x.
9
00:00:30.133 --> 00:00:31.300
And it's easy to remember
10
00:00:31.300 --> 00:00:35.166
this is the floor function because
our brackets essentially have a floor.
11
00:00:35.966 --> 00:00:39.566
And the ceiling function is similar
but asks us to round up
12
00:00:40.033 --> 00:00:44.433
to the nearest integer greater
than or equal to x.
13
00:00:45.033 --> 00:00:46.800
So let's take a look at an example.
14
00:00:46.800 --> 00:00:51.366
I've got 2.2, and if I'm thinking
about 2.2 on a number line,
15
00:00:52.333 --> 00:00:53.500
then I'm thinking about
16
00:00:53.500 --> 00:00:57.066
2, and then 3, and 2.2
17
00:00:57.533 --> 00:00:59.533
is right around somewhere in there.
18
00:01:01.000 --> 00:01:04.800
And if I'm rounding or
if I'm using the ceiling function,
19
00:01:05.466 --> 00:01:10.200
the ceiling function says
round up to the next integer
20
00:01:10.933 --> 00:01:14.000
and the floor function says round
21
00:01:14.000 --> 00:01:17.833
down to the next integer.
22
00:01:17.966 --> 00:01:21.633
Same thing happens for my -3.7.
23
00:01:22.100 --> 00:01:25.033
But just be careful how
you put these numbers on the number line.
24
00:01:25.600 --> 00:01:27.500
Remember, 0 is over here somewhere.
25
00:01:27.500 --> 00:01:28.733
This would be -3,
26
00:01:28.733 --> 00:01:33.866
this would be -4, and -3.7 somewhere in here.
27
00:01:34.633 --> 00:01:36.700
And then if I'm rounding up
28
00:01:37.266 --> 00:01:40.166
for my ceiling function,
I end up at -3.
29
00:01:40.500 --> 00:01:44.533
If I'm rounding down to my floor function,
I end up at -4.
30
00:01:45.166 --> 00:01:47.633
So just be very careful
with your negatives.
31
00:01:48.966 --> 00:01:50.166
And I am certain,
32
00:01:50.166 --> 00:01:53.300
absolutely certain that you have
had the factorial function before.
33
00:01:53.766 --> 00:01:58.400
Factorial function
is essentially denoted by f(n) = n!
34
00:01:58.400 --> 00:02:02.400
That's the exclamation point,
which means factorial.
35
00:02:02.900 --> 00:02:06.866
And it is the product of the first
n positive integers
36
00:02:06.966 --> 00:02:09.233
when n is a non-negative integer.
37
00:02:09.833 --> 00:02:12.633
So I give you an f(n) here
38
00:02:12.633 --> 00:02:15.200
but let's say f(4).
39
00:02:15.200 --> 00:02:19.033
I would take
4 times 3 times 2 times 1.
40
00:02:19.033 --> 00:02:22.366
That would be my factorial function.
41
00:02:22.366 --> 00:02:24.300
4 times 3 times 2 times 1.
42
00:02:24.300 --> 00:02:27.700
So again,
symbolically, it's n, n - 1,
43
00:02:27.700 --> 00:02:31.600
n - 2, all the way down
until you get to 1.
44
00:02:32.700 --> 00:02:35.266
Stirling's formula is fantastic.
45
00:02:36.033 --> 00:02:39.366
We're not going to use it a ton right now,
but this is a way
46
00:02:39.666 --> 00:02:44.100
because that factorial function
gets very large very quickly.
47
00:02:45.000 --> 00:02:49.100
This is an approximation that we can find
48
00:02:49.400 --> 00:02:52.400
of the product of the numbers
49
00:02:52.833 --> 00:02:54.966
of n!.
50
00:02:55.500 --> 00:02:58.100
Here's just one more
example for you to try.
51
00:02:59.133 --> 00:03:03.500
Our function is the floor function
of x squared divided by two and we're
52
00:03:03.500 --> 00:03:07.800
trying to find f(S) for the set of S,
53
00:03:07.800 --> 00:03:10.500
which includes 0, 1, 2, and 3.
54
00:03:10.833 --> 00:03:13.466
So if you'd like, go ahead and press pause
and try it yourself
55
00:03:13.500 --> 00:03:15.400
before I go through the answer.
56
00:03:15.400 --> 00:03:18.000
Otherwise, we're going to get started.
57
00:03:18.000 --> 00:03:21.000
So if I'm finding f(0),
58
00:03:22.266 --> 00:03:26.333
that tells me 0 squared
divided by 2 and the floor
59
00:03:26.333 --> 00:03:30.333
function of that 0 squared is 0
divided by 2 is 0.
60
00:03:30.900 --> 00:03:34.533
And the floor of 0 would
of course be 0.
61
00:03:35.033 --> 00:03:36.800
If I'm looking at f(1),
62
00:03:38.000 --> 00:03:39.900
f(1) would be 1
63
00:03:39.900 --> 00:03:43.300
squared over 2 and the floor function
64
00:03:44.166 --> 00:03:45.566
1 squared is 1.
65
00:03:46.500 --> 00:03:50.466
1 divided by 2,
that just gives me one half.
66
00:03:50.466 --> 00:03:52.766
So what is the floor function of one half?
67
00:03:53.533 --> 00:03:57.000
That is also 0.
68
00:03:57.000 --> 00:03:59.633
Let's do f(2).
69
00:03:59.633 --> 00:04:02.800
f(2) is the floor function
of 2 squared
70
00:04:04.133 --> 00:04:05.500
over 2.
71
00:04:05.833 --> 00:04:10.000
Oops, floor function
of 2 squared over 2.
72
00:04:10.000 --> 00:04:14.500
Which is...
2 squared is 4, divided by 2
73
00:04:15.200 --> 00:04:18.300
And the floor function of 2
of course gives me 2.
74
00:04:19.666 --> 00:04:21.733
And my last one, f(3)
75
00:04:22.666 --> 00:04:26.800
tells me the floor of 3
squared over 2,
76
00:04:26.800 --> 00:04:29.766
which is the floor of 9 over 2.
77
00:04:30.600 --> 00:04:32.800
And the floor of 9 over 2,
which is basically
78
00:04:32.800 --> 00:04:35.733
4.5 is 4.
79
00:04:36.333 --> 00:04:40.933
So these would
be my solutions: 0, 0, 2, 4.
80
00:04:42.700 --> 00:04:43.366
Up next,
81
00:04:43.366 --> 00:04:47.166
we are going to switch gears
and talk a little bit about sequences.
82
00:04:47.166 --> 00:04:49.666
So it's an introduction to sequences.

3
src/captions/captions.js Normal file
View file

@ -0,0 +1,3 @@
// Export an array of caption names
const captions = ["-JTq1BFBwmo", "_a9veRNS78w"];
export default captions;

37
src/pages/VideoPage.js Normal file
View file

@ -0,0 +1,37 @@
import { useState } from "react";
import "videojs-youtube";
import "./video-js.min.css";
import captions from "../captions/-JTq1BFBwmo.vtt";
const VideoPage = () => {
const videoID = "-JTq1BFBwmo";
return (
<>
<main class="container">
<h1 id="title" style={{ marginTop: "2rem" }}>
Loading title...
</h1>
<video
id="vid1"
class="video-js vjs-default-skin vjs-big-play-centered"
controls
data-setup={`{ "fluid": true, "techOrder": ["youtube"], "sources": [{ "type": "video/youtube", "src": "https://www.youtube.com/watch?v=${videoID}"}] }`}
>
<track
kind="captions"
src={captions}
srclang="en"
label="English"
mode="showing"
></track>
</video>
</main>
<script src={"%PUBLIC_URL%/dist/video.min.js"}></script>
<script src={"%PUBLIC_URL%/dist/Youtube.min.js"}></script>
</>
);
};
export default VideoPage;

1
src/pages/video-js.min.css vendored Normal file

File diff suppressed because one or more lines are too long