CC-5108 : Waveform Editor UI

putting on the timescale for time reference.

fade editor now has cursor playback info.
This commit is contained in:
Naomi 2013-05-23 18:33:40 -04:00
parent 16bd407136
commit 75e6f21ce0
10 changed files with 141 additions and 14 deletions

View file

@ -36,6 +36,7 @@
<script id="tmpl-pl-cues" type="text/template">
<div class="waveform-cues">
<div class="playlist-time-scale"></div>
<div class="playlist-tracks"></div>
<div class="playlist-controls">
<a class="btn btn-small btn_play"><i class="icon-play icon-white"></i><?php echo _("Play"); ?></a>
@ -61,10 +62,12 @@
<script id="tmpl-pl-fades" type="text/template">
<div class="waveform-fades">
<div class="playlist-time-scale"></div>
<div class="playlist-tracks"></div>
<div class="playlist-controls left-floated">
<a class="btn btn-small btn_play"><i class="icon-play icon-white"></i><?php echo _("Play"); ?></a>
<a class="btn btn-small btn_stop"><i class="icon-stop icon-white"></i><?php echo _("Stop"); ?></a>
<label class="audio audio_pos">00:00:00.0</label>
</div>
<div class="set-fade left-floated">
<a type="button" class="btn btn-small btn_cursor" data-state="cursor"><?php echo _("Cursor"); ?></a>

View file

@ -686,6 +686,10 @@ SQL;
public function createCrossfade($id1, $fadeOut, $id2, $fadeIn, $offset)
{
$this->con->beginTransaction();
if (!isset($offset)) {
$offset = Application_Model_Preference::GetDefaultCrossfadeDuration();
}
try {
if (isset($id1)) {

View file

@ -673,6 +673,10 @@ SQL;
{
$this->con->beginTransaction();
if (!isset($offset)) {
$offset = Application_Model_Preference::GetDefaultCrossfadeDuration();
}
try {
if (isset($id1)) {
$this->changeFadeInfo($id1, null, $fadeOut);

View file

@ -528,8 +528,6 @@ SQL;
*/
public function getRelativeFileUrl($baseUrl)
{
Logging::debug("Zend base url: $baseUrl");
return $baseUrl."api/get-media/file/".$this->getId().".".$this->getFileExtension();
}

View file

@ -14,11 +14,36 @@
.btn-small {
/*line-height: 20px;*/
}
.playlist-time-scale {
position: absolute;
top: 5px;
left: 0;
right: 0;
height: 30px;
overflow: hidden;
}
.playlist-time-scale canvas {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
height: 30px;
}
.playlist-time-scale div {
position: absolute;
}
.playlist-tracks {
margin: 8px 0;
position: relative;
top: 35px;
margin: 2px 0;
}
.playlist-controls {
margin: 0 0 16px 0;
margin: 40px 0 16px 0;
}
.channel-wrapper {
@ -30,6 +55,8 @@
margin: 0;
padding: 0;
background: #6e6e6e;
/*border-top: 1px solid #6e6e6e;*/
/*border-bottom: 1px solid #6e6e6e;*/
}
.state-select {
@ -41,6 +68,12 @@
overflow-y: hidden;
}
.playlist-tracks > .error {
height: 80px;
width: 300px;
background-color: rgba(255,0,0,0.5);
}
.playlist-fade {
position: absolute;
background-color: rgba(0,0,0,0.1);
@ -50,7 +83,7 @@
margin: 12px 0 16px 0;
}
.set-fade {
margin: 0 0 0 30px;
margin: 40px 0 0 30px;
}
.set-cue input[type="text"] {
vertical-align: middle;

View file

@ -1246,7 +1246,7 @@ var AIRTIME = (function(AIRTIME){
show: 'clip',
hide: 'clip',
width: dim.width - 100,
height: dim.height - 100,
height: 350,
buttons: [
{text: $.i18n._("Cancel"), class: "btn btn-small", click: removeDialog},
{text: $.i18n._("Save"), class: "btn btn-small btn-inverse", click: function() {
@ -1263,9 +1263,11 @@ var AIRTIME = (function(AIRTIME){
if (fade["type"] === "FadeOut") {
fadeOut = fade["end"] - fade["start"];
id2 = undefined; //incase of track decode error.
}
else {
fadeIn = fade["end"] - fade["start"];
id1 = undefined; //incase of track decode error.
}
}
else {
@ -1291,6 +1293,7 @@ var AIRTIME = (function(AIRTIME){
resolution: 15000,
state: "cursor",
mono: true,
timescale: true,
waveHeight: 80,
container: $html[0],
UITheme: "jQueryUI",
@ -1301,7 +1304,10 @@ var AIRTIME = (function(AIRTIME){
playlistEditor.setConfig(config);
playlistEditor.init(tracks);
},
close: removeDialog
close: removeDialog,
resizeStop: function(event, ui) {
playlistEditor.resize();
}
});
};
@ -1354,7 +1360,7 @@ var AIRTIME = (function(AIRTIME){
show: 'clip',
hide: 'clip',
width: dim.width - 100,
height: dim.height - 100,
height: 325,
buttons: [
{text: $.i18n._("Cancel"), class: "btn btn-small", click: removeDialog},
{text: $.i18n._("Save"), class: "btn btn-small btn-inverse", click: function() {
@ -1371,6 +1377,7 @@ var AIRTIME = (function(AIRTIME){
var config = new Config({
resolution: 15000,
mono: true,
timescale: true,
waveHeight: 80,
container: $html[0],
UITheme: "jQueryUI",
@ -1381,7 +1388,10 @@ var AIRTIME = (function(AIRTIME){
playlistEditor.setConfig(config);
playlistEditor.init(tracks);
},
close: removeDialog
close: removeDialog,
resizeStop: function(event, ui) {
playlistEditor.resize();
}
});
};

View file

@ -56,6 +56,16 @@ PlaylistEditor.prototype.init = function(tracks) {
trackEditor.on("deactivateSelection", "onAudioDeselection", audioControls);
trackEditor.on("changecursor", "onCursorSelection", audioControls);
trackEditor.on("changecursor", "onSelectUpdate", this);
trackEditor.on("unregister", (function() {
var editor = this;
audioControls.remove("trackedit", "onTrackEdit", editor);
audioControls.remove("changeresolution", "onResolutionChange", editor);
that.removeTrack(editor);
}).bind(trackEditor));
}
div.innerHTML = '';
@ -79,7 +89,27 @@ PlaylistEditor.prototype.init = function(tracks) {
audioControls.on("trimaudio", "onTrimAudio", this);
audioControls.on("removeaudio", "onRemoveAudio", this);
audioControls.on("changestate", "onStateChange", this);
audioControls.on("changeselection", "onSelectionChange", this);
audioControls.on("changeselection", "onSelectionChange", this);
};
PlaylistEditor.prototype.removeTrack = function(trackEditor) {
var i,
len,
editor,
editors = this.trackEditors;
for (i = 0, len = editors.length; i < len; i++) {
editor = editors[i];
if (editor === trackEditor) {
editors.splice(i, 1);
return;
}
}
};
PlaylistEditor.prototype.resize = function() {
this.timeScale.onResize();
};
PlaylistEditor.prototype.onTrimAudio = function() {

View file

@ -83,7 +83,8 @@ AudioPlayout.prototype.loadData = function (audioData, cb) {
cb(buffer);
},
function(err) {
console.log("err(decodeAudioData): "+err);
console.log("err(decodeAudioData): "+err);
cb(null, err);
}
);
};

View file

@ -8,7 +8,8 @@ TimeScale.prototype.init = function(config) {
var that = this,
canv,
div;
div,
resizeTimer;
makePublisher(this);
@ -36,6 +37,24 @@ TimeScale.prototype.init = function(config) {
this.prevScrollPos = 0; //checking the horizontal scroll (must update timeline above in case of change)
//TODO check scroll adjust.
function doneResizing() {
that.width = that.container.clientWidth;
that.height = that.container.clientHeight;
canv.setAttribute('width', that.width);
canv.setAttribute('height', that.height);
that.drawScale();
};
function onResize() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(doneResizing, 100);
};
TimeScale.prototype.onResize = onResize;
this.drawScale();
};

View file

@ -208,11 +208,20 @@ TrackEditor.prototype.drawTrack = function(buffer) {
this.drawer.drawFades(this.fades);
};
TrackEditor.prototype.onTrackLoad = function(buffer) {
TrackEditor.prototype.onTrackLoad = function(buffer, err) {
var res,
startTime,
endTime;
if (err !== undefined) {
this.container.innerHTML = "";
this.container.classList.add("error");
this.fire('unregister');
return;
}
if (this.cues === undefined) {
this.setCuePoints(0, buffer.length - 1);
}
@ -282,6 +291,8 @@ TrackEditor.prototype.deactivate = function() {
/* start of state methods */
TrackEditor.prototype.timeShift = function(e) {
e.preventDefault();
var el = e.currentTarget, //want the events placed on the channel wrapper.
startX = e.pageX,
diffX = 0,
@ -296,6 +307,8 @@ TrackEditor.prototype.timeShift = function(e) {
//dynamically put an event on the element.
el.onmousemove = function(e) {
e.preventDefault();
var endX = e.pageX;
diffX = endX - startX;
@ -303,7 +316,9 @@ TrackEditor.prototype.timeShift = function(e) {
editor.drawer.setTimeShift(updatedX);
editor.leftOffset = editor.pixelsToSamples(updatedX);
};
el.onmouseup = function() {
el.onmouseup = function(e) {
e.preventDefault();
var delta;
el.onmousemove = el.onmouseup = null;
@ -453,6 +468,8 @@ TrackEditor.prototype.findLayerOffset = function(e) {
};
TrackEditor.prototype.selectStart = function(e) {
e.preventDefault();
var el = e.currentTarget, //want the events placed on the channel wrapper.
editor = this,
startX = e.layerX || e.offsetX, //relative to e.target (want the canvas).
@ -475,6 +492,8 @@ TrackEditor.prototype.selectStart = function(e) {
//dynamically put an event on the element.
el.onmousemove = function(e) {
e.preventDefault();
var currentX = layerOffset + (e.layerX || e.offsetX),
delta = currentX - prevX,
minX = Math.min(prevX, currentX, startX),
@ -500,6 +519,8 @@ TrackEditor.prototype.selectStart = function(e) {
prevX = currentX;
};
el.onmouseup = function(e) {
e.preventDefault();
var endX = layerOffset + (e.layerX || e.offsetX),
minX, maxX,
startTime, endTime;
@ -555,6 +576,8 @@ TrackEditor.prototype.selectCursorPos = function(e) {
};
TrackEditor.prototype.selectFadeIn = function(e) {
e.preventDefault();
var startX = e.layerX || e.offsetX, //relative to e.target (want the canvas).
layerOffset,
FADETYPE = "FadeIn",
@ -572,6 +595,8 @@ TrackEditor.prototype.selectFadeIn = function(e) {
};
TrackEditor.prototype.selectFadeOut = function(e) {
e.preventDefault();
var startX = e.layerX || e.offsetX, //relative to e.target (want the canvas).
layerOffset,
FADETYPE = "FadeOut",