Skip to content
This repository has been archived by the owner on Feb 17, 2021. It is now read-only.

Commit

Permalink
Upload custom backgrounds and set custom waveform colours (#6)
Browse files Browse the repository at this point in the history
* Allow upload of custom images

Uses DataRozhlas@921ebd6

* Add ability set custom waveform colour

TODO: Need to take theme waveform colour if no custom image set

* Get custom waveform color when a custom background is set

* add instructions for custom image size

* render custom waveform colour if there is a custom background image

* add note to check for image rights; style note
  • Loading branch information
joannaskao authored May 10, 2018
1 parent 9a8d850 commit 147de1d
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 26 deletions.
5 changes: 5 additions & 0 deletions audiogram/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,11 @@ Audiogram.prototype.drawFrames = function(cb) {

self.status("frames");

// render custom waveform colour if there is a custom background image
if (self.settings.backgroundImage !== 'undefined') {
self.settings.theme.waveColor = self.settings.waveformColor;
}

drawFrames(renderer, {
width: self.settings.theme.width,
height: self.settings.theme.height,
Expand Down
9 changes: 5 additions & 4 deletions audiogram/initialize-canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ function initializeCanvas(theme, cb) {

// Fonts pre-registered in bin/worker
var renderer = getRenderer(theme);

if (!theme.backgroundImage) {
if (!(theme.backgroundImage || theme.customBackgroundImage)) {
return cb(null, renderer);
}
backgroundImagePath = theme.customBackgroundImage
? theme.customBackgroundImage
: path.join(__dirname, "..", "settings", "backgrounds", theme.backgroundImage);

// Load background image from file (done separately so renderer code can work in browser too)
fs.readFile(path.join(__dirname, "..", "settings", "backgrounds", theme.backgroundImage), function(err, raw){

fs.readFile(backgroundImagePath, function(err, raw){
if (err) {
return cb(err);
}
Expand Down
28 changes: 27 additions & 1 deletion client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ var d3 = require("d3"),
video = require("./video.js"),
audio = require("./audio.js");

d3.json("/settings/themes.json", function(err, themes){
d3.json(window.location.protocol + "//" + window.location.host + "/settings/themes.json", function(err, themes){

var errorMessage;

Expand Down Expand Up @@ -42,6 +42,8 @@ function submitted() {
var theme = preview.theme(),
caption = preview.caption(),
selection = preview.selection(),
backgroundFile = preview.backgroundFile(),
waveformColor = preview.waveformColor(),
file = preview.file();

if (!file) {
Expand All @@ -63,6 +65,8 @@ function submitted() {
var formData = new FormData();

formData.append("audio", file);
formData.append("backgroundImage", backgroundFile);
formData.append("waveformColor", waveformColor);
if (selection.start || selection.end) {
formData.append("start", selection.start);
formData.append("end", selection.end);
Expand Down Expand Up @@ -173,6 +177,8 @@ function initialize(err, themesWithImages) {

// If there's an initial piece of audio (e.g. back button) load it
d3.select("#input-audio").on("change", updateAudioFile).each(updateAudioFile);
d3.select("#input-background-image").on("change", updateBackgroundFile).each(updateBackgroundFile);
d3.select("#input-waveform-color").on("change", updateWaveformColor).each(updateWaveformColor);

d3.select("#return").on("click", function(){
d3.event.preventDefault();
Expand Down Expand Up @@ -218,6 +224,26 @@ function updateAudioFile() {

}

function updateBackgroundFile() {
preview.loadBackgroundImage(this.files[0], function(err) {
if(err) {
console.warn(err);
}
});

// disable option to customize waveform color unless there is a custom background
if (this.files[0]) {
d3.select('#input-waveform-color').attr('disabled', null);
} else {
d3.select('#input-waveform-color').attr('disabled', 'disabled');
preview.loadWaveformColor(null);
}
}

function updateWaveformColor() {
preview.loadWaveformColor(this.value);
}

function updateCaption() {
preview.caption(this.value);
}
Expand Down
51 changes: 49 additions & 2 deletions client/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,23 @@ var context = d3.select("canvas").node().getContext("2d");
var theme,
caption,
file,
backgroundFile,
backgroundFileCanvasImage,
waveformColor,
selection;

function _file(_) {
return arguments.length ? (file = _) : file;
}

function _backgroundFile(_) {
return arguments.length ? (backgroundFile = _) : backgroundFile;
}

function _waveformColor(_) {
return arguments.length ? (waveformColor = _) : waveformColor;
}

function _theme(_) {
return arguments.length ? (theme = _, redraw()) : theme;
}
Expand Down Expand Up @@ -76,7 +87,14 @@ function redraw() {

var renderer = getRenderer(theme);

renderer.backgroundImage(theme.backgroundImageFile || null);
renderer.backgroundImage(backgroundFileCanvasImage || theme.backgroundImageFile || null);

var waveformColorCustom = theme.waveColor || theme.foregroundColor || "#000";
if (backgroundFileCanvasImage) {
// if there is a custom background, get custom waveform color
waveformColorCustom = waveformColor
}
renderer.waveformColor(waveformColorCustom);

renderer.drawFrame(context, {
caption: caption,
Expand Down Expand Up @@ -106,10 +124,39 @@ function loadAudio(f, cb) {

}

function loadBackgroundImage(f, cb) {
var reader;
backgroundFile = f;
if(backgroundFile) {
reader = new FileReader();
reader.readAsDataURL(backgroundFile);
reader.onload = function(event) {
backgroundFileCanvasImage = new Image();
backgroundFileCanvasImage.onload = function(event) {
redraw();
cb(null);
}
backgroundFileCanvasImage.src = event.target.result;
}
} else {
backgroundFileCanvasImage = null;
redraw();
}
}

function loadWaveformColor (f) {
waveformColor = f;
redraw();
}

module.exports = {
caption: _caption,
theme: _theme,
file: _file,
backgroundFile: _backgroundFile,
waveformColor: _waveformColor,
selection: _selection,
loadAudio: loadAudio
loadAudio: loadAudio,
loadBackgroundImage: loadBackgroundImage,
loadWaveformColor: loadWaveformColor,
};
4 changes: 4 additions & 0 deletions editor/css/editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ label {
font-weight: 500;
}

.label-note {
color: #999;
}

select {
margin-top: 6px;
padding: 6px;
Expand Down
9 changes: 9 additions & 0 deletions editor/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ <h1>Audiogram</h1>
<label for="input-audio">Audio</label>
<input id="input-audio" name="audio" type="file" />
</div>
<div class="row form-row" id="row-background-image">
<label for="input-background-image">Custom image</label>
<input id="input-background-image" name="backgroundImage" type="file" />
<div class="label-note">*Please check with the picture desk that we have rights to the image<br />*Image must be 1280x720 or 640x640</div>
</div>
<div class="row form-row" id="row-waveform-color">
<label for="input-waveform-color">Custom waveform color</label>
<input id="input-waveform-color" name="waveformColor" type="color" disabled />
</div>
<div class="row form-row" id="row-theme">
<label for="input-theme">Theme</label>
<select id="input-theme" name="theme"></select>
Expand Down
16 changes: 14 additions & 2 deletions renderer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module.exports = function(t) {

var renderer = {},
backgroundImage,
waveformColor,
wrapText,
theme;

Expand All @@ -15,14 +16,20 @@ module.exports = function(t) {
return this;
};

renderer.waveformColor = function(_) {
if (!arguments.length) return waveformColor;
waveformColor = _;
return this;
};

renderer.theme = function(_) {
if (!arguments.length) return theme;

theme = _;

// Default colors
theme.backgroundColor = theme.backgroundColor || "#fff";
theme.waveColor = theme.waveColor || theme.foregroundColor || "#000";
// theme.waveColor = theme.waveColor || theme.foregroundColor || "#000";
theme.captionColor = theme.captionColor || theme.foregroundColor || "#000";

// Default wave dimensions
Expand Down Expand Up @@ -51,7 +58,12 @@ module.exports = function(t) {
context.drawImage(backgroundImage, 0, 0, theme.width, theme.height);
}

patterns[theme.pattern || "wave"](context, options.waveform, theme);
var customTheme = Object.assign({}, theme);
if (waveformColor) {
customTheme.waveColor = waveformColor;
}

patterns[theme.pattern || "wave"](context, options.waveform, customTheme);

// Write the caption
if (options.caption) {
Expand Down
26 changes: 15 additions & 11 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ var express = require("express"),
path = require("path"),
multer = require("multer"),
uuid = require("uuid"),
mkdirp = require("mkdirp"),
authS3O = require('s3o-middleware');
mkdirp = require("mkdirp");

// Routes and middleware
var logger = require("../lib/logger/"),
Expand All @@ -21,21 +20,26 @@ var app = express();

app.use(compression());
app.use(logger.morgan());
app.use(authS3O);

// Options for where to store uploaded audio and max size
var fileOptions = {
storage: multer.diskStorage({
destination: function(req, file, cb) {

var dir = path.join(serverSettings.workingDirectory, uuid.v1());

mkdirp(dir, function(err) {
return cb(err, dir);
});
if(file.fieldname === "audio") {
var dir = path.join(serverSettings.workingDirectory, uuid.v1());
mkdirp(dir, function(err) {
return cb(err, dir);
});
} else {
cb(null, serverSettings.workingDirectory);
}
},
filename: function(req, file, cb) {
cb(null, "audio");
if(file.fieldname === "audio") {
cb(null, "audio");
} else {
cb(null, uuid.v1());
}
}
})
};
Expand All @@ -47,7 +51,7 @@ if (serverSettings.maxUploadSize) {
}

// On submission, check upload, validate input, and start generating a video
app.post("/submit/", [multer(fileOptions).single("audio"), render.validate, render.route]);
app.post("/submit/", [multer(fileOptions).fields([{name: "audio", maxCount: 1}, {name: "backgroundImage", maxCount: 1}], {}), render.validate, render.route]);

// If not using S3, serve videos locally
if (!serverSettings.s3Bucket) {
Expand Down
13 changes: 7 additions & 6 deletions server/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ function validate(req, res, next) {
return res.status(500).send("Unknown settings error.");

}

if (!req.file || !req.file.filename) {
if (!req.files.audio || !req.files.audio[0].filename) {
return res.status(500).send("No valid audio received.");
}

if(req.files.backgroundImage && req.files.backgroundImage[0].filename) {
req.body.theme.customBackgroundImage = req.files.backgroundImage[0].path;
}

// Start at the beginning, or specified time
if (req.body.start) {
req.body.start = +req.body.start;
Expand All @@ -36,9 +39,9 @@ function validate(req, res, next) {

function route(req, res) {

var id = req.file.destination.split(path.sep).pop();
var id = req.files.audio[0].destination.split(path.sep).pop();

transports.uploadAudio(path.join(req.file.destination, "audio"), "audio/" + id,function(err) {
transports.uploadAudio(path.join(req.files.audio[0].destination, "audio"), "audio/" + id,function(err) {

if (err) {
throw err;
Expand All @@ -59,8 +62,6 @@ function route(req, res) {
stdio: "inherit",
cwd: path.join(__dirname, ".."),
env: _.extend({}, process.env, { SPAWNED: true })
}).on('error', function(err) {
throw err;
});

}
Expand Down

0 comments on commit 147de1d

Please sign in to comment.