Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video upload #24

Merged
merged 5 commits into from
Jan 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ style.min.css
node_modules

.env

uploads/
112 changes: 108 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
"test": "NODE_ENV=test mocha ./tests/* ",
"test:watch": "NODE_ENV=test mocha ./tests/* --watch",
"devbug": "elm-live src/elm/Main.elm --output=public/elm.js --dir=public --open --debug --pushstate & npm run css-watch",
"dev": "elm-live src/elm/Main.elm --output=public/elm.js --dir=public --open --pushstate & npm run css-watch",
"dev-front-end": "elm-live src/elm/Main.elm --output=public/elm.js --dir=public --open --pushstate & npm run css-watch",
"build": "npm run css-build; elm-make src/elm/Main.elm --output=public/elm.js --yes",
"css-watch": "postcss ./src/css/index.css --output ./public/style.min.css --watch --config ./postcss.config.js",
"css-build": "postcss ./src/css/index.css --output ./public/style.min.css --config ./postcss.config.js",
"dev-server": "NODE_ENV=development nodemon ./src/server/start",
"heroku-postbuild": "npm run build",
"start": "node ./src/server/start"
"start": "node ./src/server/start",
"dev": "npm run dev-server & npm run dev-front-end"
},
"repository": {
"type": "git",
Expand All @@ -38,8 +39,10 @@
"airtable": "^0.5.2",
"autoprefixer": "^7.1.6",
"body-parser": "^1.18.2",
"cloudinary": "^1.9.1",
"elm": "^0.18.0",
"express": "^4.16.2",
"multer": "^1.3.0",
"postcss-clean": "^1.1.0",
"postcss-cli": "^4.1.1",
"postcss-custom-media": "^6.0.0",
Expand Down
10 changes: 7 additions & 3 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,14 @@
<link rel="prefetch" href="assets/hands.jpg">
<link href="https://fonts.googleapis.com/css?family=Quicksand:300,400,500,700" rel="stylesheet">
</head>

<video autoplay></video>
<h3 id="status"></h3>
<input id="record" type="button" value="record" />
<input id="stop" type="button" value="stop" />
<script src="video.js"></script>
<body>
<script>
<!-- <script>
Elm.Main.fullscreen()
</script>
</script> -->
</body>
</html>
61 changes: 61 additions & 0 deletions public/video.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const record = document.getElementById('record')
const stop = document.getElementById('stop')

if (!navigator.mediaDevices){
alert('getUserMedia support required to use this page')
}

const chunks = []
let onDataAvailable = (e) => {
chunks.push(e.data)
}

// Not showing vendor prefixes.
navigator.mediaDevices.getUserMedia({
audio: true,
video: {
width: { ideal: 1280 },
height: { ideal: 720 }
}
}).then((mediaStream) => {
const recorder = new MediaRecorder(mediaStream)
recorder.ondataavailable = onDataAvailable
const video = document.querySelector('video')
const url = window.URL.createObjectURL(mediaStream)
video.src = url

record.onclick = () => {
recorder.start()
document.getElementById('status').innerHTML = 'recorder started'
console.log(recorder.state)
console.log('recorder started')
}

stop.onclick = ()=> {
recorder.stop()
console.log(recorder.state)
document.getElementById('status').innerHTML = 'recorder started'
console.log('recorder stopped')
}

video.onloadedmetadata = (e) => {
console.log('onloadedmetadata', e)
}

recorder.onstop = (e) => {
console.log('e', e)
console.log('chunks', chunks)
const bigVideoBlob = new Blob(chunks, { 'type' : 'video/mp4' })
let fd = new FormData()
fd.append('videoData', bigVideoBlob)
fetch("/api/v1/video-upload", {
method: 'POST',
body: fd
})
.then(response => response.json())
.then(response => console.log('Success', response))
.catch(error => console.log('Error', error))
}
}).catch(function(err){
console.log('error', err)
})
3 changes: 3 additions & 0 deletions src/server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ const path = require("path");
const express = require("express");
const bodyParser = require("body-parser");
const api_router = require("./routers/api_router");
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })

const app = express();

app.use(express.static(path.join(__dirname, "../../public")));
app.use(bodyParser.json());
app.use(upload.single('videoData'));
app.use(express.static("public"));

app.use("/api/v1/", api_router);
Expand Down
20 changes: 20 additions & 0 deletions src/server/routers/api_router.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
const router = require("express").Router();
const Airtable = require("airtable");
const base = Airtable.base(process.env.AIRTABLE_BASE);
const fs = require('fs')
const cloudinary = require('cloudinary');

cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUDNAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET
});

Airtable.configure({
endpointUrl: "https://api.airtable.com",
Expand All @@ -16,4 +24,16 @@ router.route("/help_form").post((req, res, next) => {
});
});

router.route("/video-upload").post((req, res, next) => {
fs.rename(req.file.path, `${req.file.path}.mp4`, function (err) {
// cloudinary documentation is wrong here, for uploader.upload the callback is the second argument and the options are the third
// the callback also has the arguments the wrong way round with the 'result' going first and the 'err' last
cloudinary.uploader.upload(`${req.file.path}.mp4`, function(result, err) {
if (err) { console.log('err', err); };
console.log('result', result);
return res.json({ success: true });
}, { resource_type: "video" });
});
});

module.exports = router;