feat(legacy): visual cue point editor (#2947)
A visual cue point editor in the track editor view. This view displays the track as a waveform and allows you to set where the in- and out-cue points are set. These cue points determine the start and end points of the track. --------- Co-authored-by: Thomas Göttgens <tgoettgens@mail.com> Co-authored-by: Kyle Robbertze <paddatrapper@users.noreply.github.com>
This commit is contained in:
parent
71b20ae3c9
commit
da02e74f21
20 changed files with 9420 additions and 43 deletions
|
@ -26,7 +26,7 @@
|
||||||
"css/media_library.css": "e1982d1f673543f7730898fb49450f8b",
|
"css/media_library.css": "e1982d1f673543f7730898fb49450f8b",
|
||||||
"css/player-form.css": "e08a4545715fc56b75c845b44a5b2a1c",
|
"css/player-form.css": "e08a4545715fc56b75c845b44a5b2a1c",
|
||||||
"css/player.css": "904bc7aede4d5f0372468528d88094f1",
|
"css/player.css": "904bc7aede4d5f0372468528d88094f1",
|
||||||
"css/playlist_builder.css": "e92ef56ddffca440a7741934edbb7f7f",
|
"css/playlist_builder.css": "9e35f1b7a1e79a7a73e7e9666d5a711f",
|
||||||
"css/playouthistory.css": "983cc1bac566b18b745b6e0da9ef3c0c",
|
"css/playouthistory.css": "983cc1bac566b18b745b6e0da9ef3c0c",
|
||||||
"css/plupload.queue.css": "0acfb6b54c18654452727d4abf297394",
|
"css/plupload.queue.css": "0acfb6b54c18654452727d4abf297394",
|
||||||
"css/pro_dropdown_3.css": "9848a27dad960c2218751c1656e9206a",
|
"css/pro_dropdown_3.css": "9848a27dad960c2218751c1656e9206a",
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
"css/show_analytics.css": "4393c521308277447afabe8791779bf1",
|
"css/show_analytics.css": "4393c521308277447afabe8791779bf1",
|
||||||
"css/showbuilder.css": "4421c01b5c2dfb03f8d06dd6023b4bd7",
|
"css/showbuilder.css": "4421c01b5c2dfb03f8d06dd6023b4bd7",
|
||||||
"css/station_podcast.css": "88e9b38ead71eddc69ef50bfc8cb2d0d",
|
"css/station_podcast.css": "88e9b38ead71eddc69ef50bfc8cb2d0d",
|
||||||
"css/styles.css": "6890a553402f44cefc7c6915f38aa657",
|
"css/styles.css": "29ce2292b2c007e86d192d0deeaf88ad",
|
||||||
"css/tipsy/jquery.tipsy.css": "b13517583583f83ed7d5fc067a0c9372",
|
"css/tipsy/jquery.tipsy.css": "b13517583583f83ed7d5fc067a0c9372",
|
||||||
"css/tracktypes.css": "94c94817a8505ff4dfcd090987859a7e",
|
"css/tracktypes.css": "94c94817a8505ff4dfcd090987859a7e",
|
||||||
"css/users.css": "94c94817a8505ff4dfcd090987859a7e",
|
"css/users.css": "94c94817a8505ff4dfcd090987859a7e",
|
||||||
|
@ -63,7 +63,7 @@
|
||||||
"js/airtime/library/plupload.js": "0f6be5b133650828b9ffc74e7852dc89",
|
"js/airtime/library/plupload.js": "0f6be5b133650828b9ffc74e7852dc89",
|
||||||
"js/airtime/library/podcast.js": "4dedd84cb571cdba2401bfb8ba621e69",
|
"js/airtime/library/podcast.js": "4dedd84cb571cdba2401bfb8ba621e69",
|
||||||
"js/airtime/library/publish.js": "ab3a1452dd332cdb0773241a1c17b7e0",
|
"js/airtime/library/publish.js": "ab3a1452dd332cdb0773241a1c17b7e0",
|
||||||
"js/airtime/library/spl.js": "c4cbac0c237b548064685a2cb16d3fa2",
|
"js/airtime/library/spl.js": "5bddd886303ff15e8b78e79b30a9e56f",
|
||||||
"js/airtime/listenerstat/listenerstat.js": "a3733dae8f9549668125ec9852d356ed",
|
"js/airtime/listenerstat/listenerstat.js": "a3733dae8f9549668125ec9852d356ed",
|
||||||
"js/airtime/listenerstat/showlistenerstat.js": "7cf0c375420f1c8471d304bc8758b2cd",
|
"js/airtime/listenerstat/showlistenerstat.js": "7cf0c375420f1c8471d304bc8758b2cd",
|
||||||
"js/airtime/login/login.js": "7278cf49618791d75bacce38dd1b1d46",
|
"js/airtime/login/login.js": "7278cf49618791d75bacce38dd1b1d46",
|
||||||
|
@ -180,5 +180,16 @@
|
||||||
"js/waveformplaylist/playout.js": "7dfc5fe760f3c6739e38499df7b61e47",
|
"js/waveformplaylist/playout.js": "7dfc5fe760f3c6739e38499df7b61e47",
|
||||||
"js/waveformplaylist/time_scale.js": "74e0e17e1c8cd597449220c98de408ba",
|
"js/waveformplaylist/time_scale.js": "74e0e17e1c8cd597449220c98de408ba",
|
||||||
"js/waveformplaylist/track.js": "5456e6081ffedf55a9e38571bc178781",
|
"js/waveformplaylist/track.js": "5456e6081ffedf55a9e38571bc178781",
|
||||||
"js/waveformplaylist/track_render.js": "e371b582b23e4b618e039f096d2f0570"
|
"js/waveformplaylist/track_render.js": "e371b582b23e4b618e039f096d2f0570",
|
||||||
|
"js/wavesurfer/cursor.js": "8ed17a7437f3ec84972d15d0073249b2",
|
||||||
|
"js/wavesurfer/cursor.min.js": "831165862b629e615cf59112fa00d963",
|
||||||
|
"js/wavesurfer/libretime.js": "17133cacf09fc204a572b56c99d44278",
|
||||||
|
"js/wavesurfer/minimap.js": "c17dd315386006bb3cffdabb5f715c7b",
|
||||||
|
"js/wavesurfer/minimap.min.js": "90b2f2d1d1b4eb189d1a9c3c27dcb4f7",
|
||||||
|
"js/wavesurfer/regions.js": "aafe4f696d3da50c976d11e472fd56d1",
|
||||||
|
"js/wavesurfer/regions.min.js": "2ed2f8b5880beee568942000a6139e85",
|
||||||
|
"js/wavesurfer/timeline.js": "0bd70779070513c2a4f34237a0f9f573",
|
||||||
|
"js/wavesurfer/timeline.min.js": "90ea16b23cacebfad10cad42f94403d0",
|
||||||
|
"js/wavesurfer/wavesurfer.js": "9e2ced8a136449f4fd78911b0f01f6ed",
|
||||||
|
"js/wavesurfer/wavesurfer.min.js": "42ebd7fdd574dfe8cae587145751a1f2"
|
||||||
}
|
}
|
||||||
|
|
|
@ -400,6 +400,12 @@ class LibraryController extends Zend_Controller_Action
|
||||||
$this->view->artist_name = $file->getPropelOrm()->getDbArtistName();
|
$this->view->artist_name = $file->getPropelOrm()->getDbArtistName();
|
||||||
$this->view->filePath = $file->getPropelOrm()->getDbFilepath();
|
$this->view->filePath = $file->getPropelOrm()->getDbFilepath();
|
||||||
$this->view->artwork = $file->getPropelOrm()->getDbArtwork();
|
$this->view->artwork = $file->getPropelOrm()->getDbArtwork();
|
||||||
|
$this->view->replay_gain = $file->getPropelOrm()->getDbReplayGain();
|
||||||
|
$this->view->cuein = $file->getPropelOrm()->getDbCuein();
|
||||||
|
$this->view->cueout = $file->getPropelOrm()->getDbCueout();
|
||||||
|
$this->view->format = $file->getPropelOrm()->getDbFormat();
|
||||||
|
$this->view->bit_rate = $file->getPropelOrm()->getDbBitRate();
|
||||||
|
$this->view->sample_rate = $file->getPropelOrm()->getDbSampleRate();
|
||||||
$this->view->html = $this->view->render('library/edit-file-md.phtml');
|
$this->view->html = $this->view->render('library/edit-file-md.phtml');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -217,6 +217,13 @@ class PageLayoutInitPlugin extends Zend_Controller_Plugin_Abstract
|
||||||
->appendFile(Assets::url('js/airtime/common/common.js'), 'text/javascript')
|
->appendFile(Assets::url('js/airtime/common/common.js'), 'text/javascript')
|
||||||
->appendFile(Assets::url('js/airtime/common/audioplaytest.js'), 'text/javascript');
|
->appendFile(Assets::url('js/airtime/common/audioplaytest.js'), 'text/javascript');
|
||||||
|
|
||||||
|
// include wavesurfer.js for waveform display
|
||||||
|
$view->headScript()->appendFile(Assets::url('js/wavesurfer/wavesurfer.min.js'), 'text/javascript')
|
||||||
|
->appendFile(Assets::url('js/wavesurfer/timeline.min.js'), 'text/javascript')
|
||||||
|
->appendFile(Assets::url('js/wavesurfer/regions.min.js'), 'text/javascript')
|
||||||
|
->appendFile(Assets::url('js/wavesurfer/cursor.min.js'), 'text/javascript')
|
||||||
|
->appendFile(Assets::url('js/wavesurfer/libretime.js'), 'text/javascript');
|
||||||
|
|
||||||
$user = Application_Model_User::getCurrentUser();
|
$user = Application_Model_User::getCurrentUser();
|
||||||
if (!is_null($user)) {
|
if (!is_null($user)) {
|
||||||
$userType = $user->getType();
|
$userType = $user->getType();
|
||||||
|
|
|
@ -8,9 +8,11 @@ class Application_Form_EditAudioMD extends Zend_Form
|
||||||
{
|
{
|
||||||
// Set the method for the display form to POST
|
// Set the method for the display form to POST
|
||||||
$this->setMethod('post');
|
$this->setMethod('post');
|
||||||
|
$this->setAttrib('id', 'track_edit_' . $p_id);
|
||||||
|
|
||||||
$file_id = new Zend_Form_Element_Hidden('file_id');
|
$file_id = new Zend_Form_Element_Hidden('file_id');
|
||||||
$file_id->setValue($p_id);
|
$file_id->setValue($p_id);
|
||||||
|
$file_id->setDecorators(['ViewHelper']);
|
||||||
$file_id->addDecorator('HtmlTag', ['tag' => 'div', 'style' => 'display:none']);
|
$file_id->addDecorator('HtmlTag', ['tag' => 'div', 'style' => 'display:none']);
|
||||||
$file_id->removeDecorator('Label');
|
$file_id->removeDecorator('Label');
|
||||||
$file_id->setAttrib('class', 'obj_id');
|
$file_id->setAttrib('class', 'obj_id');
|
||||||
|
@ -188,6 +190,14 @@ class Application_Form_EditAudioMD extends Zend_Form
|
||||||
]);
|
]);
|
||||||
$this->addElement($mood);
|
$this->addElement($mood);
|
||||||
|
|
||||||
|
// Add replay gain field
|
||||||
|
$replay_gain = new Zend_Form_Element_Hidden('replay_gain');
|
||||||
|
$replay_gain->class = 'input_text replay_gain_' . $p_id;
|
||||||
|
$replay_gain->setLabel(_('Replay Gain:'))
|
||||||
|
->addDecorator('HtmlTag', ['tag' => 'div', 'style' => 'display:none'])
|
||||||
|
->removeDecorator('Label');
|
||||||
|
$this->addElement($replay_gain);
|
||||||
|
|
||||||
// Add bmp field
|
// Add bmp field
|
||||||
$bpm = new Zend_Form_Element_Text('bpm');
|
$bpm = new Zend_Form_Element_Text('bpm');
|
||||||
$bpm->class = 'input_text';
|
$bpm->class = 'input_text';
|
||||||
|
@ -242,7 +252,7 @@ class Application_Form_EditAudioMD extends Zend_Form
|
||||||
$validCuePattern = '/^(?:[0-9]{1,2}:)?(?:[0-9]{1,2}:)?[0-9]{1,6}(\.\d{1,6})?$/';
|
$validCuePattern = '/^(?:[0-9]{1,2}:)?(?:[0-9]{1,2}:)?[0-9]{1,6}(\.\d{1,6})?$/';
|
||||||
|
|
||||||
$cueIn = new Zend_Form_Element_Text('cuein');
|
$cueIn = new Zend_Form_Element_Text('cuein');
|
||||||
$cueIn->class = 'input_text';
|
$cueIn->class = 'input_text cuein_' . $p_id;
|
||||||
$cueIn->setLabel('Cue In:');
|
$cueIn->setLabel('Cue In:');
|
||||||
$cueInValidator = Application_Form_Helper_ValidationTypes::overrideRegexValidator(
|
$cueInValidator = Application_Form_Helper_ValidationTypes::overrideRegexValidator(
|
||||||
$validCuePattern,
|
$validCuePattern,
|
||||||
|
@ -252,7 +262,7 @@ class Application_Form_EditAudioMD extends Zend_Form
|
||||||
$this->addElement($cueIn);
|
$this->addElement($cueIn);
|
||||||
|
|
||||||
$cueOut = new Zend_Form_Element_Text('cueout');
|
$cueOut = new Zend_Form_Element_Text('cueout');
|
||||||
$cueOut->class = 'input_text';
|
$cueOut->class = 'input_text cueout_' . $p_id;
|
||||||
$cueOut->setLabel('Cue Out:');
|
$cueOut->setLabel('Cue Out:');
|
||||||
$cueOutValidator = Application_Form_Helper_ValidationTypes::overrideRegexValidator(
|
$cueOutValidator = Application_Form_Helper_ValidationTypes::overrideRegexValidator(
|
||||||
$validCuePattern,
|
$validCuePattern,
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
<?php $get_artwork = FileDataHelper::getArtworkData($this->artwork, 256); ?>
|
<?php $get_artwork = FileDataHelper::getArtworkData($this->artwork, 256);
|
||||||
|
|
||||||
|
$baseUrl = Config::getBasePath();
|
||||||
|
|
||||||
|
$get_replay_gain = Application_Model_Preference::getReplayGainModifier();
|
||||||
|
if (!Application_Model_Preference::GetEnableReplayGain() ) {
|
||||||
|
$get_replay_gain = 0;
|
||||||
|
}
|
||||||
|
$analogMeter = true;
|
||||||
|
?>
|
||||||
<div class="ui-widget ui-widget-content block-shadow simple-formblock clearfix padded-strong edit-md-dialog">
|
<div class="ui-widget ui-widget-content block-shadow simple-formblock clearfix padded-strong edit-md-dialog">
|
||||||
<div class="track-edit-header" style="top:15px">
|
<div class="track-edit-header" style="top:15px">
|
||||||
<?php if ($this->permissionDenied) { ?> <h3><?php echo _("You do not have permission to edit this track.") ?></h3> <?php } ?>
|
<?php if ($this->permissionDenied) { ?> <h3><?php echo _("You do not have permission to edit this track.") ?></h3> <?php } ?>
|
||||||
|
@ -36,4 +45,142 @@
|
||||||
</div>
|
</div>
|
||||||
<div style="height: 160px;"></div>
|
<div style="height: 160px;"></div>
|
||||||
<?php echo $this->form; ?>
|
<?php echo $this->form; ?>
|
||||||
|
<div class="collapsible-header closed"><span class="arrow-icon"></span><?php echo _("Visual Waveform Editor"); ?></div>
|
||||||
|
<div class="visual-waveform-editor" style="clear:both;padding:18px 24px 0 0;">
|
||||||
|
<div class="controls">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-7">
|
||||||
|
<div class="btn-toolbar track-toolbar">
|
||||||
|
<div class="btn-group" title="Play Controls">
|
||||||
|
<button class="btn btn-control-player btn-new control-play-btn" id="track-play-<?php echo $this->id; ?>" onClick="wavesurfer['t<?php echo $this->id; ?>'].playPause();" style="background-color:#555555; border-top-left-radius: 5px; border-bottom-left-radius: 5px;">
|
||||||
|
<i class="icon-white icon-play"></i>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-control-player btn-new control-playedit-btn" id="track-playedit-<?php echo $this->id; ?>" onClick="" style="background-color:#555555; border-top-right-radius: 5px; border-bottom-right-radius: 5px">
|
||||||
|
<i class="icon-white icon-step-backward"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="btn-group" title="Playhead">
|
||||||
|
<div class="btn track-timer" style="border-radius: 5px">
|
||||||
|
<input class="track-timer-input" id="tracktimerinput-<?php echo $this->id; ?>" val="0.000" style="font-size:15px; font-weight:500;"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group" title="Cue Controls">
|
||||||
|
<img src="<?php echo $baseUrl.'css/img/icon_cut_white.png';?>" style="top:6px;margin-right:5px;">
|
||||||
|
<button class="btn btn-control-player btn-new" id="cuein-set-<?php echo $this->id; ?>" style="background-color:#00e640; border-top-left-radius: 5px; border-bottom-left-radius: 5px;">
|
||||||
|
<i class="icon-white icon-chevron-right"></i>
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-control-player btn-new" id="cueout-set-<?php echo $this->id; ?>" style="background-color:#f22613; border-top-right-radius: 5px; border-bottom-right-radius: 5px">
|
||||||
|
<i class="icon-white icon-chevron-left"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group pull-right zoom-container" title="Zoom">
|
||||||
|
<i class="icon-white icon-zoom-out" style="margin-top: -24px;"></i>
|
||||||
|
<input id="zoom-slider-<?php echo $this->id; ?>" class="input-slider" data-height="26" data-width="120" data-action="zoom-<?php echo $this->id; ?>" type="range" min="20" max="290" data-sprites="50" data-src="<?php echo $baseUrl.'css/images/slider.png'; ?>" value="0" />
|
||||||
|
<i class="icon-white icon-zoom-in" style="margin-top: -24px;"></i>
|
||||||
|
</div>
|
||||||
|
<br><br>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div id="track-waveform-<?php echo $this->id; ?>"></div>
|
||||||
|
<div id="timeline-<?php echo $this->id; ?>"></div>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" id="volume-<?php echo $this->id; ?>" type="range" min="0" max="1" value="1" step="0.1">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script>
|
||||||
|
//waveform
|
||||||
|
var track_id = <?php echo $this->id; ?>;
|
||||||
|
var selector_id = "#track-waveform-"+<?php echo $this->id; ?>;
|
||||||
|
var url = baseUrl + 'api/get-media/file/<?php echo $this->id; ?>';
|
||||||
|
var cuein = '<?php echo $this->cuein; ?>';
|
||||||
|
var cueout = '<?php echo $this->cueout; ?>';
|
||||||
|
var gain_level = deciSteps(<?php echo $this->replay_gain; ?>);
|
||||||
|
var default_gain = <?php echo $get_replay_gain; ?>;
|
||||||
|
var eTrack = renderWaveform(track_id, selector_id, url, cuein, cueout, gain_level, default_gain);
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
$(".collapsible-header")
|
||||||
|
.off("click")
|
||||||
|
.on("click", function () {
|
||||||
|
$(this).toggleClass("visible");
|
||||||
|
$(".visual-waveform-editor").toggle();
|
||||||
|
$(".editor_pane_wrapper").animate({
|
||||||
|
scrollTop: $(".collapsible-header").offset().top * 2
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Counter field edit
|
||||||
|
$(document).on('change', '#tracktimerinput-<?php echo $this->id; ?>', 'input', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
var val = $(this).val();
|
||||||
|
eTrack.setCurrentTime(val);
|
||||||
|
}).on('keypress keydown', '#tracktimerinput-<?php echo $this->id; ?>', 'input', function(event) {
|
||||||
|
if (event.key === 'Enter' || event.keyCode === 13 || event.keyCode === 10) {
|
||||||
|
var val = $(this).val();
|
||||||
|
eTrack.setCurrentTime(val);
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
event.stopImmediatePropagation();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//Gain Knob
|
||||||
|
$("#volume-<?php echo $this->id; ?>").val(deciSteps(<?php echo $this->replay_gain; ?>));
|
||||||
|
|
||||||
|
$(document).on('change', '.cuein_<?php echo $this->id; ?>', 'input', function(event) {
|
||||||
|
console.log('cuein input');
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
var val = $(this).val();
|
||||||
|
var a = val.split(':');
|
||||||
|
var startseconds = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]);
|
||||||
|
console.log(startseconds);
|
||||||
|
var region = eTrack.regions.list[track_id];
|
||||||
|
region.update({start: startseconds});
|
||||||
|
$('#track-playedit-'+track_id).attr('onClick', 'wavesurfer["t'+ track_id +'"].play('+ region.start +', '+ region.end +');');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('change', '.cueout_<?php echo $this->id; ?>', 'input', function(event) {
|
||||||
|
console.log('cueout input');
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
var val = $(this).val();
|
||||||
|
var b = val.split(':');
|
||||||
|
var endseconds = (+b[0]) * 60 * 60 + (+b[1]) * 60 + (+b[2]);
|
||||||
|
var region = eTrack.regions.list[track_id];
|
||||||
|
region.update({end: endseconds});
|
||||||
|
$('#track-playedit-'+track_id).attr('onClick', 'wavesurfer["t'+ track_id +'"].play('+ region.start +', '+ region.end +');');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#cuein-set-<?php echo $this->id; ?>', 'button', function(event) {
|
||||||
|
console.log('cuein button');
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
var val = eTrack.getCurrentTime();
|
||||||
|
var region = eTrack.regions.list[track_id];
|
||||||
|
region.update({start: val});
|
||||||
|
document.getElementsByClassName("cuein_"+track_id)[0].value = toHHMMSS(region.start);
|
||||||
|
$('#track-playedit-'+track_id).attr('onClick', 'wavesurfer["t'+ track_id +'"].play('+ region.start +', '+ region.end +');');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '#cueout-set-<?php echo $this->id; ?>', 'button', function(event) {
|
||||||
|
console.log('cueout button')
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
var val = eTrack.getCurrentTime();
|
||||||
|
var region = eTrack.regions.list[track_id];
|
||||||
|
region.update({end: val});
|
||||||
|
document.getElementsByClassName("cueout_"+track_id)[0].value = toHHMMSS(region.end);
|
||||||
|
$('#track-playedit-'+track_id).attr('onClick', 'wavesurfer["t'+ track_id +'"].play('+ region.start +', '+ region.end +');');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
BIN
legacy/public/css/images/slider.png
Executable file
BIN
legacy/public/css/images/slider.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 118 KiB |
|
@ -658,7 +658,7 @@ li.spl_empty {
|
||||||
.collapsible-header.visible .arrow-icon {
|
.collapsible-header.visible .arrow-icon {
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
.smart-block-advanced {
|
.smart-block-advanced, .visual-waveform-editor {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.smart-block-form .smart-block-advanced dt {
|
.smart-block-form .smart-block-advanced dt {
|
||||||
|
|
|
@ -4350,3 +4350,95 @@ body.droppable .artwork-upload .artwork-preview {
|
||||||
border: 2px dashed lightblue;
|
border: 2px dashed lightblue;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cue editor GUI starts here */
|
||||||
|
|
||||||
|
.track-file-details {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-window {
|
||||||
|
top: 285px;
|
||||||
|
width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
|
-ms-appearance: none;
|
||||||
|
appearance: none; */
|
||||||
|
textarea,
|
||||||
|
input {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus,
|
||||||
|
select:focus,
|
||||||
|
textarea:focus,
|
||||||
|
button:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navtt {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
margin-left: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navtt > li > a {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navtt-content.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navtt-content.hide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-control-player {
|
||||||
|
padding: 5px 7px 5px 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zoom-container {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-toolbar {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-timer {
|
||||||
|
border-radius: 5px;
|
||||||
|
background-image: none;
|
||||||
|
-webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3), 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||||
|
-moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3), 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||||
|
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3), 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||||
|
/*background-color: #727272;*/
|
||||||
|
outline: 0;
|
||||||
|
border-top-color: #333333;
|
||||||
|
/*background: #246B86;*/
|
||||||
|
|
||||||
|
width: 65px;
|
||||||
|
/*padding: 5px 7px 5px 10px;*/
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
background-color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.track-timer-input {
|
||||||
|
background-color: transparent;
|
||||||
|
border: none;
|
||||||
|
width: 75px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Track Edit - Cue and Gain editor GUI ends here */
|
||||||
|
|
|
@ -1160,8 +1160,8 @@ var AIRTIME = (function (AIRTIME) {
|
||||||
});
|
});
|
||||||
|
|
||||||
newTab.wrapper.find(".edit-md-dialog").on("keyup", function (event) {
|
newTab.wrapper.find(".edit-md-dialog").on("keyup", function (event) {
|
||||||
// Don't submit if the user hits enter in a textarea (description)
|
// Don't submit if the user hits enter in a textarea (description) or in the waveform editor
|
||||||
if ($(event.target).is("input") && event.keyCode === 13) {
|
if ($(event.target).is("form input") && event.keyCode === 13) {
|
||||||
newTab.wrapper.find(".md-save").click();
|
newTab.wrapper.find(".md-save").click();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
404
legacy/public/js/wavesurfer/cursor.js
Normal file
404
legacy/public/js/wavesurfer/cursor.js
Normal file
|
@ -0,0 +1,404 @@
|
||||||
|
/*!
|
||||||
|
* wavesurfer.js cursor plugin 4.6.0 (2024-02-05)
|
||||||
|
* https://wavesurfer-js.org
|
||||||
|
* @license BSD-3-Clause
|
||||||
|
*/
|
||||||
|
(function webpackUniversalModuleDefinition(root, factory) {
|
||||||
|
if(typeof exports === 'object' && typeof module === 'object')
|
||||||
|
module.exports = factory();
|
||||||
|
else if(typeof define === 'function' && define.amd)
|
||||||
|
define("WaveSurfer", [], factory);
|
||||||
|
else if(typeof exports === 'object')
|
||||||
|
exports["WaveSurfer"] = factory();
|
||||||
|
else
|
||||||
|
root["WaveSurfer"] = root["WaveSurfer"] || {}, root["WaveSurfer"]["cursor"] = factory();
|
||||||
|
})(this, () => {
|
||||||
|
return /******/ (() => { // webpackBootstrap
|
||||||
|
/******/ "use strict";
|
||||||
|
/******/ var __webpack_modules__ = ({
|
||||||
|
|
||||||
|
/***/ "./src/plugin/cursor/index.js":
|
||||||
|
/*!************************************!*\
|
||||||
|
!*** ./src/plugin/cursor/index.js ***!
|
||||||
|
\************************************/
|
||||||
|
/***/ ((module, exports) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
||||||
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
||||||
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
||||||
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
||||||
|
/**
|
||||||
|
* @typedef {Object} CursorPluginParams
|
||||||
|
* @property {?boolean} deferInit Set to true to stop auto init in `addPlugin()`
|
||||||
|
* @property {boolean} hideOnBlur=true Hide the cursor when the mouse leaves the
|
||||||
|
* waveform
|
||||||
|
* @property {string} width='1px' The width of the cursor
|
||||||
|
* @property {string} color='black' The color of the cursor
|
||||||
|
* @property {string} opacity='0.25' The opacity of the cursor
|
||||||
|
* @property {string} style='solid' The border style of the cursor
|
||||||
|
* @property {number} zIndex=3 The z-index of the cursor element
|
||||||
|
* @property {object} customStyle An object with custom styles which are applied
|
||||||
|
* to the cursor element
|
||||||
|
* @property {boolean} showTime=false Show the time on the cursor.
|
||||||
|
* @property {object} customShowTimeStyle An object with custom styles which are
|
||||||
|
* applied to the cursor time element.
|
||||||
|
* @property {string} followCursorY=false Use `true` to make the time on
|
||||||
|
* the cursor follow the x and the y-position of the mouse. Use `false` to make the
|
||||||
|
* it only follow the x-position of the mouse.
|
||||||
|
* @property {function} formatTimeCallback Formats the timestamp on the cursor.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Displays a thin line at the position of the cursor on the waveform.
|
||||||
|
*
|
||||||
|
* @implements {PluginClass}
|
||||||
|
* @extends {Observer}
|
||||||
|
* @example
|
||||||
|
* // es6
|
||||||
|
* import CursorPlugin from 'wavesurfer.cursor.js';
|
||||||
|
*
|
||||||
|
* // commonjs
|
||||||
|
* var CursorPlugin = require('wavesurfer.cursor.js');
|
||||||
|
*
|
||||||
|
* // if you are using <script> tags
|
||||||
|
* var CursorPlugin = window.WaveSurfer.cursor;
|
||||||
|
*
|
||||||
|
* // ... initialising wavesurfer with the plugin
|
||||||
|
* var wavesurfer = WaveSurfer.create({
|
||||||
|
* // wavesurfer options ...
|
||||||
|
* plugins: [
|
||||||
|
* CursorPlugin.create({
|
||||||
|
* // plugin options ...
|
||||||
|
* })
|
||||||
|
* ]
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
var CursorPlugin = exports["default"] = /*#__PURE__*/function () {
|
||||||
|
/**
|
||||||
|
* Construct the plugin class. You probably want to use `CursorPlugin.create`
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
|
* @param {CursorPluginParams} params Plugin parameters
|
||||||
|
* @param {object} ws Wavesurfer instance
|
||||||
|
*/
|
||||||
|
function CursorPlugin(params, ws) {
|
||||||
|
var _this = this;
|
||||||
|
_classCallCheck(this, CursorPlugin);
|
||||||
|
this.defaultParams = {
|
||||||
|
hideOnBlur: true,
|
||||||
|
width: '1px',
|
||||||
|
color: 'black',
|
||||||
|
opacity: '0.25',
|
||||||
|
style: 'solid',
|
||||||
|
zIndex: 4,
|
||||||
|
customStyle: {},
|
||||||
|
customShowTimeStyle: {},
|
||||||
|
showTime: false,
|
||||||
|
followCursorY: false,
|
||||||
|
formatTimeCallback: null
|
||||||
|
};
|
||||||
|
this._onMousemove = function (e) {
|
||||||
|
var bbox = _this.wavesurfer.container.getBoundingClientRect();
|
||||||
|
var y = 0;
|
||||||
|
var x = e.clientX - bbox.left;
|
||||||
|
var flip = bbox.right < e.clientX + _this.outerWidth(_this.displayTime);
|
||||||
|
if (_this.params.showTime && _this.params.followCursorY) {
|
||||||
|
// follow y-position of the mouse
|
||||||
|
y = e.clientY - (bbox.top + bbox.height / 2);
|
||||||
|
}
|
||||||
|
_this.updateCursorPosition(x, y, flip);
|
||||||
|
};
|
||||||
|
this._onMouseenter = function () {
|
||||||
|
return _this.showCursor();
|
||||||
|
};
|
||||||
|
this._onMouseleave = function () {
|
||||||
|
return _this.hideCursor();
|
||||||
|
};
|
||||||
|
this.wavesurfer = ws;
|
||||||
|
this.style = ws.util.style;
|
||||||
|
/**
|
||||||
|
* The cursor HTML element
|
||||||
|
*
|
||||||
|
* @type {?HTMLElement}
|
||||||
|
*/
|
||||||
|
this.cursor = null;
|
||||||
|
/**
|
||||||
|
* displays the time next to the cursor
|
||||||
|
*
|
||||||
|
* @type {?HTMLElement}
|
||||||
|
*/
|
||||||
|
this.showTime = null;
|
||||||
|
/**
|
||||||
|
* The html container that will display the time
|
||||||
|
*
|
||||||
|
* @type {?HTMLElement}
|
||||||
|
*/
|
||||||
|
this.displayTime = null;
|
||||||
|
this.params = Object.assign({}, this.defaultParams, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the plugin (used by the Plugin API)
|
||||||
|
*/
|
||||||
|
_createClass(CursorPlugin, [{
|
||||||
|
key: "init",
|
||||||
|
value: function init() {
|
||||||
|
this.wrapper = this.wavesurfer.container;
|
||||||
|
this.cursor = this.wrapper.appendChild(this.style(document.createElement('cursor'), Object.assign({
|
||||||
|
position: 'absolute',
|
||||||
|
zIndex: this.params.zIndex,
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
width: '0',
|
||||||
|
display: 'flex',
|
||||||
|
borderRightStyle: this.params.style,
|
||||||
|
borderRightWidth: this.params.width,
|
||||||
|
borderRightColor: this.params.color,
|
||||||
|
opacity: this.params.opacity,
|
||||||
|
pointerEvents: 'none'
|
||||||
|
}, this.params.customStyle)));
|
||||||
|
if (this.params.showTime) {
|
||||||
|
this.showTime = this.wrapper.appendChild(this.style(document.createElement('showTitle'), Object.assign({
|
||||||
|
position: 'absolute',
|
||||||
|
zIndex: this.params.zIndex,
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
width: 'auto',
|
||||||
|
display: 'flex',
|
||||||
|
opacity: this.params.opacity,
|
||||||
|
pointerEvents: 'none',
|
||||||
|
height: '100%'
|
||||||
|
}, this.params.customStyle)));
|
||||||
|
this.displayTime = this.showTime.appendChild(this.style(document.createElement('div'), Object.assign({
|
||||||
|
display: 'inline',
|
||||||
|
pointerEvents: 'none',
|
||||||
|
margin: 'auto',
|
||||||
|
visibility: 'hidden' // initial value will be hidden just for measuring purpose
|
||||||
|
}, this.params.customShowTimeStyle)));
|
||||||
|
// initial value to measure display width
|
||||||
|
this.displayTime.innerHTML = this.formatTime(0);
|
||||||
|
}
|
||||||
|
this.wrapper.addEventListener('mousemove', this._onMousemove);
|
||||||
|
if (this.params.hideOnBlur) {
|
||||||
|
// ensure elements are hidden initially
|
||||||
|
this.hideCursor();
|
||||||
|
this.wrapper.addEventListener('mouseenter', this._onMouseenter);
|
||||||
|
this.wrapper.addEventListener('mouseleave', this._onMouseleave);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the plugin (used by the Plugin API)
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "destroy",
|
||||||
|
value: function destroy() {
|
||||||
|
if (this.params.showTime) {
|
||||||
|
this.cursor.parentNode.removeChild(this.showTime);
|
||||||
|
}
|
||||||
|
this.cursor.parentNode.removeChild(this.cursor);
|
||||||
|
this.wrapper.removeEventListener('mousemove', this._onMousemove);
|
||||||
|
if (this.params.hideOnBlur) {
|
||||||
|
this.wrapper.removeEventListener('mouseenter', this._onMouseenter);
|
||||||
|
this.wrapper.removeEventListener('mouseleave', this._onMouseleave);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the cursor position
|
||||||
|
*
|
||||||
|
* @param {number} xpos The x offset of the cursor in pixels
|
||||||
|
* @param {number} ypos The y offset of the cursor in pixels
|
||||||
|
* @param {boolean} flip Flag to flip duration text from right to left
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "updateCursorPosition",
|
||||||
|
value: function updateCursorPosition(xpos, ypos) {
|
||||||
|
var flip = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
||||||
|
this.style(this.cursor, {
|
||||||
|
left: "".concat(xpos, "px")
|
||||||
|
});
|
||||||
|
if (this.params.showTime) {
|
||||||
|
var duration = this.wavesurfer.getDuration();
|
||||||
|
var elementWidth = this.wavesurfer.drawer.width / this.wavesurfer.params.pixelRatio;
|
||||||
|
var scrollWidth = this.wavesurfer.drawer.getScrollX();
|
||||||
|
var scrollTime = duration / this.wavesurfer.drawer.width * scrollWidth;
|
||||||
|
var timeValue = Math.max(0, xpos / elementWidth * duration) + scrollTime;
|
||||||
|
var formatValue = this.formatTime(timeValue);
|
||||||
|
if (flip) {
|
||||||
|
var textOffset = this.outerWidth(this.displayTime);
|
||||||
|
xpos -= textOffset;
|
||||||
|
}
|
||||||
|
this.style(this.showTime, {
|
||||||
|
left: "".concat(xpos, "px"),
|
||||||
|
top: "".concat(ypos, "px")
|
||||||
|
});
|
||||||
|
this.style(this.displayTime, {
|
||||||
|
visibility: 'visible'
|
||||||
|
});
|
||||||
|
this.displayTime.innerHTML = "".concat(formatValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the cursor
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "showCursor",
|
||||||
|
value: function showCursor() {
|
||||||
|
this.style(this.cursor, {
|
||||||
|
display: 'flex'
|
||||||
|
});
|
||||||
|
if (this.params.showTime) {
|
||||||
|
this.style(this.showTime, {
|
||||||
|
display: 'flex'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide the cursor
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "hideCursor",
|
||||||
|
value: function hideCursor() {
|
||||||
|
this.style(this.cursor, {
|
||||||
|
display: 'none'
|
||||||
|
});
|
||||||
|
if (this.params.showTime) {
|
||||||
|
this.style(this.showTime, {
|
||||||
|
display: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the timestamp for `cursorTime`.
|
||||||
|
*
|
||||||
|
* @param {number} cursorTime Time in seconds
|
||||||
|
* @returns {string} Formatted timestamp
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "formatTime",
|
||||||
|
value: function formatTime(cursorTime) {
|
||||||
|
cursorTime = isNaN(cursorTime) ? 0 : cursorTime;
|
||||||
|
if (this.params.formatTimeCallback) {
|
||||||
|
return this.params.formatTimeCallback(cursorTime);
|
||||||
|
}
|
||||||
|
return [cursorTime].map(function (time) {
|
||||||
|
return [Math.floor(time % 3600 / 60),
|
||||||
|
// minutes
|
||||||
|
('00' + Math.floor(time % 60)).slice(-2),
|
||||||
|
// seconds
|
||||||
|
('000' + Math.floor(time % 1 * 1000)).slice(-3) // milliseconds
|
||||||
|
].join(':');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get outer width of given element.
|
||||||
|
*
|
||||||
|
* @param {DOM} element DOM Element
|
||||||
|
* @returns {number} outer width
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "outerWidth",
|
||||||
|
value: function outerWidth(element) {
|
||||||
|
if (!element) return 0;
|
||||||
|
var width = element.offsetWidth;
|
||||||
|
var style = getComputedStyle(element);
|
||||||
|
width += parseInt(style.marginLeft + style.marginRight);
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
}], [{
|
||||||
|
key: "create",
|
||||||
|
value:
|
||||||
|
/**
|
||||||
|
* Cursor plugin definition factory
|
||||||
|
*
|
||||||
|
* This function must be used to create a plugin definition which can be
|
||||||
|
* used by wavesurfer to correctly instantiate the plugin.
|
||||||
|
*
|
||||||
|
* @param {CursorPluginParams} params parameters use to initialise the
|
||||||
|
* plugin
|
||||||
|
* @return {PluginDefinition} an object representing the plugin
|
||||||
|
*/
|
||||||
|
function create(params) {
|
||||||
|
return {
|
||||||
|
name: 'cursor',
|
||||||
|
deferInit: params && params.deferInit ? params.deferInit : false,
|
||||||
|
params: params,
|
||||||
|
staticProps: {},
|
||||||
|
instance: CursorPlugin
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {CursorPluginParams}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object} e Mouse move event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
}]);
|
||||||
|
return CursorPlugin;
|
||||||
|
}();
|
||||||
|
module.exports = exports.default;
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
|
||||||
|
/******/ });
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ // The module cache
|
||||||
|
/******/ var __webpack_module_cache__ = {};
|
||||||
|
/******/
|
||||||
|
/******/ // The require function
|
||||||
|
/******/ function __webpack_require__(moduleId) {
|
||||||
|
/******/ // Check if module is in cache
|
||||||
|
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||||
|
/******/ if (cachedModule !== undefined) {
|
||||||
|
/******/ return cachedModule.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/ // Create a new module (and put it into the cache)
|
||||||
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||||
|
/******/ // no module.id needed
|
||||||
|
/******/ // no module.loaded needed
|
||||||
|
/******/ exports: {}
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // Execute the module function
|
||||||
|
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||||
|
/******/
|
||||||
|
/******/ // Return the exports of the module
|
||||||
|
/******/ return module.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/************************************************************************/
|
||||||
|
/******/
|
||||||
|
/******/ // startup
|
||||||
|
/******/ // Load entry module and return exports
|
||||||
|
/******/ // This entry module is referenced by other modules so it can't be inlined
|
||||||
|
/******/ var __webpack_exports__ = __webpack_require__("./src/plugin/cursor/index.js");
|
||||||
|
/******/
|
||||||
|
/******/ return __webpack_exports__;
|
||||||
|
/******/ })()
|
||||||
|
;
|
||||||
|
});
|
||||||
|
//# sourceMappingURL=wavesurfer.cursor.js.map
|
7
legacy/public/js/wavesurfer/cursor.min.js
vendored
Normal file
7
legacy/public/js/wavesurfer/cursor.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
627
legacy/public/js/wavesurfer/libretime.js
Normal file
627
legacy/public/js/wavesurfer/libretime.js
Normal file
|
@ -0,0 +1,627 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var wavesurfer = [];
|
||||||
|
|
||||||
|
window.addEventListener("load",()=>{
|
||||||
|
let op=window.inputKnobsOptions||{};
|
||||||
|
op.knobWidth=op.knobWidth||op.knobDiameter||64;
|
||||||
|
op.knobHeight=op.knobHeight||op.knobDiameter||64;
|
||||||
|
op.sliderWidth=op.sliderWidth||op.sliderDiameter||128;
|
||||||
|
op.sliderHeight=op.sliderHeight||op.sliderDiameter||20;
|
||||||
|
op.switchWidth=op.switchWidth||op.switchDiameter||24;
|
||||||
|
op.switchHeight=op.switchHeight||op.switchDiameter||24;
|
||||||
|
op.fgcolor=op.fgcolor||"#f00";
|
||||||
|
op.bgcolor=op.bgcolor||"#000";
|
||||||
|
op.knobMode=op.knobMode||"linear";
|
||||||
|
op.sliderMode=op.sliderMode||"relative";
|
||||||
|
let styles=document.createElement("style");
|
||||||
|
styles.innerHTML=
|
||||||
|
`input[type=range].input-knob,input[type=range].input-slider{
|
||||||
|
-webkit-appearance:none;
|
||||||
|
-moz-appearance:none;
|
||||||
|
border:none;
|
||||||
|
box-sizing:border-box;
|
||||||
|
overflow:hidden;
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
background-size:100% 100%;
|
||||||
|
background-position:0px 0%;
|
||||||
|
background-color:transparent;
|
||||||
|
touch-action:none;
|
||||||
|
}
|
||||||
|
input[type=range].input-knob{
|
||||||
|
width:${op.knobWidth}px; height:${op.knobHeight}px;
|
||||||
|
}
|
||||||
|
input[type=range].input-slider{
|
||||||
|
width:${op.sliderWidth}px; height:${op.sliderHeight}px;
|
||||||
|
}
|
||||||
|
input[type=range].input-knob::-webkit-slider-thumb,input[type=range].input-slider::-webkit-slider-thumb{
|
||||||
|
-webkit-appearance:none;
|
||||||
|
opacity:0;
|
||||||
|
}
|
||||||
|
input[type=range].input-knob::-moz-range-thumb,input[type=range].input-slider::-moz-range-thumb{
|
||||||
|
-moz-appearance:none;
|
||||||
|
height:0;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
input[type=range].input-knob::-moz-range-track,input[type=range].input-slider::-moz-range-track{
|
||||||
|
-moz-appearance:none;
|
||||||
|
height:0;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
input[type=checkbox].input-switch,input[type=radio].input-switch {
|
||||||
|
width:${op.switchWidth}px;
|
||||||
|
height:${op.switchHeight}px;
|
||||||
|
-webkit-appearance:none;
|
||||||
|
-moz-appearance:none;
|
||||||
|
background-size:100% 200%;
|
||||||
|
background-position:0% 0%;
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
border:none;
|
||||||
|
border-radius:0;
|
||||||
|
background-color:transparent;
|
||||||
|
}
|
||||||
|
input[type=checkbox].input-switch:checked,input[type=radio].input-switch:checked {
|
||||||
|
background-position:0% 100%;
|
||||||
|
}`;
|
||||||
|
document.head.appendChild(styles);
|
||||||
|
let makeKnobFrames=(fr,fg,bg)=>{
|
||||||
|
let r=
|
||||||
|
`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="${fr*64}" viewBox="0 0 64 ${fr*64}" preserveAspectRatio="none">
|
||||||
|
<defs><g id="K"><circle cx="32" cy="32" r="30" fill="${bg}"/>
|
||||||
|
<line x1="32" y1="28" x2="32" y2="7" stroke-linecap="round" stroke-width="6" stroke="${fg}"/></g></defs>
|
||||||
|
<use xlink:href="#K" transform="rotate(-135,32,32)"/>`;
|
||||||
|
for(let i=1;i<fr;++i)
|
||||||
|
r+=`<use xlink:href="#K" transform="translate(0,${64*i}) rotate(${-135+270*i/fr},32,32)"/>`;
|
||||||
|
return r+"</svg>";
|
||||||
|
}
|
||||||
|
let makeHSliderFrames=(fr,fg,bg,w,h)=>{
|
||||||
|
let r=
|
||||||
|
`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${w}" height="${fr*h}" viewBox="0 0 ${w} ${fr*h}" preserveAspectRatio="none">
|
||||||
|
<defs><g id="B"><rect x="0" y="0" width="${w}" height="${h}" rx="${h/2}" ry="${h/2}" fill="${bg}"/></g>
|
||||||
|
<g id="K"><circle x="${w/2}" y="0" r="${h/2*0.9}" fill="${fg}"/></g></defs>`;
|
||||||
|
for(let i=0;i<fr;++i){
|
||||||
|
r+=`<use xlink:href="#B" transform="translate(0,${h*i})"/>`;
|
||||||
|
r+=`<use xlink:href="#K" transform="translate(${h/2+(w-h)*i/100},${h/2+h*i})"/>`;
|
||||||
|
}
|
||||||
|
return r+"</svg>";
|
||||||
|
}
|
||||||
|
let makeVSliderFrames=(fr,fg,bg,w,h)=>{
|
||||||
|
let r=
|
||||||
|
`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${w}" height="${fr*h}" viewBox="0 0 ${w} ${fr*h}" preserveAspectRatio="none">
|
||||||
|
<defs><rect id="B" x="0" y="0" width="${w}" height="${h}" rx="${w/2}" ry="${w/2}" fill="${bg}"/>
|
||||||
|
<circle id="K" x="0" y="0" r="${w/2*0.9}" fill="${fg}"/></defs>`;
|
||||||
|
for(let i=0;i<fr;++i){
|
||||||
|
r+=`<use xlink:href="#B" transform="translate(0,${h*i})"/>`;
|
||||||
|
r+=`<use xlink:href="#K" transform="translate(${w/2} ${h*(i+1)-w/2-i*(h-w)/100})"/>`;
|
||||||
|
}
|
||||||
|
return r+"</svg>";
|
||||||
|
}
|
||||||
|
let initSwitches=(el)=>{
|
||||||
|
let w,h,d,fg,bg;
|
||||||
|
if(el.inputKnobs)
|
||||||
|
return;
|
||||||
|
el.inputKnobs={};
|
||||||
|
el.refresh=()=>{
|
||||||
|
let src=el.getAttribute("data-src");
|
||||||
|
d=+el.getAttribute("data-diameter");
|
||||||
|
let st=document.defaultView.getComputedStyle(el,null);
|
||||||
|
w=parseFloat(el.getAttribute("data-width")||d||st.width);
|
||||||
|
h=parseFloat(el.getAttribute("data-height")||d||st.height);
|
||||||
|
bg=el.getAttribute("data-bgcolor")||op.bgcolor;
|
||||||
|
fg=el.getAttribute("data-fgcolor")||op.fgcolor;
|
||||||
|
el.style.width=w+"px";
|
||||||
|
el.style.height=h+"px";
|
||||||
|
if(src)
|
||||||
|
el.style.backgroundImage="url("+src+")";
|
||||||
|
else {
|
||||||
|
let minwh=Math.min(w,h);
|
||||||
|
let svg=
|
||||||
|
`<svg xmlns="http://www.w3.org/2000/svg" width="${w}" height="${h*2}" viewBox="0 0 ${w} ${h*2}" preserveAspectRatio="none">
|
||||||
|
<g><rect fill="${bg}" x="1" y="1" width="${w-2}" height="${h-2}" rx="${minwh*0.25}" ry="${minwh*0.25}"/>
|
||||||
|
<rect fill="${bg}" x="1" y="${h+1}" width="${w-2}" height="${h-2}" rx="${minwh*0.25}" ry="${minwh*0.25}"/>
|
||||||
|
<circle fill="${fg}" cx="${w*0.5}" cy="${h*1.5}" r="${minwh*0.25}"/></g></svg>`;
|
||||||
|
el.style.backgroundImage="url(data:image/svg+xml;base64,"+btoa(svg)+")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
el.refresh();
|
||||||
|
};
|
||||||
|
let initKnobs=(el)=>{
|
||||||
|
let w,h,d,fg,bg;
|
||||||
|
if(el.inputKnobs){
|
||||||
|
el.redraw();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let ik=el.inputKnobs={};
|
||||||
|
el.refresh=()=>{
|
||||||
|
d=+el.getAttribute("data-diameter");
|
||||||
|
let st=document.defaultView.getComputedStyle(el,null);
|
||||||
|
w=parseFloat(el.getAttribute("data-width")||d||st.width);
|
||||||
|
h=parseFloat(el.getAttribute("data-height")||d||st.height);
|
||||||
|
bg=el.getAttribute("data-bgcolor")||op.bgcolor;
|
||||||
|
fg=el.getAttribute("data-fgcolor")||op.fgcolor;
|
||||||
|
ik.sensex=ik.sensey=200;
|
||||||
|
if(el.className.indexOf("input-knob")>=0)
|
||||||
|
ik.itype="k";
|
||||||
|
else{
|
||||||
|
if(w>=h){
|
||||||
|
ik.itype="h";
|
||||||
|
ik.sensex=w-h;
|
||||||
|
ik.sensey=Infinity;
|
||||||
|
el.style.backgroundSize="auto 100%";
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
ik.itype="v";
|
||||||
|
ik.sensex="Infinity";
|
||||||
|
ik.sensey=h-w;
|
||||||
|
el.style.backgroundSize="100% auto";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
el.style.width=w+"px";
|
||||||
|
el.style.height=h+"px";
|
||||||
|
ik.frameheight=h;
|
||||||
|
let src=el.getAttribute("data-src");
|
||||||
|
if(src){
|
||||||
|
el.style.backgroundImage=`url(${src})`;
|
||||||
|
let sp=+el.getAttribute("data-sprites");
|
||||||
|
if(sp)
|
||||||
|
ik.sprites=sp;
|
||||||
|
else
|
||||||
|
ik.sprites=0;
|
||||||
|
if(ik.sprites>=1)
|
||||||
|
el.style.backgroundSize=`100% ${(ik.sprites+1)*100}%`;
|
||||||
|
else if(ik.itype!="k"){
|
||||||
|
el.style.backgroundColor=bg;
|
||||||
|
el.style.borderRadius=Math.min(w,h)*0.25+"px";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
let svg;
|
||||||
|
switch(ik.itype){
|
||||||
|
case "k": svg=makeKnobFrames(101,fg,bg); break;
|
||||||
|
case "h": svg=makeHSliderFrames(101,fg,bg,w,h); break;
|
||||||
|
case "v": svg=makeVSliderFrames(101,fg,bg,w,h); break;
|
||||||
|
}
|
||||||
|
ik.sprites=100;
|
||||||
|
el.style.backgroundImage="url(data:image/svg+xml;base64,"+btoa(svg)+")";
|
||||||
|
el.style.backgroundSize=`100% ${(ik.sprites+1)*100}%`;
|
||||||
|
}
|
||||||
|
ik.valrange={min:+el.min, max:(el.max=="")?100:+el.max, step:(el.step=="")?1:+el.step};
|
||||||
|
el.redraw(true);
|
||||||
|
};
|
||||||
|
el.setValue=(v)=>{
|
||||||
|
v=(Math.round((v-ik.valrange.min)/ik.valrange.step))*ik.valrange.step+ik.valrange.min;
|
||||||
|
if(v<ik.valrange.min) v=ik.valrange.min;
|
||||||
|
if(v>ik.valrange.max) v=ik.valrange.max;
|
||||||
|
el.value=v;
|
||||||
|
if(el.value!=ik.oldvalue){
|
||||||
|
el.setAttribute("value",el.value);
|
||||||
|
el.redraw();
|
||||||
|
let event=document.createEvent("HTMLEvents");
|
||||||
|
event.initEvent("input",false,true);
|
||||||
|
el.dispatchEvent(event);
|
||||||
|
ik.oldvalue=el.value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ik.pointerdown=(ev)=>{
|
||||||
|
el.focus();
|
||||||
|
if(ev.touches)
|
||||||
|
ev = ev.touches[0];
|
||||||
|
let rc=el.getBoundingClientRect();
|
||||||
|
let cx=(rc.left+rc.right)*0.5,cy=(rc.top+rc.bottom)*0.5;
|
||||||
|
let dx=ev.clientX,dy=ev.clientY;
|
||||||
|
let da=Math.atan2(ev.clientX-cx,cy-ev.clientY);
|
||||||
|
if(ik.itype=="k"&&op.knobMode=="circularabs"){
|
||||||
|
dv=ik.valrange.min+(da/Math.PI*0.75+0.5)*(ik.valrange.max-ik.valrange.min);
|
||||||
|
el.setValue(dv);
|
||||||
|
}
|
||||||
|
if(ik.itype!="k"&&op.sliderMode=="abs"){
|
||||||
|
dv=(ik.valrange.min+ik.valrange.max)*0.5+((dx-cx)/ik.sensex-(dy-cy)/ik.sensey)*(ik.valrange.max-ik.valrange.min);
|
||||||
|
el.setValue(dv);
|
||||||
|
}
|
||||||
|
ik.dragfrom={x:ev.clientX,y:ev.clientY,a:Math.atan2(ev.clientX-cx,cy-ev.clientY),v:+el.value};
|
||||||
|
document.addEventListener("mousemove",ik.pointermove);
|
||||||
|
document.addEventListener("mouseup",ik.pointerup);
|
||||||
|
document.addEventListener("touchmove",ik.pointermove);
|
||||||
|
document.addEventListener("touchend",ik.pointerup);
|
||||||
|
document.addEventListener("touchcancel",ik.pointerup);
|
||||||
|
document.addEventListener("touchstart",ik.preventScroll);
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
};
|
||||||
|
ik.pointermove=(ev)=>{
|
||||||
|
let dv;
|
||||||
|
let rc=el.getBoundingClientRect();
|
||||||
|
let cx=(rc.left+rc.right)*0.5,cy=(rc.top+rc.bottom)*0.5;
|
||||||
|
if(ev.touches)
|
||||||
|
ev = ev.touches[0];
|
||||||
|
let dx=ev.clientX-ik.dragfrom.x,dy=ev.clientY-ik.dragfrom.y;
|
||||||
|
let da=Math.atan2(ev.clientX-cx,cy-ev.clientY);
|
||||||
|
switch(ik.itype){
|
||||||
|
case "k":
|
||||||
|
switch(op.knobMode){
|
||||||
|
case "linear":
|
||||||
|
dv=(dx/ik.sensex-dy/ik.sensey)*(ik.valrange.max-ik.valrange.min);
|
||||||
|
if(ev.shiftKey)
|
||||||
|
dv*=0.2;
|
||||||
|
el.setValue(ik.dragfrom.v+dv);
|
||||||
|
break;
|
||||||
|
case "circularabs":
|
||||||
|
if(!ev.shiftKey){
|
||||||
|
dv=ik.valrange.min+(da/Math.PI*0.75+0.5)*(ik.valrange.max-ik.valrange.min);
|
||||||
|
el.setValue(dv);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "circularrel":
|
||||||
|
if(da>ik.dragfrom.a+Math.PI) da-=Math.PI*2;
|
||||||
|
if(da<ik.dragfrom.a-Math.PI) da+=Math.PI*2;
|
||||||
|
da-=ik.dragfrom.a;
|
||||||
|
dv=da/Math.PI/1.5*(ik.valrange.max-ik.valrange.min);
|
||||||
|
if(ev.shiftKey)
|
||||||
|
dv*=0.2;
|
||||||
|
el.setValue(ik.dragfrom.v+dv);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "h":
|
||||||
|
case "v":
|
||||||
|
dv=(dx/ik.sensex-dy/ik.sensey)*(ik.valrange.max-ik.valrange.min);
|
||||||
|
if(ev.shiftKey)
|
||||||
|
dv*=0.2;
|
||||||
|
el.setValue(ik.dragfrom.v+dv);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ik.pointerup=()=>{
|
||||||
|
document.removeEventListener("mousemove",ik.pointermove);
|
||||||
|
document.removeEventListener("touchmove",ik.pointermove);
|
||||||
|
document.removeEventListener("mouseup",ik.pointerup);
|
||||||
|
document.removeEventListener("touchend",ik.pointerup);
|
||||||
|
document.removeEventListener("touchcancel",ik.pointerup);
|
||||||
|
document.removeEventListener("touchstart",ik.preventScroll);
|
||||||
|
let event=document.createEvent("HTMLEvents");
|
||||||
|
event.initEvent("change",false,true);
|
||||||
|
el.dispatchEvent(event);
|
||||||
|
};
|
||||||
|
ik.preventScroll=(ev)=>{
|
||||||
|
ev.preventDefault();
|
||||||
|
};
|
||||||
|
ik.keydown=()=>{
|
||||||
|
el.redraw();
|
||||||
|
};
|
||||||
|
ik.wheel=(ev)=>{
|
||||||
|
let delta=ev.deltaY>0?-ik.valrange.step:ik.valrange.step;
|
||||||
|
if(!ev.shiftKey)
|
||||||
|
delta*=5;
|
||||||
|
el.setValue(+el.value+delta);
|
||||||
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
};
|
||||||
|
el.redraw=(f)=>{
|
||||||
|
if(f||ik.valueold!=el.value){
|
||||||
|
let v=(el.value-ik.valrange.min)/(ik.valrange.max-ik.valrange.min);
|
||||||
|
if(ik.sprites>=1)
|
||||||
|
el.style.backgroundPosition="0px "+(-((v*ik.sprites)|0)*ik.frameheight)+"px";
|
||||||
|
else{
|
||||||
|
switch(ik.itype){
|
||||||
|
case "k":
|
||||||
|
el.style.transform="rotate("+(270*v-135)+"deg)";
|
||||||
|
break;
|
||||||
|
case "h":
|
||||||
|
el.style.backgroundPosition=((w-h)*v)+"px 0px";
|
||||||
|
break;
|
||||||
|
case "v":
|
||||||
|
el.style.backgroundPosition="0px "+(h-w)*(1-v)+"px";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ik.valueold=el.value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
el.refresh();
|
||||||
|
el.redraw(true);
|
||||||
|
el.addEventListener("keydown",ik.keydown);
|
||||||
|
el.addEventListener("mousedown",ik.pointerdown);
|
||||||
|
el.addEventListener("touchstart",ik.pointerdown);
|
||||||
|
el.addEventListener("wheel",function (event){ event.stopPropagation(); }); //previous: el.addEventListener("wheel",ik.wheel); Maybe optional, can accidently move knob if allowed
|
||||||
|
el.addEventListener("click",function (event){ event.stopPropagation(); });
|
||||||
|
}
|
||||||
|
let refreshque=()=>{
|
||||||
|
let elem=document.querySelectorAll("input.input-knob,input.input-slider");
|
||||||
|
for(let i=0;i<elem.length;++i)
|
||||||
|
procque.push([initKnobs,elem[i]]);
|
||||||
|
elem=document.querySelectorAll("input[type=checkbox].input-switch,input[type=radio].input-switch");
|
||||||
|
for(let i=0;i<elem.length;++i){
|
||||||
|
procque.push([initSwitches,elem[i]]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let procque=[];
|
||||||
|
refreshque();
|
||||||
|
setInterval(()=>{
|
||||||
|
for(let i=0;procque.length>0&&i<8;++i){
|
||||||
|
let q=procque.shift();
|
||||||
|
q[0](q[1]);
|
||||||
|
}
|
||||||
|
if(procque.length<=0)
|
||||||
|
refreshque();
|
||||||
|
},50);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Used for converting back to HH-MM-SS, Cuein and Cueout
|
||||||
|
function toHHMMSS(secs) {
|
||||||
|
let totalSeconds = secs;
|
||||||
|
let hours = Math.floor(totalSeconds / 3600);
|
||||||
|
totalSeconds %= 3600;
|
||||||
|
let minutes = Math.floor(totalSeconds / 60);
|
||||||
|
let seconds = totalSeconds % 60;
|
||||||
|
|
||||||
|
// If you want strings with leading zeroes:
|
||||||
|
minutes = String(minutes).padStart(2, "0");
|
||||||
|
hours = String(hours).padStart(2, "0");
|
||||||
|
seconds = String(seconds).padStart(2, "0");
|
||||||
|
return(hours + ":" + minutes + ":" + seconds.slice(0, 6));
|
||||||
|
}
|
||||||
|
|
||||||
|
//outputs gain percentage from decibels
|
||||||
|
function deciNum(value){
|
||||||
|
const decibels = Math.exp(value / 8.6858);
|
||||||
|
return 50 * decibels;
|
||||||
|
}
|
||||||
|
|
||||||
|
//outputs decibel from gain
|
||||||
|
function gainNum(perc, minDb, maxDb, minP, maxP){
|
||||||
|
const getPerc = (db) => (Math.round(1000000000 * Math.pow(10, db / 20)) / 10000000);
|
||||||
|
const maxPerc = maxP || (_.isNumber(maxDb) && getPerc(maxDb)) || 100;
|
||||||
|
const minPerc = minP || (_.isNumber(minDb) && getPerc(minDb)) || 0;
|
||||||
|
const range = maxPerc - minPerc;
|
||||||
|
const newPerc = (range / 50) * perc;
|
||||||
|
const total = Math.round(1000000000 * 20 * (Math.log(newPerc * 0.01) / Math.log(10))) / 1000000000;
|
||||||
|
return total.toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//outputs steps from decibels
|
||||||
|
function deciSteps(value){
|
||||||
|
//convert decibel to gain/percent
|
||||||
|
const percent = deciNum(value);
|
||||||
|
var result = percent / 100;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTimeCallback(seconds, pxPerSec) {
|
||||||
|
|
||||||
|
seconds = Number(seconds);
|
||||||
|
|
||||||
|
//alert(seconds);
|
||||||
|
var minutes = Math.floor(seconds / 60);
|
||||||
|
seconds = seconds % 60;
|
||||||
|
|
||||||
|
// fill up seconds with zeroes
|
||||||
|
var secondsStr = Math.round(seconds).toString();
|
||||||
|
if (pxPerSec >= 25 * 10) {
|
||||||
|
secondsStr = seconds.toFixed(2);
|
||||||
|
} else if (pxPerSec >= 25 * 1) {
|
||||||
|
secondsStr = seconds.toFixed(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minutes > 0) {
|
||||||
|
if (seconds < 10) {
|
||||||
|
secondsStr = '0' + secondsStr;
|
||||||
|
}
|
||||||
|
return `${minutes}:${secondsStr}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return secondsStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use timeInterval to set the period between notches, in seconds,
|
||||||
|
* adding notches as the number of pixels per second increases.
|
||||||
|
*
|
||||||
|
* Note that if you override the default function, you'll almost
|
||||||
|
* certainly want to override formatTimeCallback, primaryLabelInterval
|
||||||
|
* and/or secondaryLabelInterval so they all work together.
|
||||||
|
*
|
||||||
|
* @param: pxPerSec
|
||||||
|
*/
|
||||||
|
function timeInterval(pxPerSec) {
|
||||||
|
var retval = 1;
|
||||||
|
if (pxPerSec >= 25 * 100) {
|
||||||
|
retval = 0.01;
|
||||||
|
} else if (pxPerSec >= 25 * 40) {
|
||||||
|
retval = 0.025;
|
||||||
|
} else if (pxPerSec >= 25 * 10) {
|
||||||
|
retval = 0.1;
|
||||||
|
} else if (pxPerSec >= 25 * 4) {
|
||||||
|
retval = 0.25;
|
||||||
|
} else if (pxPerSec >= 25) {
|
||||||
|
retval = 1;
|
||||||
|
} else if (pxPerSec * 5 >= 25) {
|
||||||
|
retval = 5;
|
||||||
|
} else if (pxPerSec * 15 >= 25) {
|
||||||
|
retval = 15;
|
||||||
|
} else {
|
||||||
|
retval = Math.ceil(0.5 / pxPerSec) * 60;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the cadence of notches that get labels in the primary color.
|
||||||
|
* EG, return 2 if every 2nd notch should be labeled,
|
||||||
|
* return 10 if every 10th notch should be labeled, etc.
|
||||||
|
*
|
||||||
|
* Note that if you override the default function, you'll almost
|
||||||
|
* certainly want to override formatTimeCallback, primaryLabelInterval
|
||||||
|
* and/or secondaryLabelInterval so they all work together.
|
||||||
|
*
|
||||||
|
* @param pxPerSec
|
||||||
|
*/
|
||||||
|
function primaryLabelInterval(pxPerSec) {
|
||||||
|
var retval = 1;
|
||||||
|
if (pxPerSec >= 25 * 100) {
|
||||||
|
retval = 10;
|
||||||
|
} else if (pxPerSec >= 25 * 40) {
|
||||||
|
retval = 4;
|
||||||
|
} else if (pxPerSec >= 25 * 10) {
|
||||||
|
retval = 10;
|
||||||
|
} else if (pxPerSec >= 25 * 4) {
|
||||||
|
retval = 4;
|
||||||
|
} else if (pxPerSec >= 25) {
|
||||||
|
retval = 1;
|
||||||
|
} else if (pxPerSec * 5 >= 25) {
|
||||||
|
retval = 5;
|
||||||
|
} else if (pxPerSec * 15 >= 25) {
|
||||||
|
retval = 15;
|
||||||
|
} else {
|
||||||
|
retval = Math.ceil(0.5 / pxPerSec) * 60;
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the cadence of notches to get labels in the secondary color.
|
||||||
|
* EG, return 2 if every 2nd notch should be labeled,
|
||||||
|
* return 10 if every 10th notch should be labeled, etc.
|
||||||
|
*
|
||||||
|
* Secondary labels are drawn after primary labels, so if
|
||||||
|
* you want to have labels every 10 seconds and another color labels
|
||||||
|
* every 60 seconds, the 60 second labels should be the secondaries.
|
||||||
|
*
|
||||||
|
* Note that if you override the default function, you'll almost
|
||||||
|
* certainly want to override formatTimeCallback, primaryLabelInterval
|
||||||
|
* and/or secondaryLabelInterval so they all work together.
|
||||||
|
*
|
||||||
|
* @param pxPerSec
|
||||||
|
*/
|
||||||
|
function secondaryLabelInterval(pxPerSec) {
|
||||||
|
// draw one every 10s as an example
|
||||||
|
return Math.floor(10 / timeInterval(pxPerSec));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function renderWaveform(track_id, selector_id, url, cuein, cueout, gain_level, default_gain) {
|
||||||
|
|
||||||
|
var trackid = "t"+track_id;
|
||||||
|
var a = cuein.split(':'); // split it at the colons
|
||||||
|
var b = cueout.split(':'); // split it at the colons
|
||||||
|
var startseconds = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]);
|
||||||
|
var endseconds = (+b[0]) * 60 * 60 + (+b[1]) * 60 + (+b[2]);
|
||||||
|
|
||||||
|
$('#track-playedit-'+track_id).attr('onClick', 'wavesurfer["'+ trackid +'"].play('+ startseconds +', '+endseconds+');');
|
||||||
|
|
||||||
|
wavesurfer[trackid] = WaveSurfer.create({
|
||||||
|
container: document.querySelector(selector_id),
|
||||||
|
waveColor: 'hsla(0, 0%, 50%, 0.8)',
|
||||||
|
backgroundColor: '#333',
|
||||||
|
progressColor: 'hsla(0, 0%, 0%, 0)',
|
||||||
|
backend: 'MediaElementWebAudio',
|
||||||
|
height: 70,
|
||||||
|
cursorColor: '#ccc',
|
||||||
|
cursorWidth: 1,
|
||||||
|
responsive: true,
|
||||||
|
scrollParent: true,
|
||||||
|
minimap: true,
|
||||||
|
autoCenter: true,
|
||||||
|
splitChannels: true,
|
||||||
|
plugins: [
|
||||||
|
WaveSurfer.regions.create({
|
||||||
|
regions: [
|
||||||
|
{
|
||||||
|
id: track_id,
|
||||||
|
start: startseconds,
|
||||||
|
end: endseconds,
|
||||||
|
loop: false,
|
||||||
|
drag: false,
|
||||||
|
color: 'hsla(232, 64%, 50%, 0.2)',
|
||||||
|
handleStyle: {
|
||||||
|
left: {
|
||||||
|
backgroundColor: '#00e640',
|
||||||
|
width: '2px',
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
backgroundColor: '#f22613',
|
||||||
|
width: '2px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}),
|
||||||
|
WaveSurfer.timeline.create({
|
||||||
|
container: "#timeline-"+ track_id,
|
||||||
|
formatTimeCallback: formatTimeCallback,
|
||||||
|
timeInterval: timeInterval,
|
||||||
|
primaryLabelInterval: primaryLabelInterval,
|
||||||
|
secondaryLabelInterval: secondaryLabelInterval,
|
||||||
|
primaryColor: '#ff611f',
|
||||||
|
secondaryColor: '#cccccc',
|
||||||
|
primaryFontColor: '#ff611f',
|
||||||
|
secondaryFontColor: '#cccccc'
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
var eTrack = wavesurfer[trackid];
|
||||||
|
eTrack.load(url);
|
||||||
|
|
||||||
|
// Zoom slider
|
||||||
|
var slider = document.querySelector('[data-action="zoom-'+track_id+'"]');
|
||||||
|
slider.value = eTrack.params.minPxPerSec;
|
||||||
|
slider.min = eTrack.params.minPxPerSec;
|
||||||
|
slider.addEventListener('input', function() {
|
||||||
|
eTrack.zoom(Number(this.value));
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('tracktimerinput-'+track_id).value='0.000';
|
||||||
|
|
||||||
|
eTrack.on('audioprocess', function (e) {
|
||||||
|
document.getElementById('tracktimerinput-'+track_id).value=(eTrack.getCurrentTime().toFixed(3));
|
||||||
|
});
|
||||||
|
|
||||||
|
var playPause = document.getElementById('track-play-'+track_id);
|
||||||
|
eTrack.on('play', function () {
|
||||||
|
//var playButton = document.getElementById('track-play-'+track_id);
|
||||||
|
playPause.style.backgroundColor = "#32CD32";
|
||||||
|
});
|
||||||
|
eTrack.on('pause', function () {
|
||||||
|
//var pauseButton = document.getElementById('track-play-'+track_id);
|
||||||
|
playPause.style.backgroundColor = "#555555";
|
||||||
|
});
|
||||||
|
eTrack.on('error', function(e) {
|
||||||
|
console.warn(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
function saveCue() {
|
||||||
|
var region = eTrack.regions.list[track_id];
|
||||||
|
document.getElementsByClassName("cuein_"+track_id)[0].value = toHHMMSS(region.start);
|
||||||
|
document.getElementsByClassName("cueout_"+track_id)[0].value = toHHMMSS(region.end);
|
||||||
|
$('#track-playedit-'+track_id).attr('onClick', 'wavesurfer["t'+ track_id +'"].play('+ region.start +', '+ region.end +');');
|
||||||
|
|
||||||
|
return {
|
||||||
|
start: region.start,
|
||||||
|
end: region.end
|
||||||
|
};
|
||||||
|
}
|
||||||
|
eTrack.on('ready', () => {
|
||||||
|
eTrack.on('region-update-end', saveCue);
|
||||||
|
});
|
||||||
|
|
||||||
|
eTrack.on('region-in', function(e) {
|
||||||
|
document.getElementById('tracktimerinput-'+track_id).style.color = "rgb(56, 232, 56)";
|
||||||
|
});
|
||||||
|
eTrack.on('region-out', function(e) {
|
||||||
|
document.getElementById('tracktimerinput-'+track_id).style.color = "#ffffff";
|
||||||
|
});
|
||||||
|
|
||||||
|
//Volume to Gain deciSteps(gainNum(gain_level))
|
||||||
|
eTrack.setVolume(0.6);
|
||||||
|
|
||||||
|
document.querySelector("#volume-"+ track_id).value = eTrack.getVolume();
|
||||||
|
|
||||||
|
var volumeInput = document.querySelector("#volume-"+ track_id);
|
||||||
|
|
||||||
|
var onChangeVolume = function (e) {
|
||||||
|
//eTrack.setVolume(e.target.value);
|
||||||
|
};
|
||||||
|
volumeInput.addEventListener('input', onChangeVolume);
|
||||||
|
volumeInput.addEventListener('change', onChangeVolume);
|
||||||
|
|
||||||
|
return eTrack;
|
||||||
|
}
|
424
legacy/public/js/wavesurfer/minimap.js
Normal file
424
legacy/public/js/wavesurfer/minimap.js
Normal file
|
@ -0,0 +1,424 @@
|
||||||
|
/*!
|
||||||
|
* wavesurfer.js minimap plugin 4.6.0 (2024-02-05)
|
||||||
|
* https://wavesurfer-js.org
|
||||||
|
* @license BSD-3-Clause
|
||||||
|
*/
|
||||||
|
(function webpackUniversalModuleDefinition(root, factory) {
|
||||||
|
if(typeof exports === 'object' && typeof module === 'object')
|
||||||
|
module.exports = factory();
|
||||||
|
else if(typeof define === 'function' && define.amd)
|
||||||
|
define("WaveSurfer", [], factory);
|
||||||
|
else if(typeof exports === 'object')
|
||||||
|
exports["WaveSurfer"] = factory();
|
||||||
|
else
|
||||||
|
root["WaveSurfer"] = root["WaveSurfer"] || {}, root["WaveSurfer"]["minimap"] = factory();
|
||||||
|
})(this, () => {
|
||||||
|
return /******/ (() => { // webpackBootstrap
|
||||||
|
/******/ "use strict";
|
||||||
|
/******/ var __webpack_modules__ = ({
|
||||||
|
|
||||||
|
/***/ "./src/plugin/minimap/index.js":
|
||||||
|
/*!*************************************!*\
|
||||||
|
!*** ./src/plugin/minimap/index.js ***!
|
||||||
|
\*************************************/
|
||||||
|
/***/ ((module, exports) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
||||||
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
||||||
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
||||||
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
||||||
|
/*eslint no-console: ["error", { allow: ["warn"] }] */
|
||||||
|
/**
|
||||||
|
* @typedef {Object} MinimapPluginParams
|
||||||
|
* @desc Extends the `WavesurferParams` wavesurfer was initialised with
|
||||||
|
* @property {?string|HTMLElement} container CSS selector or HTML element where
|
||||||
|
* the map should be rendered. By default it is simply appended
|
||||||
|
* after the waveform.
|
||||||
|
* @property {?boolean} deferInit Set to true to manually call
|
||||||
|
* `initPlugin('minimap')`
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Renders a smaller version waveform as a minimap of the main waveform.
|
||||||
|
*
|
||||||
|
* @implements {PluginClass}
|
||||||
|
* @extends {Observer}
|
||||||
|
* @example
|
||||||
|
* // es6
|
||||||
|
* import MinimapPlugin from 'wavesurfer.minimap.js';
|
||||||
|
*
|
||||||
|
* // commonjs
|
||||||
|
* var MinimapPlugin = require('wavesurfer.minimap.js');
|
||||||
|
*
|
||||||
|
* // if you are using <script> tags
|
||||||
|
* var MinimapPlugin = window.WaveSurfer.minimap;
|
||||||
|
*
|
||||||
|
* // ... initialising wavesurfer with the plugin
|
||||||
|
* var wavesurfer = WaveSurfer.create({
|
||||||
|
* // wavesurfer options ...
|
||||||
|
* plugins: [
|
||||||
|
* MinimapPlugin.create({
|
||||||
|
* // plugin options ...
|
||||||
|
* })
|
||||||
|
* ]
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
var MinimapPlugin = exports["default"] = /*#__PURE__*/function () {
|
||||||
|
function MinimapPlugin(params, ws) {
|
||||||
|
var _this = this;
|
||||||
|
_classCallCheck(this, MinimapPlugin);
|
||||||
|
this.params = Object.assign({}, ws.params, {
|
||||||
|
showRegions: false,
|
||||||
|
regionsPluginName: params.regionsPluginName || 'regions',
|
||||||
|
showOverview: false,
|
||||||
|
overviewBorderColor: 'green',
|
||||||
|
overviewBorderSize: 2,
|
||||||
|
// the container should be different
|
||||||
|
container: false,
|
||||||
|
height: Math.max(Math.round(ws.params.height / 4), 20)
|
||||||
|
}, params, {
|
||||||
|
scrollParent: false,
|
||||||
|
fillParent: true
|
||||||
|
});
|
||||||
|
// if container is a selector, get the element
|
||||||
|
if (typeof params.container === 'string') {
|
||||||
|
var el = document.querySelector(params.container);
|
||||||
|
if (!el) {
|
||||||
|
console.warn("Wavesurfer minimap container ".concat(params.container, " was not found! The minimap will be automatically appended below the waveform."));
|
||||||
|
}
|
||||||
|
this.params.container = el;
|
||||||
|
}
|
||||||
|
// if no container is specified add a new element and insert it
|
||||||
|
if (!params.container) {
|
||||||
|
this.params.container = ws.util.style(document.createElement('minimap'), {
|
||||||
|
display: 'block'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.drawer = new ws.Drawer(this.params.container, this.params);
|
||||||
|
this.wavesurfer = ws;
|
||||||
|
this.util = ws.util;
|
||||||
|
/**
|
||||||
|
* Minimap needs to listen for the `ready` and `waveform-ready` events
|
||||||
|
* to work with the `MediaElement` backend. The moment the `ready` event
|
||||||
|
* is called is different (and peaks would not load).
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @see https://github.com/katspaugh/wavesurfer.js/issues/736
|
||||||
|
*/
|
||||||
|
this.renderEvent = ws.params.backend === 'MediaElement' ? 'waveform-ready' : 'ready';
|
||||||
|
this.overviewRegion = null;
|
||||||
|
this.regionsPlugin = this.wavesurfer[this.params.regionsPluginName];
|
||||||
|
this.drawer.createWrapper();
|
||||||
|
this.createElements();
|
||||||
|
var isInitialised = false;
|
||||||
|
|
||||||
|
// ws ready event listener
|
||||||
|
this._onShouldRender = function () {
|
||||||
|
// only bind the events in the first run
|
||||||
|
if (!isInitialised) {
|
||||||
|
_this.bindWavesurferEvents();
|
||||||
|
_this.bindMinimapEvents();
|
||||||
|
isInitialised = true;
|
||||||
|
}
|
||||||
|
// if there is no such element, append it to the container (below
|
||||||
|
// the waveform)
|
||||||
|
if (!document.body.contains(_this.params.container)) {
|
||||||
|
ws.container.insertBefore(_this.params.container, null);
|
||||||
|
}
|
||||||
|
if (_this.regionsPlugin && _this.params.showRegions) {
|
||||||
|
_this.regions();
|
||||||
|
}
|
||||||
|
_this.render();
|
||||||
|
};
|
||||||
|
this._onAudioprocess = function (currentTime) {
|
||||||
|
_this.drawer.progress(_this.wavesurfer.backend.getPlayedPercents());
|
||||||
|
};
|
||||||
|
|
||||||
|
// ws seek event listener
|
||||||
|
this._onSeek = function () {
|
||||||
|
return _this.drawer.progress(ws.backend.getPlayedPercents());
|
||||||
|
};
|
||||||
|
|
||||||
|
// event listeners for the overview region
|
||||||
|
this._onScroll = function (e) {
|
||||||
|
if (!_this.draggingOverview) {
|
||||||
|
_this.moveOverviewRegion(e.target.scrollLeft / _this.ratio);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this._onMouseover = function (e) {
|
||||||
|
if (_this.draggingOverview) {
|
||||||
|
_this.draggingOverview = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var prevWidth = 0;
|
||||||
|
this._onResize = ws.util.debounce(function () {
|
||||||
|
if (prevWidth != _this.drawer.wrapper.clientWidth) {
|
||||||
|
prevWidth = _this.drawer.wrapper.clientWidth;
|
||||||
|
_this.render();
|
||||||
|
_this.drawer.progress(_this.wavesurfer.backend.getPlayedPercents());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this._onZoom = function (e) {
|
||||||
|
_this.render();
|
||||||
|
};
|
||||||
|
this.wavesurfer.on('zoom', this._onZoom);
|
||||||
|
}
|
||||||
|
_createClass(MinimapPlugin, [{
|
||||||
|
key: "init",
|
||||||
|
value: function init() {
|
||||||
|
if (this.wavesurfer.isReady) {
|
||||||
|
this._onShouldRender();
|
||||||
|
}
|
||||||
|
this.wavesurfer.on(this.renderEvent, this._onShouldRender);
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "destroy",
|
||||||
|
value: function destroy() {
|
||||||
|
window.removeEventListener('resize', this._onResize, true);
|
||||||
|
window.removeEventListener('orientationchange', this._onResize, true);
|
||||||
|
this.wavesurfer.drawer.wrapper.removeEventListener('mouseover', this._onMouseover);
|
||||||
|
this.wavesurfer.un(this.renderEvent, this._onShouldRender);
|
||||||
|
this.wavesurfer.un('seek', this._onSeek);
|
||||||
|
this.wavesurfer.un('scroll', this._onScroll);
|
||||||
|
this.wavesurfer.un('audioprocess', this._onAudioprocess);
|
||||||
|
this.wavesurfer.un('zoom', this._onZoom);
|
||||||
|
this.drawer.destroy();
|
||||||
|
this.overviewRegion = null;
|
||||||
|
this.unAll();
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "regions",
|
||||||
|
value: function regions() {
|
||||||
|
var _this2 = this;
|
||||||
|
this.regions = {};
|
||||||
|
this.wavesurfer.on('region-created', function (region) {
|
||||||
|
_this2.regions[region.id] = region;
|
||||||
|
_this2.drawer.wrapper && _this2.renderRegions();
|
||||||
|
});
|
||||||
|
this.wavesurfer.on('region-updated', function (region) {
|
||||||
|
_this2.regions[region.id] = region;
|
||||||
|
_this2.drawer.wrapper && _this2.renderRegions();
|
||||||
|
});
|
||||||
|
this.wavesurfer.on('region-removed', function (region) {
|
||||||
|
delete _this2.regions[region.id];
|
||||||
|
_this2.drawer.wrapper && _this2.renderRegions();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "renderRegions",
|
||||||
|
value: function renderRegions() {
|
||||||
|
var _this3 = this;
|
||||||
|
var regionElements = this.drawer.wrapper.querySelectorAll('region');
|
||||||
|
var i;
|
||||||
|
for (i = 0; i < regionElements.length; ++i) {
|
||||||
|
this.drawer.wrapper.removeChild(regionElements[i]);
|
||||||
|
}
|
||||||
|
Object.keys(this.regions).forEach(function (id) {
|
||||||
|
var region = _this3.regions[id];
|
||||||
|
var width = _this3.getWidth() * ((region.end - region.start) / _this3.wavesurfer.getDuration());
|
||||||
|
var left = _this3.getWidth() * (region.start / _this3.wavesurfer.getDuration());
|
||||||
|
var regionElement = _this3.util.style(document.createElement('region'), {
|
||||||
|
height: 'inherit',
|
||||||
|
backgroundColor: region.color,
|
||||||
|
width: width + 'px',
|
||||||
|
left: left + 'px',
|
||||||
|
display: 'block',
|
||||||
|
position: 'absolute'
|
||||||
|
});
|
||||||
|
regionElement.classList.add(id);
|
||||||
|
_this3.drawer.wrapper.appendChild(regionElement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "createElements",
|
||||||
|
value: function createElements() {
|
||||||
|
this.drawer.createElements();
|
||||||
|
if (this.params.showOverview) {
|
||||||
|
this.overviewRegion = this.util.style(document.createElement('overview'), {
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
width: '0px',
|
||||||
|
display: 'block',
|
||||||
|
position: 'absolute',
|
||||||
|
cursor: 'move',
|
||||||
|
border: this.params.overviewBorderSize + 'px solid ' + this.params.overviewBorderColor,
|
||||||
|
zIndex: 2,
|
||||||
|
opacity: this.params.overviewOpacity
|
||||||
|
});
|
||||||
|
this.drawer.wrapper.appendChild(this.overviewRegion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "bindWavesurferEvents",
|
||||||
|
value: function bindWavesurferEvents() {
|
||||||
|
window.addEventListener('resize', this._onResize, true);
|
||||||
|
window.addEventListener('orientationchange', this._onResize, true);
|
||||||
|
this.wavesurfer.on('audioprocess', this._onAudioprocess);
|
||||||
|
this.wavesurfer.on('seek', this._onSeek);
|
||||||
|
if (this.params.showOverview) {
|
||||||
|
this.wavesurfer.on('scroll', this._onScroll);
|
||||||
|
this.wavesurfer.drawer.wrapper.addEventListener('mouseover', this._onMouseover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "bindMinimapEvents",
|
||||||
|
value: function bindMinimapEvents() {
|
||||||
|
var _this4 = this;
|
||||||
|
var positionMouseDown = {
|
||||||
|
clientX: 0,
|
||||||
|
clientY: 0
|
||||||
|
};
|
||||||
|
var relativePositionX = 0;
|
||||||
|
var seek = true;
|
||||||
|
|
||||||
|
// the following event listeners will be destroyed by using
|
||||||
|
// this.unAll() and nullifying the DOM node references after
|
||||||
|
// removing them
|
||||||
|
if (this.params.interact) {
|
||||||
|
this.drawer.wrapper.addEventListener('click', function (event) {
|
||||||
|
_this4.fireEvent('click', event, _this4.drawer.handleEvent(event));
|
||||||
|
});
|
||||||
|
this.on('click', function (event, position) {
|
||||||
|
if (seek) {
|
||||||
|
_this4.drawer.progress(position);
|
||||||
|
_this4.wavesurfer.seekAndCenter(position);
|
||||||
|
} else {
|
||||||
|
seek = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.params.showOverview) {
|
||||||
|
this.overviewRegion.addEventListener('mousedown', function (event) {
|
||||||
|
_this4.draggingOverview = true;
|
||||||
|
relativePositionX = event.layerX;
|
||||||
|
positionMouseDown.clientX = event.clientX;
|
||||||
|
positionMouseDown.clientY = event.clientY;
|
||||||
|
});
|
||||||
|
this.drawer.wrapper.addEventListener('mousemove', function (event) {
|
||||||
|
if (_this4.draggingOverview) {
|
||||||
|
_this4.moveOverviewRegion(event.clientX - _this4.drawer.container.getBoundingClientRect().left - relativePositionX);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.drawer.wrapper.addEventListener('mouseup', function (event) {
|
||||||
|
if (positionMouseDown.clientX - event.clientX === 0 && positionMouseDown.clientX - event.clientX === 0) {
|
||||||
|
seek = true;
|
||||||
|
_this4.draggingOverview = false;
|
||||||
|
} else if (_this4.draggingOverview) {
|
||||||
|
seek = false;
|
||||||
|
_this4.draggingOverview = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "render",
|
||||||
|
value: function render() {
|
||||||
|
var len = this.drawer.getWidth();
|
||||||
|
var peaks = this.wavesurfer.backend.getPeaks(len, 0, len);
|
||||||
|
this.drawer.drawPeaks(peaks, len, 0, len);
|
||||||
|
this.drawer.progress(this.wavesurfer.backend.getPlayedPercents());
|
||||||
|
if (this.params.showOverview) {
|
||||||
|
//get proportional width of overview region considering the respective
|
||||||
|
//width of the drawers
|
||||||
|
this.ratio = this.wavesurfer.drawer.width / this.drawer.width;
|
||||||
|
this.waveShowedWidth = this.wavesurfer.drawer.width / this.ratio;
|
||||||
|
this.waveWidth = this.wavesurfer.drawer.width;
|
||||||
|
this.overviewWidth = this.drawer.container.offsetWidth / this.ratio;
|
||||||
|
this.overviewPosition = 0;
|
||||||
|
this.moveOverviewRegion(this.wavesurfer.drawer.wrapper.scrollLeft / this.ratio);
|
||||||
|
this.overviewRegion.style.width = this.overviewWidth + 'px';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "moveOverviewRegion",
|
||||||
|
value: function moveOverviewRegion(pixels) {
|
||||||
|
if (pixels < 0) {
|
||||||
|
this.overviewPosition = 0;
|
||||||
|
} else if (pixels + this.overviewWidth < this.drawer.container.offsetWidth) {
|
||||||
|
this.overviewPosition = pixels;
|
||||||
|
} else {
|
||||||
|
this.overviewPosition = this.drawer.container.offsetWidth - this.overviewWidth;
|
||||||
|
}
|
||||||
|
this.overviewRegion.style.left = this.overviewPosition + 'px';
|
||||||
|
if (this.draggingOverview) {
|
||||||
|
this.wavesurfer.drawer.wrapper.scrollLeft = this.overviewPosition * this.ratio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "getWidth",
|
||||||
|
value: function getWidth() {
|
||||||
|
return this.drawer.width / this.params.pixelRatio;
|
||||||
|
}
|
||||||
|
}], [{
|
||||||
|
key: "create",
|
||||||
|
value:
|
||||||
|
/**
|
||||||
|
* Minimap plugin definition factory
|
||||||
|
*
|
||||||
|
* This function must be used to create a plugin definition which can be
|
||||||
|
* used by wavesurfer to correctly instantiate the plugin.
|
||||||
|
*
|
||||||
|
* @param {MinimapPluginParams} params parameters use to initialise the plugin
|
||||||
|
* @return {PluginDefinition} an object representing the plugin
|
||||||
|
*/
|
||||||
|
function create(params) {
|
||||||
|
return {
|
||||||
|
name: 'minimap',
|
||||||
|
deferInit: params && params.deferInit ? params.deferInit : false,
|
||||||
|
params: params,
|
||||||
|
staticProps: {},
|
||||||
|
instance: MinimapPlugin
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}]);
|
||||||
|
return MinimapPlugin;
|
||||||
|
}();
|
||||||
|
module.exports = exports.default;
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
|
||||||
|
/******/ });
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ // The module cache
|
||||||
|
/******/ var __webpack_module_cache__ = {};
|
||||||
|
/******/
|
||||||
|
/******/ // The require function
|
||||||
|
/******/ function __webpack_require__(moduleId) {
|
||||||
|
/******/ // Check if module is in cache
|
||||||
|
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||||
|
/******/ if (cachedModule !== undefined) {
|
||||||
|
/******/ return cachedModule.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/ // Create a new module (and put it into the cache)
|
||||||
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||||
|
/******/ // no module.id needed
|
||||||
|
/******/ // no module.loaded needed
|
||||||
|
/******/ exports: {}
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // Execute the module function
|
||||||
|
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||||
|
/******/
|
||||||
|
/******/ // Return the exports of the module
|
||||||
|
/******/ return module.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/************************************************************************/
|
||||||
|
/******/
|
||||||
|
/******/ // startup
|
||||||
|
/******/ // Load entry module and return exports
|
||||||
|
/******/ // This entry module is referenced by other modules so it can't be inlined
|
||||||
|
/******/ var __webpack_exports__ = __webpack_require__("./src/plugin/minimap/index.js");
|
||||||
|
/******/
|
||||||
|
/******/ return __webpack_exports__;
|
||||||
|
/******/ })()
|
||||||
|
;
|
||||||
|
});
|
||||||
|
//# sourceMappingURL=wavesurfer.minimap.js.map
|
7
legacy/public/js/wavesurfer/minimap.min.js
vendored
Normal file
7
legacy/public/js/wavesurfer/minimap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1200
legacy/public/js/wavesurfer/regions.js
Normal file
1200
legacy/public/js/wavesurfer/regions.js
Normal file
File diff suppressed because it is too large
Load diff
7
legacy/public/js/wavesurfer/regions.min.js
vendored
Normal file
7
legacy/public/js/wavesurfer/regions.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
640
legacy/public/js/wavesurfer/timeline.js
Normal file
640
legacy/public/js/wavesurfer/timeline.js
Normal file
|
@ -0,0 +1,640 @@
|
||||||
|
/*!
|
||||||
|
* wavesurfer.js timeline plugin 4.6.0 (2024-02-05)
|
||||||
|
* https://wavesurfer-js.org
|
||||||
|
* @license BSD-3-Clause
|
||||||
|
*/
|
||||||
|
(function webpackUniversalModuleDefinition(root, factory) {
|
||||||
|
if(typeof exports === 'object' && typeof module === 'object')
|
||||||
|
module.exports = factory();
|
||||||
|
else if(typeof define === 'function' && define.amd)
|
||||||
|
define("WaveSurfer", [], factory);
|
||||||
|
else if(typeof exports === 'object')
|
||||||
|
exports["WaveSurfer"] = factory();
|
||||||
|
else
|
||||||
|
root["WaveSurfer"] = root["WaveSurfer"] || {}, root["WaveSurfer"]["timeline"] = factory();
|
||||||
|
})(this, () => {
|
||||||
|
return /******/ (() => { // webpackBootstrap
|
||||||
|
/******/ "use strict";
|
||||||
|
/******/ var __webpack_modules__ = ({
|
||||||
|
|
||||||
|
/***/ "./src/plugin/timeline/index.js":
|
||||||
|
/*!**************************************!*\
|
||||||
|
!*** ./src/plugin/timeline/index.js ***!
|
||||||
|
\**************************************/
|
||||||
|
/***/ ((module, exports) => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", ({
|
||||||
|
value: true
|
||||||
|
}));
|
||||||
|
exports["default"] = void 0;
|
||||||
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
||||||
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
||||||
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
||||||
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
||||||
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
||||||
|
/**
|
||||||
|
* @typedef {Object} TimelinePluginParams
|
||||||
|
* @desc Extends the `WavesurferParams` wavesurfer was initialised with
|
||||||
|
* @property {!string|HTMLElement} container CSS selector or HTML element where
|
||||||
|
* the timeline should be drawn. This is the only required parameter.
|
||||||
|
* @property {number} notchPercentHeight=90 Height of notches in percent
|
||||||
|
* @property {string} unlabeledNotchColor='#c0c0c0' The colour of the notches
|
||||||
|
* that do not have labels
|
||||||
|
* @property {string} primaryColor='#000' The colour of the main notches
|
||||||
|
* @property {string} secondaryColor='#c0c0c0' The colour of the secondary
|
||||||
|
* notches
|
||||||
|
* @property {string} primaryFontColor='#000' The colour of the labels next to
|
||||||
|
* the main notches
|
||||||
|
* @property {string} secondaryFontColor='#000' The colour of the labels next to
|
||||||
|
* the secondary notches
|
||||||
|
* @property {number} labelPadding=5 The padding between the label and the notch
|
||||||
|
* @property {?number} zoomDebounce A debounce timeout to increase rendering
|
||||||
|
* performance for large files
|
||||||
|
* @property {string} fontFamily='Arial'
|
||||||
|
* @property {number} fontSize=10 Font size of labels in pixels
|
||||||
|
* @property {?number} duration Length of the track in seconds. Overrides
|
||||||
|
* getDuration() for setting length of timeline
|
||||||
|
* @property {function} formatTimeCallback (sec, pxPerSec) -> label
|
||||||
|
* @property {function} timeInterval (pxPerSec) -> seconds between notches
|
||||||
|
* @property {function} primaryLabelInterval (pxPerSec) -> cadence between
|
||||||
|
* labels in primary color
|
||||||
|
* @property {function} secondaryLabelInterval (pxPerSec) -> cadence between
|
||||||
|
* labels in secondary color
|
||||||
|
* @property {?number} offset Offset for the timeline start in seconds. May also be
|
||||||
|
* negative.
|
||||||
|
* @property {?boolean} deferInit Set to true to manually call
|
||||||
|
* `initPlugin('timeline')`
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Adds a timeline to the waveform.
|
||||||
|
*
|
||||||
|
* @implements {PluginClass}
|
||||||
|
* @extends {Observer}
|
||||||
|
* @example
|
||||||
|
* // es6
|
||||||
|
* import TimelinePlugin from 'wavesurfer.timeline.js';
|
||||||
|
*
|
||||||
|
* // commonjs
|
||||||
|
* var TimelinePlugin = require('wavesurfer.timeline.js');
|
||||||
|
*
|
||||||
|
* // if you are using <script> tags
|
||||||
|
* var TimelinePlugin = window.WaveSurfer.timeline;
|
||||||
|
*
|
||||||
|
* // ... initialising wavesurfer with the plugin
|
||||||
|
* var wavesurfer = WaveSurfer.create({
|
||||||
|
* // wavesurfer options ...
|
||||||
|
* plugins: [
|
||||||
|
* TimelinePlugin.create({
|
||||||
|
* // plugin options ...
|
||||||
|
* })
|
||||||
|
* ]
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
var TimelinePlugin = exports["default"] = /*#__PURE__*/function () {
|
||||||
|
/**
|
||||||
|
* Creates an instance of TimelinePlugin.
|
||||||
|
*
|
||||||
|
* You probably want to use TimelinePlugin.create()
|
||||||
|
*
|
||||||
|
* @param {TimelinePluginParams} params Plugin parameters
|
||||||
|
* @param {object} ws Wavesurfer instance
|
||||||
|
*/
|
||||||
|
function TimelinePlugin(params, ws) {
|
||||||
|
var _this = this;
|
||||||
|
_classCallCheck(this, TimelinePlugin);
|
||||||
|
_initialiseProps.call(this);
|
||||||
|
this.container = 'string' == typeof params.container ? document.querySelector(params.container) : params.container;
|
||||||
|
if (!this.container) {
|
||||||
|
throw new Error('No container for wavesurfer timeline');
|
||||||
|
}
|
||||||
|
this.wavesurfer = ws;
|
||||||
|
this.util = ws.util;
|
||||||
|
this.params = Object.assign({}, {
|
||||||
|
height: 20,
|
||||||
|
notchPercentHeight: 90,
|
||||||
|
labelPadding: 5,
|
||||||
|
unlabeledNotchColor: '#c0c0c0',
|
||||||
|
primaryColor: '#000',
|
||||||
|
secondaryColor: '#c0c0c0',
|
||||||
|
primaryFontColor: '#000',
|
||||||
|
secondaryFontColor: '#000',
|
||||||
|
fontFamily: 'Arial',
|
||||||
|
fontSize: 10,
|
||||||
|
duration: null,
|
||||||
|
zoomDebounce: false,
|
||||||
|
formatTimeCallback: this.defaultFormatTimeCallback,
|
||||||
|
timeInterval: this.defaultTimeInterval,
|
||||||
|
primaryLabelInterval: this.defaultPrimaryLabelInterval,
|
||||||
|
secondaryLabelInterval: this.defaultSecondaryLabelInterval,
|
||||||
|
offset: 0
|
||||||
|
}, params);
|
||||||
|
this.canvases = [];
|
||||||
|
this.wrapper = null;
|
||||||
|
this.drawer = null;
|
||||||
|
this.pixelRatio = null;
|
||||||
|
this.maxCanvasWidth = null;
|
||||||
|
this.maxCanvasElementWidth = null;
|
||||||
|
/**
|
||||||
|
* This event handler has to be in the constructor function because it
|
||||||
|
* relies on the debounce function which is only available after
|
||||||
|
* instantiation
|
||||||
|
*
|
||||||
|
* Use a debounced function if `params.zoomDebounce` is defined
|
||||||
|
*
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
this._onZoom = this.params.zoomDebounce ? this.wavesurfer.util.debounce(function () {
|
||||||
|
return _this.render();
|
||||||
|
}, this.params.zoomDebounce) : function () {
|
||||||
|
return _this.render();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialisation function used by the plugin API
|
||||||
|
*/
|
||||||
|
_createClass(TimelinePlugin, [{
|
||||||
|
key: "init",
|
||||||
|
value: function init() {
|
||||||
|
// Check if ws is ready
|
||||||
|
if (this.wavesurfer.isReady) {
|
||||||
|
this._onReady();
|
||||||
|
} else {
|
||||||
|
this.wavesurfer.once('ready', this._onReady);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy function used by the plugin API
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "destroy",
|
||||||
|
value: function destroy() {
|
||||||
|
this.unAll();
|
||||||
|
this.wavesurfer.un('redraw', this._onRedraw);
|
||||||
|
this.wavesurfer.un('zoom', this._onZoom);
|
||||||
|
this.wavesurfer.un('ready', this._onReady);
|
||||||
|
this.wavesurfer.drawer.wrapper.removeEventListener('scroll', this._onScroll);
|
||||||
|
if (this.wrapper && this.wrapper.parentNode) {
|
||||||
|
this.wrapper.removeEventListener('click', this._onWrapperClick);
|
||||||
|
this.wrapper.parentNode.removeChild(this.wrapper);
|
||||||
|
this.wrapper = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a timeline element to wrap the canvases drawn by this plugin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "createWrapper",
|
||||||
|
value: function createWrapper() {
|
||||||
|
var wsParams = this.wavesurfer.params;
|
||||||
|
this.container.innerHTML = '';
|
||||||
|
this.wrapper = this.container.appendChild(document.createElement('timeline'));
|
||||||
|
this.util.style(this.wrapper, {
|
||||||
|
display: 'block',
|
||||||
|
position: 'relative',
|
||||||
|
userSelect: 'none',
|
||||||
|
webkitUserSelect: 'none',
|
||||||
|
height: "".concat(this.params.height, "px")
|
||||||
|
});
|
||||||
|
if (wsParams.fillParent || wsParams.scrollParent) {
|
||||||
|
this.util.style(this.wrapper, {
|
||||||
|
width: '100%',
|
||||||
|
overflowX: 'hidden',
|
||||||
|
overflowY: 'hidden'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.wrapper.addEventListener('click', this._onWrapperClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the timeline (also updates the already rendered timeline)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "render",
|
||||||
|
value: function render() {
|
||||||
|
if (!this.wrapper) {
|
||||||
|
this.createWrapper();
|
||||||
|
}
|
||||||
|
this.updateCanvases();
|
||||||
|
this.updateCanvasesPositioning();
|
||||||
|
this.renderCanvases();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new timeline canvas
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "addCanvas",
|
||||||
|
value: function addCanvas() {
|
||||||
|
var canvas = this.wrapper.appendChild(document.createElement('canvas'));
|
||||||
|
this.canvases.push(canvas);
|
||||||
|
this.util.style(canvas, {
|
||||||
|
position: 'absolute',
|
||||||
|
zIndex: 4
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove timeline canvas
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "removeCanvas",
|
||||||
|
value: function removeCanvas() {
|
||||||
|
var canvas = this.canvases.pop();
|
||||||
|
canvas.parentElement.removeChild(canvas);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure the correct of timeline canvas elements exist and are cached in
|
||||||
|
* this.canvases
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "updateCanvases",
|
||||||
|
value: function updateCanvases() {
|
||||||
|
var totalWidth = Math.round(this.drawer.wrapper.scrollWidth);
|
||||||
|
var requiredCanvases = Math.ceil(totalWidth / this.maxCanvasElementWidth);
|
||||||
|
while (this.canvases.length < requiredCanvases) {
|
||||||
|
this.addCanvas();
|
||||||
|
}
|
||||||
|
while (this.canvases.length > requiredCanvases) {
|
||||||
|
this.removeCanvas();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the dimensions and positioning style for all the timeline canvases
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "updateCanvasesPositioning",
|
||||||
|
value: function updateCanvasesPositioning() {
|
||||||
|
var _this2 = this;
|
||||||
|
// cache length for performance
|
||||||
|
var canvasesLength = this.canvases.length;
|
||||||
|
this.canvases.forEach(function (canvas, i) {
|
||||||
|
// canvas width is the max element width, or if it is the last the
|
||||||
|
// required width
|
||||||
|
var canvasWidth = i === canvasesLength - 1 ? _this2.drawer.wrapper.scrollWidth - _this2.maxCanvasElementWidth * (canvasesLength - 1) : _this2.maxCanvasElementWidth;
|
||||||
|
// set dimensions and style
|
||||||
|
canvas.width = canvasWidth * _this2.pixelRatio;
|
||||||
|
// on certain pixel ratios the canvas appears cut off at the bottom,
|
||||||
|
// therefore leave 1px extra
|
||||||
|
canvas.height = (_this2.params.height + 1) * _this2.pixelRatio;
|
||||||
|
_this2.util.style(canvas, {
|
||||||
|
width: "".concat(canvasWidth, "px"),
|
||||||
|
height: "".concat(_this2.params.height, "px"),
|
||||||
|
left: "".concat(i * _this2.maxCanvasElementWidth, "px")
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the timeline labels and notches
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "renderCanvases",
|
||||||
|
value: function renderCanvases() {
|
||||||
|
var _this3 = this;
|
||||||
|
var duration = this.params.duration || this.wavesurfer.backend.getDuration();
|
||||||
|
if (duration <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var wsParams = this.wavesurfer.params;
|
||||||
|
var fontSize = this.params.fontSize * wsParams.pixelRatio;
|
||||||
|
var totalSeconds = parseInt(duration, 10) + 1;
|
||||||
|
var width = wsParams.fillParent && !wsParams.scrollParent ? this.drawer.getWidth() : this.drawer.wrapper.scrollWidth * wsParams.pixelRatio;
|
||||||
|
var height1 = this.params.height * this.pixelRatio;
|
||||||
|
var height2 = this.params.height * (this.params.notchPercentHeight / 100) * this.pixelRatio;
|
||||||
|
var pixelsPerSecond = width / duration;
|
||||||
|
var formatTime = this.params.formatTimeCallback;
|
||||||
|
// if parameter is function, call the function with
|
||||||
|
// pixelsPerSecond, otherwise simply take the value as-is
|
||||||
|
var intervalFnOrVal = function intervalFnOrVal(option) {
|
||||||
|
return typeof option === 'function' ? option(pixelsPerSecond) : option;
|
||||||
|
};
|
||||||
|
var timeInterval = intervalFnOrVal(this.params.timeInterval);
|
||||||
|
var primaryLabelInterval = intervalFnOrVal(this.params.primaryLabelInterval);
|
||||||
|
var secondaryLabelInterval = intervalFnOrVal(this.params.secondaryLabelInterval);
|
||||||
|
var curPixel = pixelsPerSecond * this.params.offset;
|
||||||
|
var curSeconds = 0;
|
||||||
|
var i;
|
||||||
|
// build an array of position data with index, second and pixel data,
|
||||||
|
// this is then used multiple times below
|
||||||
|
var positioning = [];
|
||||||
|
for (i = 0; i < totalSeconds / timeInterval; i++) {
|
||||||
|
positioning.push([i, curSeconds, curPixel]);
|
||||||
|
curSeconds += timeInterval;
|
||||||
|
curPixel += pixelsPerSecond * timeInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterate over each position
|
||||||
|
var renderPositions = function renderPositions(cb) {
|
||||||
|
positioning.forEach(function (pos) {
|
||||||
|
cb(pos[0], pos[1], pos[2]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// render primary labels
|
||||||
|
this.setFillStyles(this.params.primaryColor);
|
||||||
|
this.setFonts("".concat(fontSize, "px ").concat(this.params.fontFamily));
|
||||||
|
this.setFillStyles(this.params.primaryFontColor);
|
||||||
|
renderPositions(function (i, curSeconds, curPixel) {
|
||||||
|
if (i % primaryLabelInterval === 0) {
|
||||||
|
_this3.fillRect(curPixel, 0, 1, height1);
|
||||||
|
_this3.fillText(formatTime(curSeconds, pixelsPerSecond), curPixel + _this3.params.labelPadding * _this3.pixelRatio, height1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// render secondary labels
|
||||||
|
this.setFillStyles(this.params.secondaryColor);
|
||||||
|
this.setFonts("".concat(fontSize, "px ").concat(this.params.fontFamily));
|
||||||
|
this.setFillStyles(this.params.secondaryFontColor);
|
||||||
|
renderPositions(function (i, curSeconds, curPixel) {
|
||||||
|
if (i % secondaryLabelInterval === 0) {
|
||||||
|
_this3.fillRect(curPixel, 0, 1, height1);
|
||||||
|
_this3.fillText(formatTime(curSeconds, pixelsPerSecond), curPixel + _this3.params.labelPadding * _this3.pixelRatio, height1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// render the actual notches (when no labels are used)
|
||||||
|
this.setFillStyles(this.params.unlabeledNotchColor);
|
||||||
|
renderPositions(function (i, curSeconds, curPixel) {
|
||||||
|
if (i % secondaryLabelInterval !== 0 && i % primaryLabelInterval !== 0) {
|
||||||
|
_this3.fillRect(curPixel, 0, 1, height2);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the canvas fill style
|
||||||
|
*
|
||||||
|
* @param {DOMString|CanvasGradient|CanvasPattern} fillStyle Fill style to
|
||||||
|
* use
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "setFillStyles",
|
||||||
|
value: function setFillStyles(fillStyle) {
|
||||||
|
this.canvases.forEach(function (canvas) {
|
||||||
|
canvas.getContext('2d').fillStyle = fillStyle;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the canvas font
|
||||||
|
*
|
||||||
|
* @param {DOMString} font Font to use
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "setFonts",
|
||||||
|
value: function setFonts(font) {
|
||||||
|
this.canvases.forEach(function (canvas) {
|
||||||
|
canvas.getContext('2d').font = font;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw a rectangle on the canvases
|
||||||
|
*
|
||||||
|
* (it figures out the offset for each canvas)
|
||||||
|
*
|
||||||
|
* @param {number} x X-position
|
||||||
|
* @param {number} y Y-position
|
||||||
|
* @param {number} width Width
|
||||||
|
* @param {number} height Height
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "fillRect",
|
||||||
|
value: function fillRect(x, y, width, height) {
|
||||||
|
var _this4 = this;
|
||||||
|
this.canvases.forEach(function (canvas, i) {
|
||||||
|
var leftOffset = i * _this4.maxCanvasWidth;
|
||||||
|
var intersection = {
|
||||||
|
x1: Math.max(x, i * _this4.maxCanvasWidth),
|
||||||
|
y1: y,
|
||||||
|
x2: Math.min(x + width, i * _this4.maxCanvasWidth + canvas.width),
|
||||||
|
y2: y + height
|
||||||
|
};
|
||||||
|
if (intersection.x1 < intersection.x2) {
|
||||||
|
canvas.getContext('2d').fillRect(intersection.x1 - leftOffset, intersection.y1, intersection.x2 - intersection.x1, intersection.y2 - intersection.y1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fill a given text on the canvases
|
||||||
|
*
|
||||||
|
* @param {string} text Text to render
|
||||||
|
* @param {number} x X-position
|
||||||
|
* @param {number} y Y-position
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "fillText",
|
||||||
|
value: function fillText(text, x, y) {
|
||||||
|
var textWidth;
|
||||||
|
var xOffset = 0;
|
||||||
|
this.canvases.forEach(function (canvas) {
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
var canvasWidth = context.canvas.width;
|
||||||
|
if (xOffset > x + textWidth) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (xOffset + canvasWidth > x) {
|
||||||
|
textWidth = context.measureText(text).width;
|
||||||
|
context.fillText(text, x - xOffset, y);
|
||||||
|
}
|
||||||
|
xOffset += canvasWidth;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turn the time into a suitable label for the time.
|
||||||
|
*
|
||||||
|
* @param {number} seconds Seconds to format
|
||||||
|
* @param {number} pxPerSec Pixels per second
|
||||||
|
* @returns {number} Time
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "defaultFormatTimeCallback",
|
||||||
|
value: function defaultFormatTimeCallback(seconds, pxPerSec) {
|
||||||
|
if (seconds / 60 > 1) {
|
||||||
|
// calculate minutes and seconds from seconds count
|
||||||
|
var minutes = parseInt(seconds / 60, 10);
|
||||||
|
seconds = parseInt(seconds % 60, 10);
|
||||||
|
// fill up seconds with zeroes
|
||||||
|
seconds = seconds < 10 ? '0' + seconds : seconds;
|
||||||
|
return "".concat(minutes, ":").concat(seconds);
|
||||||
|
}
|
||||||
|
return Math.round(seconds * 1000) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return how many seconds should be between each notch
|
||||||
|
*
|
||||||
|
* @param {number} pxPerSec Pixels per second
|
||||||
|
* @returns {number} Time
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "defaultTimeInterval",
|
||||||
|
value: function defaultTimeInterval(pxPerSec) {
|
||||||
|
if (pxPerSec >= 25) {
|
||||||
|
return 1;
|
||||||
|
} else if (pxPerSec * 5 >= 25) {
|
||||||
|
return 5;
|
||||||
|
} else if (pxPerSec * 15 >= 25) {
|
||||||
|
return 15;
|
||||||
|
}
|
||||||
|
return Math.ceil(0.5 / pxPerSec) * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the cadence of notches that get labels in the primary color.
|
||||||
|
*
|
||||||
|
* @param {number} pxPerSec Pixels per second
|
||||||
|
* @returns {number} Cadence
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "defaultPrimaryLabelInterval",
|
||||||
|
value: function defaultPrimaryLabelInterval(pxPerSec) {
|
||||||
|
if (pxPerSec >= 25) {
|
||||||
|
return 10;
|
||||||
|
} else if (pxPerSec * 5 >= 25) {
|
||||||
|
return 6;
|
||||||
|
} else if (pxPerSec * 15 >= 25) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the cadence of notches that get labels in the secondary color.
|
||||||
|
*
|
||||||
|
* @param {number} pxPerSec Pixels per second
|
||||||
|
* @returns {number} Cadence
|
||||||
|
*/
|
||||||
|
}, {
|
||||||
|
key: "defaultSecondaryLabelInterval",
|
||||||
|
value: function defaultSecondaryLabelInterval(pxPerSec) {
|
||||||
|
if (pxPerSec >= 25) {
|
||||||
|
return 5;
|
||||||
|
} else if (pxPerSec * 5 >= 25) {
|
||||||
|
return 2;
|
||||||
|
} else if (pxPerSec * 15 >= 25) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}], [{
|
||||||
|
key: "create",
|
||||||
|
value:
|
||||||
|
/**
|
||||||
|
* Timeline plugin definition factory
|
||||||
|
*
|
||||||
|
* This function must be used to create a plugin definition which can be
|
||||||
|
* used by wavesurfer to correctly instantiate the plugin.
|
||||||
|
*
|
||||||
|
* @param {TimelinePluginParams} params parameters use to initialise the plugin
|
||||||
|
* @return {PluginDefinition} an object representing the plugin
|
||||||
|
*/
|
||||||
|
function create(params) {
|
||||||
|
return {
|
||||||
|
name: 'timeline',
|
||||||
|
deferInit: params && params.deferInit ? params.deferInit : false,
|
||||||
|
params: params,
|
||||||
|
instance: TimelinePlugin
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// event handlers
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object} e Click event
|
||||||
|
*/
|
||||||
|
}]);
|
||||||
|
return TimelinePlugin;
|
||||||
|
}();
|
||||||
|
var _initialiseProps = function _initialiseProps() {
|
||||||
|
var _this5 = this;
|
||||||
|
this._onScroll = function () {
|
||||||
|
if (_this5.wrapper && _this5.drawer.wrapper) {
|
||||||
|
_this5.wrapper.scrollLeft = _this5.drawer.wrapper.scrollLeft;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this._onRedraw = function () {
|
||||||
|
return _this5.render();
|
||||||
|
};
|
||||||
|
this._onReady = function () {
|
||||||
|
var ws = _this5.wavesurfer;
|
||||||
|
_this5.drawer = ws.drawer;
|
||||||
|
_this5.pixelRatio = ws.drawer.params.pixelRatio;
|
||||||
|
_this5.maxCanvasWidth = ws.drawer.maxCanvasWidth || ws.drawer.width;
|
||||||
|
_this5.maxCanvasElementWidth = ws.drawer.maxCanvasElementWidth || Math.round(_this5.maxCanvasWidth / _this5.pixelRatio);
|
||||||
|
|
||||||
|
// add listeners
|
||||||
|
ws.drawer.wrapper.addEventListener('scroll', _this5._onScroll);
|
||||||
|
ws.on('redraw', _this5._onRedraw);
|
||||||
|
ws.on('zoom', _this5._onZoom);
|
||||||
|
_this5.render();
|
||||||
|
};
|
||||||
|
this._onWrapperClick = function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var relX = 'offsetX' in e ? e.offsetX : e.layerX;
|
||||||
|
_this5.fireEvent('click', relX / _this5.wrapper.scrollWidth || 0);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
module.exports = exports.default;
|
||||||
|
|
||||||
|
/***/ })
|
||||||
|
|
||||||
|
/******/ });
|
||||||
|
/************************************************************************/
|
||||||
|
/******/ // The module cache
|
||||||
|
/******/ var __webpack_module_cache__ = {};
|
||||||
|
/******/
|
||||||
|
/******/ // The require function
|
||||||
|
/******/ function __webpack_require__(moduleId) {
|
||||||
|
/******/ // Check if module is in cache
|
||||||
|
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||||
|
/******/ if (cachedModule !== undefined) {
|
||||||
|
/******/ return cachedModule.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/ // Create a new module (and put it into the cache)
|
||||||
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||||
|
/******/ // no module.id needed
|
||||||
|
/******/ // no module.loaded needed
|
||||||
|
/******/ exports: {}
|
||||||
|
/******/ };
|
||||||
|
/******/
|
||||||
|
/******/ // Execute the module function
|
||||||
|
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||||
|
/******/
|
||||||
|
/******/ // Return the exports of the module
|
||||||
|
/******/ return module.exports;
|
||||||
|
/******/ }
|
||||||
|
/******/
|
||||||
|
/************************************************************************/
|
||||||
|
/******/
|
||||||
|
/******/ // startup
|
||||||
|
/******/ // Load entry module and return exports
|
||||||
|
/******/ // This entry module is referenced by other modules so it can't be inlined
|
||||||
|
/******/ var __webpack_exports__ = __webpack_require__("./src/plugin/timeline/index.js");
|
||||||
|
/******/
|
||||||
|
/******/ return __webpack_exports__;
|
||||||
|
/******/ })()
|
||||||
|
;
|
||||||
|
});
|
||||||
|
//# sourceMappingURL=wavesurfer.timeline.js.map
|
7
legacy/public/js/wavesurfer/timeline.min.js
vendored
Normal file
7
legacy/public/js/wavesurfer/timeline.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5774
legacy/public/js/wavesurfer/wavesurfer.js
Normal file
5774
legacy/public/js/wavesurfer/wavesurfer.js
Normal file
File diff suppressed because it is too large
Load diff
7
legacy/public/js/wavesurfer/wavesurfer.min.js
vendored
Normal file
7
legacy/public/js/wavesurfer/wavesurfer.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue