Flare-k

[Add] Recording and User image

1 import "../scss/styles.scss"; 1 import "../scss/styles.scss";
2 import "./videoPlayer"; 2 import "./videoPlayer";
3 +import "./videoRecorder";
......
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 +}
1 +.record-container {
2 + width: 100%;
3 + max-width: 320px;
4 + margin-bottom: 50px;
5 + video {
6 + background-color: $black;
7 + width: 100%;
8 + margin-bottom: 20px;
9 + }
10 +}
...@@ -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
......