Quick Sign In:  

Forum: VirtualDJ Plugins

Topic: Where is the "Master panel in the Master Effect drop-down under the Auto-Start category"?
I am trying to configure the Network Control plugin. The instructions say I need to set the port in the settings in the "Master panel in the Master Effect drop-down under the Auto-Start category".

Where is this? I can't find it. Have tried all the effects drop downs I can think of.

Huge thanks
 

Posted Sun 16 Apr 23 @ 9:17 am
 

Posted Sun 16 Apr 23 @ 9:21 am
Gosh I did Google around, honest! Huge thanks!
 

Posted Sun 16 Apr 23 @ 9:26 am
locoDogPRO InfinityModeratorMember since 2013
 

Posted Sun 16 Apr 23 @ 10:53 am
Huge thanks and apologies - rtfm! Could a link be added to the plugin page?

Anyway, posting back to maybe contribute something related back. A major struggle for me is keeping up with my tunes. I am always buying new bits, but getting it my tagging is always a few hundred tunes behind my shopping, especially since having a baby in the house..!

I figured if I make something that works in a web page I can make things much more seamless. It is hacky, but works a treat and has sped up my tagging by orders of magnitude. I have a web page open that automatically goes through the playlist in VDJ, requesting the genre and comments tag.


First you need to install a Firefox plugin called CORS Everywhere (author spenibus.net). Then you need to install NetworkControl and configure the port. Copy the IP address and port into the below, save the below as an HTML page, open it, and turn CORS Everywhere on.

The result is a row of buttons, an autocomplete genre text and a free text comments field.

It then logs filepath, genre and comment so I can update myself in bulk with a CLI (am I right thinking VDJScript can't set tags?). I've gone from tagging a tune every few minutes to a minute or less per tune, which soon adds up.


<!doctype html>
<html>

<head>
<title>gridder</title>
<style>
html,
body {
height: 99%;
width: 99%;
}

#output {
height: 300px;
width: 99%;
}

#copy {
height: 3px;
width: 4px;
}
</style>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.12.4.js"></script>
<script src="http://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
</head>

<body>
<input type="button" value="play/pause" onclick="execute(cmds.play_pause)" />
<input type="button" value="<<" onclick="execute(cmds.beatjump_back_1)" />
<input type="button" value=">>" onclick="execute(cmds.beatjump_1)" />
<input type="button" value="load" onclick="execute(cmds.browser_enter);moveTrack();" />
<input type="button" value="load next" onclick="execute(cmds.load_next);moveTrack();" />
<input type="button" value="deck toggle" onclick="execute(cmds.deck_select)" />


<br /><br /><br />

<span id="filepath"></span><br />
<span id="artistTitle"></span><br />
<span id="bpm"></span> bpm<br />

<input type="text" id="genre" placeholder="genre" />
<input type="text" id="comment" placeholder="comment" onkeydown="submit(this)" />

<br /><br /><br />

<textarea id="output"></textarea>
<textarea id="copy"></textarea>

<script>
const filepathEl = document.querySelector('#filepath');
const artistTitleEl = document.querySelector('#artistTitle');
const bpmEl = document.querySelector('#bpm');
const genreEl = document.querySelector('#genre');
const commentEl = document.querySelector('#comment');
const outputEl = document.querySelector('#output');
const copyEl = document.querySelector('#copy');
var logs = "";

$("#genre").autocomplete({
source: ["bass", "breaks - dnb", "breaks - jungle", "breaks - footwork", "breaks - drum funk", "broken", "hiphop", "hiphop - too chilled", "hiphop - soul rnb", "hiphop - beatz", "house", "other", "techno - atmospheric", "techno - deep diving", "techno - vocals", "other - reggae", "other - electronica", "other - dub", "other - soul funk", "other - world", "other - latin jazz afo beat", "DELETE"]
});
// was first on prep list: Guru feat Bahamadia - Respect the Architect

const getPlayingDetails = async () => {
await execute(cmds.reanalyze);
await populate(filepathEl, cmds.get_filepath);
await populate(artistTitleEl, cmds.get_artist_title);
await populate(bpmEl, cmds.get_bpm);
genreEl.select();
};
window.addEventListener('load', () => {
getPlayingDetails();
execute(cmds.log_search);
});
window.onbeforeunload = () => {
return 'Did you copy the logs?';
};

const populate = async (el, cmd) => {
el.innerHTML = await query(cmd);
}

// const seek = async el => {
// if (event.keycode === '39') { // right arrow
// await execute(cmds.cue_2);
// await execute(cmds.beatjump_1);
// await execute(cmds.delete_cue_2);
// await execute(cmds.cue_2);
// } else if (event.keycode === '37') { // left arrow
// await execute(cmds.cue_2);
// await execute(cmds.beatjump_back_1);
// await execute(cmds.delete_cue_2);
// await execute(cmds.cue_2);
// } else if (event.keycode === '38') { // up arrow
// await execute(cmds.load_previous);
// await moveTrack();
// } else if (event.keycode === '40') { // down arrow
// await execute(cmds.load_next);
// await moveTrack();
// }
// }

const moveTrack = async () => {
// give VDJ time to load track
await new Promise(resolve => setTimeout(resolve, 200));
// await execute(cmds.goto_first_beat);
// await execute(cmds.cue_1);
// await execute(cmds.beatjump_256);
// await execute(cmds.cue_2); // this will set if not set, o skip to the pos if already set
await execute(cmds.goto_40);
await execute(cmds.play);
await getPlayingDetails();
};

const submit = async el => {
if (event.key === 'Enter') {
const filepath = filepathEl.innerHTML;
const genre = genreEl.value;
const comment = commentEl.value;
const row = `"${filepath}" ${genre} ::: ${comment}`;
log(row);
// await execute(cmds.search + text);
await execute(cmds.load_next);
await moveTrack();
genreEl.select();
};
};

const cue_mapping = 'shift ? delete_cue 1 : hot_cue 1';
const cmds = {
reanalyze: 'reanalyze',
deck_select: 'select',
browser_scroll_top: 'browser_scroll top',
get_bpm: 'get_bpm absolute',
goto_first_beat: 'goto_first_beat',
cue_1: 'hot_cue 1',
delete_cue_1: 'delete_cue 1',
beatjump_256: 'beatjump +256',
beatjump_1: 'beatjump +1',
beatjump_back_1: 'beatjump -1',
cue_2: 'hot_cue 2',
delete_cue_2: 'delete_cue 2',
play_pause: 'play_pause',
pause: 'pause',
play: 'play',
browser_scroll: 'browser_scroll +1',
browser_enter: 'browser_enter',
load_next: 'load_next',
load_previous: 'load_previous',
get_display: 'get_display',
get_filename: 'get_filename',
get_filepath: 'get_filepath',
get_artist_title: 'get_artist_title',
get_browsed_song: "get_browsed_song 'title'",
get_browsed_artist: 'get_browsed_artist',
add_named_playlist: 'virtual folder_add ',
log_search: 'log_search',
search_str: 'search ',
goto_40: 'goto 40%',
};

const query = async vdjs => await send(`/query?script=${encodeURIComponent(vdjs)}`);
const execute = async vdjs => await send(`/execute?script=${encodeURIComponent(vdjs)}`);
const log = text => {
const concatenated = text + "\n";
logs += concatenated;
outputEl.value += concatenated;
copyLogs();
return logs;
}
const copyLogs = () => {
// for some reason using the output textarea blanks the value whenever I run .select() (firefox esr for mac), so we use an additional textarea
copyEl.value = logs;
copyEl.select();
copyEl.setSelectionRange(0, 99999);
document.execCommand('copy');
}

const server = 'http://192.168.1.11:808';
const send = async path => {
const response = await fetch(server + path);
const text = await response.text();
log(`QUERY: ${path} => ${text}`);
return text;
};

</script>

</body>

</html>
 

Posted Tue 18 Apr 23 @ 3:18 pm
locoDogPRO InfinityModeratorMember since 2013
vdj can set tags, when setting setTag auto

then it's just
browsed_song "field" "value"
loaded_song "field" "value"
 

Posted Tue 18 Apr 23 @ 3:25 pm
Thanks very much indeed locodog!
 

Posted Wed 19 Apr 23 @ 7:20 am