562 lines
12 KiB
JavaScript
562 lines
12 KiB
JavaScript
'use strict';
|
|
|
|
var AudioControls = function() {
|
|
|
|
};
|
|
|
|
AudioControls.prototype.groups = {
|
|
"audio-select": ["btns_audio_tools", "btns_fade"]
|
|
};
|
|
|
|
AudioControls.prototype.classes = {
|
|
"btn-state-active": "btn btn-mini active",
|
|
"btn-state-default": "btn btn-mini",
|
|
"disabled": "disabled",
|
|
"active": "active"
|
|
};
|
|
|
|
AudioControls.prototype.events = {
|
|
"btn_rewind": {
|
|
click: "rewindAudio"
|
|
},
|
|
|
|
"btn_play": {
|
|
click: "playAudio"
|
|
},
|
|
|
|
"btn_stop": {
|
|
click: "stopAudio"
|
|
},
|
|
|
|
"btn_cursor": {
|
|
click: "changeState"
|
|
},
|
|
|
|
"btn_select": {
|
|
click: "changeState"
|
|
},
|
|
|
|
"btn_shift": {
|
|
click: "changeState"
|
|
},
|
|
|
|
"btn_fadein": {
|
|
click: "changeState"
|
|
},
|
|
|
|
"btn_fadeout": {
|
|
click: "changeState"
|
|
},
|
|
|
|
|
|
"btns_fade": {
|
|
click: "createFade"
|
|
},
|
|
|
|
"btn_save": {
|
|
click: "save"
|
|
},
|
|
|
|
"btn_open": {
|
|
click: "open"
|
|
},
|
|
|
|
"btn_trim_audio": {
|
|
click: "trimAudio"
|
|
},
|
|
|
|
"time_format": {
|
|
change: "changeTimeFormat"
|
|
},
|
|
|
|
"audio_start": {
|
|
blur: "validateCueIn"
|
|
},
|
|
|
|
"audio_end": {
|
|
blur: "validateCueOut"
|
|
},
|
|
|
|
"audio_pos": {
|
|
|
|
},
|
|
|
|
"audio_resolution": {
|
|
change: "changeResolution"
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.validateCue = function(value) {
|
|
var validators,
|
|
regex,
|
|
result;
|
|
|
|
validators = {
|
|
"seconds": /^\d+$/,
|
|
|
|
"thousandths": /^\d+\.\d{3}$/,
|
|
|
|
"hh:mm:ss": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]$/,
|
|
|
|
"hh:mm:ss.u": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]\.\d{1}$/,
|
|
|
|
"hh:mm:ss.uu": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]\.\d{2}$/,
|
|
|
|
"hh:mm:ss.uuu": /^[0-9]{2,}:[0-5][0-9]:[0-5][0-9]\.\d{3}$/
|
|
};
|
|
|
|
regex = validators[this.timeFormat];
|
|
result = regex.test(value);
|
|
|
|
return result;
|
|
};
|
|
|
|
AudioControls.prototype.cueToSeconds = function(value) {
|
|
var converter,
|
|
func,
|
|
seconds;
|
|
|
|
function clockConverter(value) {
|
|
var data = value.split(":"),
|
|
hours = parseInt(data[0], 10) * 3600,
|
|
mins = parseInt(data[1], 10) * 60,
|
|
secs = parseFloat(data[2]),
|
|
seconds;
|
|
|
|
seconds = hours + mins + secs;
|
|
|
|
return seconds;
|
|
}
|
|
|
|
converter = {
|
|
"seconds": function(value) {
|
|
return parseInt(value, 10);
|
|
},
|
|
|
|
"thousandths": function(value) {
|
|
return parseFloat(value);
|
|
},
|
|
|
|
"hh:mm:ss": function(value) {
|
|
return clockConverter(value);
|
|
},
|
|
|
|
"hh:mm:ss.u": function(value) {
|
|
return clockConverter(value);
|
|
},
|
|
|
|
"hh:mm:ss.uu": function(value) {
|
|
return clockConverter(value);
|
|
},
|
|
|
|
"hh:mm:ss.uuu": function(value) {
|
|
return clockConverter(value);
|
|
}
|
|
};
|
|
|
|
func = converter[this.timeFormat];
|
|
seconds = func(value);
|
|
|
|
return seconds;
|
|
};
|
|
|
|
AudioControls.prototype.cueFormatters = function(format) {
|
|
|
|
function clockFormat(seconds, decimals) {
|
|
var hours,
|
|
minutes,
|
|
secs,
|
|
result;
|
|
|
|
hours = parseInt(seconds / 3600, 10) % 24;
|
|
minutes = parseInt(seconds / 60, 10) % 60;
|
|
secs = seconds % 60;
|
|
secs = secs.toFixed(decimals);
|
|
|
|
result = (hours < 10 ? "0" + hours : hours) + ":" + (minutes < 10 ? "0" + minutes : minutes) + ":" + (secs < 10 ? "0" + secs : secs);
|
|
|
|
return result;
|
|
}
|
|
|
|
var formats = {
|
|
"seconds": function (seconds) {
|
|
return seconds.toFixed(0);
|
|
},
|
|
|
|
"thousandths": function (seconds) {
|
|
return seconds.toFixed(3);
|
|
},
|
|
|
|
"hh:mm:ss": function (seconds) {
|
|
return clockFormat(seconds, 0);
|
|
},
|
|
|
|
"hh:mm:ss.u": function (seconds) {
|
|
return clockFormat(seconds, 1);
|
|
},
|
|
|
|
"hh:mm:ss.uu": function (seconds) {
|
|
return clockFormat(seconds, 2);
|
|
},
|
|
|
|
"hh:mm:ss.uuu": function (seconds) {
|
|
return clockFormat(seconds, 3);
|
|
}
|
|
};
|
|
|
|
return formats[format];
|
|
};
|
|
|
|
AudioControls.prototype.init = function(config) {
|
|
var that = this,
|
|
className,
|
|
event,
|
|
events = this.events,
|
|
tmpEl,
|
|
func,
|
|
state,
|
|
container,
|
|
tmpBtn;
|
|
|
|
makePublisher(this);
|
|
|
|
this.ctrls = {};
|
|
this.config = config;
|
|
container = this.config.getContainer();
|
|
state = this.config.getState();
|
|
|
|
tmpBtn = document.getElementsByClassName("btn_"+state)[0];
|
|
|
|
if (tmpBtn) {
|
|
this.activateButton(tmpBtn);
|
|
}
|
|
|
|
for (className in events) {
|
|
|
|
tmpEl = container.getElementsByClassName(className)[0];
|
|
this.ctrls[className] = tmpEl;
|
|
|
|
for (event in events[className]) {
|
|
|
|
if (tmpEl) {
|
|
func = that[events[className][event]].bind(that);
|
|
tmpEl.addEventListener(event, func);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.ctrls["time_format"]) {
|
|
this.ctrls["time_format"].value = this.config.getTimeFormat();
|
|
}
|
|
|
|
if (this.ctrls["audio_resolution"]) {
|
|
this.ctrls["audio_resolution"].value = this.config.getResolution();
|
|
}
|
|
|
|
this.timeFormat = this.config.getTimeFormat();
|
|
|
|
//Kept in seconds so time format change can update fields easily.
|
|
this.currentSelectionValues = undefined;
|
|
|
|
this.onCursorSelection({
|
|
start: 0,
|
|
end: 0
|
|
});
|
|
};
|
|
|
|
AudioControls.prototype.changeTimeFormat = function(e) {
|
|
var format = e.target.value,
|
|
func, start, end;
|
|
|
|
format = (this.cueFormatters(format) !== undefined) ? format : "hh:mm:ss";
|
|
this.config.setTimeFormat(format);
|
|
this.timeFormat = format;
|
|
|
|
if (this.currentSelectionValues !== undefined) {
|
|
func = this.cueFormatters(format);
|
|
start = this.currentSelectionValues.start;
|
|
end = this.currentSelectionValues.end;
|
|
|
|
if (this.ctrls["audio_start"]) {
|
|
this.ctrls["audio_start"].value = func(start);
|
|
}
|
|
|
|
if (this.ctrls["audio_end"]) {
|
|
this.ctrls["audio_end"].value = func(end);
|
|
}
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.changeResolution = function(e) {
|
|
var res = parseInt(e.target.value, 10);
|
|
|
|
this.config.setResolution(res);
|
|
this.fire("changeresolution", res);
|
|
};
|
|
|
|
AudioControls.prototype.validateCueIn = function(e) {
|
|
var value = e.target.value,
|
|
end,
|
|
startSecs;
|
|
|
|
if (this.validateCue(value)) {
|
|
end = this.currentSelectionValues.end;
|
|
startSecs = this.cueToSeconds(value);
|
|
|
|
if (startSecs <= end) {
|
|
this.notifySelectionUpdate(startSecs, end);
|
|
this.currentSelectionValues.start = startSecs;
|
|
return;
|
|
}
|
|
}
|
|
|
|
//time entered was otherwise invalid.
|
|
e.target.value = this.cueFormatters(this.timeFormat)(this.currentSelectionValues.start);
|
|
};
|
|
|
|
AudioControls.prototype.validateCueOut = function(e) {
|
|
var value = e.target.value,
|
|
start,
|
|
endSecs;
|
|
|
|
if (this.validateCue(value)) {
|
|
start = this.currentSelectionValues.start;
|
|
endSecs = this.cueToSeconds(value);
|
|
|
|
if (endSecs >= start) {
|
|
this.notifySelectionUpdate(start, endSecs);
|
|
this.currentSelectionValues.end = endSecs;
|
|
return;
|
|
}
|
|
}
|
|
|
|
//time entered was otherwise invalid.
|
|
e.target.value = this.cueFormatters(this.timeFormat)(this.currentSelectionValues.end);
|
|
};
|
|
|
|
AudioControls.prototype.activateButtonGroup = function(id) {
|
|
var el = document.getElementById(id),
|
|
btns,
|
|
classes = this.classes,
|
|
i, len;
|
|
|
|
if (el === null) {
|
|
return;
|
|
}
|
|
|
|
btns = el.getElementsByTagName("a");
|
|
|
|
for (i = 0, len = btns.length; i < len; i++) {
|
|
btns[i].classList.remove(classes["disabled"]);
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.deactivateButtonGroup = function(id) {
|
|
var el = document.getElementById(id),
|
|
btns,
|
|
classes = this.classes,
|
|
i, len;
|
|
|
|
if (el === null) {
|
|
return;
|
|
}
|
|
|
|
btns = el.getElementsByTagName("a");
|
|
|
|
for (i = 0, len = btns.length; i < len; i++) {
|
|
btns[i].classList.add(classes["disabled"]);
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.activateAudioSelection = function() {
|
|
var ids = this.groups["audio-select"],
|
|
i, len;
|
|
|
|
for (i = 0, len = ids.length; i < len; i++) {
|
|
this.activateButtonGroup(ids[i]);
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.deactivateAudioSelection = function() {
|
|
var ids = this.groups["audio-select"],
|
|
i, len;
|
|
|
|
for (i = 0, len = ids.length; i < len; i++) {
|
|
this.deactivateButtonGroup(ids[i]);
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.save = function() {
|
|
|
|
this.fire('playlistsave', this);
|
|
};
|
|
|
|
AudioControls.prototype.open = function() {
|
|
|
|
this.fire('playlistrestore', this);
|
|
};
|
|
|
|
AudioControls.prototype.rewindAudio = function() {
|
|
|
|
this.fire('rewindaudio', this);
|
|
};
|
|
|
|
AudioControls.prototype.playAudio = function() {
|
|
|
|
this.fire('playaudio', this);
|
|
};
|
|
|
|
AudioControls.prototype.stopAudio = function() {
|
|
|
|
this.fire('stopaudio', this);
|
|
};
|
|
|
|
AudioControls.prototype.activateButton = function(el) {
|
|
if (el) {
|
|
el.classList.add(this.classes["active"]);
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.deactivateButton = function(el) {
|
|
if (el) {
|
|
el.classList.remove(this.classes["active"]);
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.enableButton = function(el) {
|
|
if (el) {
|
|
el.classList.remove(this.classes["disabled"]);
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.disableButton = function(el) {
|
|
if (el) {
|
|
el.classList.add(this.classes["disabled"]);
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.changeState = function(e) {
|
|
var el = e.currentTarget,
|
|
prevEl = el.parentElement.getElementsByClassName('active')[0],
|
|
state = el.dataset.state;
|
|
|
|
this.deactivateButton(prevEl);
|
|
this.activateButton(el);
|
|
|
|
this.config.setState(state);
|
|
this.fire('changestate', this);
|
|
};
|
|
|
|
AudioControls.prototype.zeroCrossing = function(e) {
|
|
var el = e.target,
|
|
disabled,
|
|
classes = this.classes;
|
|
|
|
disabled = el.classList.contains(classes["disabled"]);
|
|
|
|
if (!disabled) {
|
|
this.fire('trackedit', {
|
|
type: "zeroCrossing"
|
|
});
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.trimAudio = function(e) {
|
|
var el = e.target,
|
|
disabled,
|
|
classes = this.classes;
|
|
|
|
disabled = el.classList.contains(classes["disabled"]);
|
|
|
|
if (!disabled) {
|
|
this.fire('trackedit', {
|
|
type: "trimAudio"
|
|
});
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.removeAudio = function(e) {
|
|
var el = e.target,
|
|
disabled,
|
|
classes = this.classes;
|
|
|
|
disabled = el.classList.contains(classes["disabled"]);
|
|
|
|
if (!disabled) {
|
|
this.fire('trackedit', {
|
|
type: "removeAudio"
|
|
});
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.createFade = function(e) {
|
|
var el = e.target,
|
|
shape = el.dataset.shape,
|
|
type = el.dataset.type,
|
|
disabled,
|
|
classes = this.classes;
|
|
|
|
disabled = el.classList.contains(classes["disabled"]);
|
|
|
|
if (!disabled) {
|
|
this.fire('trackedit', {
|
|
type: "createFade",
|
|
args: {
|
|
type: type,
|
|
shape: shape
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
AudioControls.prototype.onAudioSelection = function() {
|
|
this.activateAudioSelection();
|
|
};
|
|
|
|
AudioControls.prototype.onAudioDeselection = function() {
|
|
this.deactivateAudioSelection();
|
|
};
|
|
|
|
/*
|
|
start, end in seconds
|
|
*/
|
|
AudioControls.prototype.notifySelectionUpdate = function(start, end) {
|
|
|
|
this.fire('changeselection', {
|
|
start: start,
|
|
end: end
|
|
});
|
|
};
|
|
|
|
/*
|
|
start, end in seconds
|
|
*/
|
|
AudioControls.prototype.onCursorSelection = function(args) {
|
|
var startFormat = this.cueFormatters(this.timeFormat)(args.start),
|
|
endFormat = this.cueFormatters(this.timeFormat)(args.end),
|
|
start = this.cueToSeconds(startFormat),
|
|
end = this.cueToSeconds(endFormat);
|
|
|
|
this.currentSelectionValues = {
|
|
start: start,
|
|
end:end
|
|
};
|
|
|
|
if (this.ctrls["audio_start"]) {
|
|
this.ctrls["audio_start"].value = startFormat;
|
|
}
|
|
|
|
if (this.ctrls["audio_end"]) {
|
|
this.ctrls["audio_end"].value = endFormat;
|
|
}
|
|
};
|
|
|
|
/*
|
|
args {seconds, pixels}
|
|
*/
|
|
AudioControls.prototype.onAudioUpdate = function(args) {
|
|
if (this.ctrls["audio_pos"]) {
|
|
this.ctrls["audio_pos"].innerHTML = this.cueFormatters(this.timeFormat)(args.seconds);
|
|
}
|
|
};
|