Showing
9 changed files
with
100 additions
and
5 deletions
assets/js/videoRecorder.js
0 → 100644
| 1 | +const recorderContainer = document.getElementById("jsRecordContainer"); | ||
| 2 | +const recordBtn = document.getElementById("jsRecordBtn"); | ||
| 3 | +const videoPreview = document.getElementById("jsVideoPreview"); | ||
| 4 | +// media devices navigator mdn -> video API | ||
| 5 | + | ||
| 6 | +let streamObject; | ||
| 7 | +let videoRecorder; | ||
| 8 | +const handleVideoData = (event) => { | ||
| 9 | + const { data: videoFile } = event; | ||
| 10 | + const link = document.createElement("a"); | ||
| 11 | + link.href = URL.createObjectURL(videoFile); | ||
| 12 | + link.download = "recorded.webm"; | ||
| 13 | + document.body.appendChild(link); | ||
| 14 | + link.click(); | ||
| 15 | +}; | ||
| 16 | + | ||
| 17 | +const stopRecording = () => { | ||
| 18 | + videoRecorder.stop(); | ||
| 19 | + recordBtn.removeEventListener("click", stopRecording); | ||
| 20 | + recordBtn.addEventListener("click", getVideo); | ||
| 21 | + recordBtn.innerHTML = "Start recording"; | ||
| 22 | +}; | ||
| 23 | +const startRecording = () => { | ||
| 24 | + videoRecorder = new MediaRecorder(streamObject); | ||
| 25 | + videoRecorder.start(); | ||
| 26 | + videoRecorder.addEventListener("dataavailable", handleVideoData); | ||
| 27 | + recordBtn.addEventListener("click", stopRecording); | ||
| 28 | +}; | ||
| 29 | +const getVideo = async () => { | ||
| 30 | + try { | ||
| 31 | + const stream = await navigator.mediaDevices.getUserMedia({ | ||
| 32 | + audio: true, | ||
| 33 | + video: { width: 1280, height: 720 }, | ||
| 34 | + }); | ||
| 35 | + videoPreview.srcObject = stream; | ||
| 36 | + videoPreview.play(); | ||
| 37 | + videoPreview.muted = true; | ||
| 38 | + recordBtn.innerHTML = "Stop recording."; | ||
| 39 | + streamObject = stream; | ||
| 40 | + startRecording(); | ||
| 41 | + } catch (error) { | ||
| 42 | + recordBtn.innerHTML = "Sorry, You can't recording."; | ||
| 43 | + } finally { | ||
| 44 | + recordBtn.removeEventListener("click", getVideo); | ||
| 45 | + } | ||
| 46 | +}; | ||
| 47 | + | ||
| 48 | +function init() { | ||
| 49 | + recordBtn.addEventListener("click", getVideo); | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +if (recorderContainer) { | ||
| 53 | + init(); | ||
| 54 | +} |
assets/scss/partials/videoRecorder.scss
0 → 100644
| ... | @@ -9,6 +9,7 @@ | ... | @@ -9,6 +9,7 @@ |
| 9 | @import "partials/socialLogin.scss"; | 9 | @import "partials/socialLogin.scss"; |
| 10 | @import "partials/videoBlock.scss"; | 10 | @import "partials/videoBlock.scss"; |
| 11 | @import "partials/videoPlayer.scss"; | 11 | @import "partials/videoPlayer.scss"; |
| 12 | +@import "partials/videoRecorder.scss"; | ||
| 12 | 13 | ||
| 13 | @import "pages/home.scss"; | 14 | @import "pages/home.scss"; |
| 14 | @import "pages/videoDetail.scss"; | 15 | @import "pages/videoDetail.scss"; | ... | ... |
| ... | @@ -118,8 +118,14 @@ export const logout = (req, res) => { | ... | @@ -118,8 +118,14 @@ export const logout = (req, res) => { |
| 118 | res.redirect(routes.home); | 118 | res.redirect(routes.home); |
| 119 | }; | 119 | }; |
| 120 | 120 | ||
| 121 | -export const getMe = (req, res) => | 121 | +export const getMe = async (req, res) => { |
| 122 | - res.render("userDetail", { pageTitle: "User Detail", user: req.user }); | 122 | + try { |
| 123 | + const user = await User.findById(req.user.id).populate("videos"); | ||
| 124 | + res.render("userDetail", { pageTitle: "User Detail", user }); | ||
| 125 | + } catch (error) { | ||
| 126 | + res.redirect(routes.home); | ||
| 127 | + } | ||
| 128 | +}; | ||
| 123 | // req.user -> 로그인된 유저 | 129 | // req.user -> 로그인된 유저 |
| 124 | // export const users = (req, res) => res.render("users", { pageTitle: "Users" }); | 130 | // export const users = (req, res) => res.render("users", { pageTitle: "Users" }); |
| 125 | 131 | ... | ... |
| ... | @@ -94,7 +94,7 @@ | ... | @@ -94,7 +94,7 @@ |
| 94 | /***/ (function(module, __webpack_exports__, __webpack_require__) { | 94 | /***/ (function(module, __webpack_exports__, __webpack_require__) { |
| 95 | 95 | ||
| 96 | "use strict"; | 96 | "use strict"; |
| 97 | -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _scss_styles_scss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scss/styles.scss */ \"./assets/scss/styles.scss\");\n/* harmony import */ var _scss_styles_scss__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_scss_styles_scss__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _videoPlayer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./videoPlayer */ \"./assets/js/videoPlayer.js\");\n/* harmony import */ var _videoPlayer__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_videoPlayer__WEBPACK_IMPORTED_MODULE_1__);\n\n\n\n\n//# sourceURL=webpack:///./assets/js/main.js?"); | 97 | +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _scss_styles_scss__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scss/styles.scss */ \"./assets/scss/styles.scss\");\n/* harmony import */ var _scss_styles_scss__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_scss_styles_scss__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _videoPlayer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./videoPlayer */ \"./assets/js/videoPlayer.js\");\n/* harmony import */ var _videoPlayer__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_videoPlayer__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _videoRecorder__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./videoRecorder */ \"./assets/js/videoRecorder.js\");\n/* harmony import */ var _videoRecorder__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_videoRecorder__WEBPACK_IMPORTED_MODULE_2__);\n\n\n\n\n\n//# sourceURL=webpack:///./assets/js/main.js?"); |
| 98 | 98 | ||
| 99 | /***/ }), | 99 | /***/ }), |
| 100 | 100 | ||
| ... | @@ -109,6 +109,17 @@ eval("const videoContainer = document.getElementById(\"jsVideoPlayer\");\nconst | ... | @@ -109,6 +109,17 @@ eval("const videoContainer = document.getElementById(\"jsVideoPlayer\");\nconst |
| 109 | 109 | ||
| 110 | /***/ }), | 110 | /***/ }), |
| 111 | 111 | ||
| 112 | +/***/ "./assets/js/videoRecorder.js": | ||
| 113 | +/*!************************************!*\ | ||
| 114 | + !*** ./assets/js/videoRecorder.js ***! | ||
| 115 | + \************************************/ | ||
| 116 | +/*! no static exports found */ | ||
| 117 | +/***/ (function(module, exports) { | ||
| 118 | + | ||
| 119 | +eval("const recorderContainer = document.getElementById(\"jsRecordContainer\");\nconst recordBtn = document.getElementById(\"jsRecordBtn\");\nconst videoPreview = document.getElementById(\"jsVideoPreview\");\n// media devices navigator mdn -> video API\n\nlet streamObject;\nlet videoRecorder;\nconst handleVideoData = (event) => {\n const { data: videoFile } = event;\n const link = document.createElement(\"a\");\n link.href = URL.createObjectURL(videoFile);\n link.download = \"recorded.webm\";\n document.body.appendChild(link);\n link.click();\n};\n\nconst stopRecording = () => {\n videoRecorder.stop();\n recordBtn.removeEventListener(\"click\", stopRecording);\n recordBtn.addEventListener(\"click\", getVideo);\n recordBtn.innerHTML = \"Start recording\";\n};\nconst startRecording = () => {\n videoRecorder = new MediaRecorder(streamObject);\n videoRecorder.start();\n videoRecorder.addEventListener(\"dataavailable\", handleVideoData);\n recordBtn.addEventListener(\"click\", stopRecording);\n};\nconst getVideo = async () => {\n try {\n const stream = await navigator.mediaDevices.getUserMedia({\n audio: true,\n video: { width: 1280, height: 720 },\n });\n videoPreview.srcObject = stream;\n videoPreview.play();\n videoPreview.muted = true;\n recordBtn.innerHTML = \"Stop recording.\";\n streamObject = stream;\n startRecording();\n } catch (error) {\n recordBtn.innerHTML = \"Sorry, You can't recording.\";\n } finally {\n recordBtn.removeEventListener(\"click\", getVideo);\n }\n};\n\nfunction init() {\n recordBtn.addEventListener(\"click\", getVideo);\n}\n\nif (recorderContainer) {\n init();\n}\n\n\n//# sourceURL=webpack:///./assets/js/videoRecorder.js?"); | ||
| 120 | + | ||
| 121 | +/***/ }), | ||
| 122 | + | ||
| 112 | /***/ "./assets/scss/styles.scss": | 123 | /***/ "./assets/scss/styles.scss": |
| 113 | /*!*********************************!*\ | 124 | /*!*********************************!*\ |
| 114 | !*** ./assets/scss/styles.scss ***! | 125 | !*** ./assets/scss/styles.scss ***! | ... | ... |
| ... | @@ -492,6 +492,15 @@ input[type="submit"] { | ... | @@ -492,6 +492,15 @@ input[type="submit"] { |
| 492 | font-size: 25px; | 492 | font-size: 25px; |
| 493 | cursor: pointer; } | 493 | cursor: pointer; } |
| 494 | 494 | ||
| 495 | +.record-container { | ||
| 496 | + width: 100%; | ||
| 497 | + max-width: 320px; | ||
| 498 | + margin-bottom: 50px; } | ||
| 499 | + .record-container video { | ||
| 500 | + background-color: #444444; | ||
| 501 | + width: 100%; | ||
| 502 | + margin-bottom: 20px; } | ||
| 503 | + | ||
| 495 | .home-videos { | 504 | .home-videos { |
| 496 | display: grid; | 505 | display: grid; |
| 497 | grid-template-columns: repeat(6, minmax(150px, 1fr)); | 506 | grid-template-columns: repeat(6, minmax(150px, 1fr)); | ... | ... |
| ... | @@ -2,6 +2,9 @@ extends layouts/main | ... | @@ -2,6 +2,9 @@ extends layouts/main |
| 2 | 2 | ||
| 3 | block content | 3 | block content |
| 4 | .form-container | 4 | .form-container |
| 5 | + .record-container#jsRecordContainer | ||
| 6 | + video#jsVideoPreview | ||
| 7 | + button#jsRecordBtn Start Recording | ||
| 5 | form(action=`/videos${routes.upload}`, method="post", enctype="multipart/form-data") | 8 | form(action=`/videos${routes.upload}`, method="post", enctype="multipart/form-data") |
| 6 | div.fileUpload | 9 | div.fileUpload |
| 7 | label(for="file") Video File | 10 | label(for="file") Video File | ... | ... |
| ... | @@ -4,9 +4,9 @@ include mixins/videoBlock | ... | @@ -4,9 +4,9 @@ include mixins/videoBlock |
| 4 | block content | 4 | block content |
| 5 | .user-profile | 5 | .user-profile |
| 6 | .user-profile__header | 6 | .user-profile__header |
| 7 | - img.u-avatar(src=user.avatarUrl) | 7 | + img.u-avatar(src=user.avatarUrl.startsWith("http") ? user.avatarUrl : `/${user.avatarUrl}`) |
| 8 | h4.profile__username=user.name | 8 | h4.profile__username=user.name |
| 9 | - if user.id === loggedUser.id | 9 | + if loggedUser && loggedUser.id === user.id |
| 10 | .user-profile__btns | 10 | .user-profile__btns |
| 11 | a(href=`/users${routes.editProfile}`) | 11 | a(href=`/users${routes.editProfile}`) |
| 12 | button 🖌 Edit Profile | 12 | button 🖌 Edit Profile | ... | ... |
-
Please register or login to post a comment