Separate Playlist
This commit is contained in:
parent
a9c71ac940
commit
31963968cc
7 changed files with 184 additions and 128 deletions
19
webserver.py
19
webserver.py
|
@ -143,8 +143,23 @@ class AnimationHandler(tornado.web.RequestHandler):
|
|||
self.set_header("Content-Type", "application/json")
|
||||
# filename = self.get_argument("file", None)
|
||||
if filename == '':
|
||||
names = sorted([f"/files/{name[:-16]}" for name in os.listdir(self.config.storage) if name.endswith('json_appendable')])
|
||||
self.write(json.dumps(names))
|
||||
files = []
|
||||
names = [name for name in os.listdir(self.config.storage) if name.endswith('json_appendable')]
|
||||
for name in names:
|
||||
with open(os.path.join(self.config.storage, name), 'r') as fp:
|
||||
first_line = fp.readline().strip()
|
||||
if first_line.endswith(','):
|
||||
first_line = first_line[:-1]
|
||||
print(first_line)
|
||||
metadata = json.loads(first_line)
|
||||
files.append({
|
||||
'name': f"/files/{name[:-16]}",
|
||||
"time": metadata[0],
|
||||
"dimensions": [metadata[1], metadata[2]],
|
||||
})
|
||||
|
||||
files.sort(key=lambda k: k['time'])
|
||||
self.write(json.dumps(files))
|
||||
else:
|
||||
path = os.path.join(self.config.storage,os.path.basename(filename)+".json_appendable")
|
||||
drawing = {
|
||||
|
|
|
@ -71,29 +71,7 @@
|
|||
background: rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.playlist {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
.playlist li {
|
||||
cursor: pointer;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.playlist li:hover {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
|
||||
input[type='range'] {
|
||||
/* position: absolute;
|
||||
|
@ -151,7 +129,8 @@
|
|||
transition: width .3s;
|
||||
pointer-events: none;
|
||||
border: none;
|
||||
direction: rtl; /* hide behind bar, instead into nothing */
|
||||
direction: rtl;
|
||||
/* hide behind bar, instead into nothing */
|
||||
}
|
||||
|
||||
.selected-annotation .tags li.annotation-rm {
|
||||
|
@ -230,6 +209,7 @@
|
|||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="assets/nouislider-15.5.0.css">
|
||||
<link rel="stylesheet" href="core.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -238,12 +218,17 @@
|
|||
<script src="assets/nouislider-15.5.0.js"></script>
|
||||
<script src="assets/wNumb-1.2.0.min.js"></script>
|
||||
<script src="annotate.js"></script>
|
||||
<script src="playlist.js"></script>
|
||||
<script type='text/javascript'>
|
||||
const player = new Annotator(
|
||||
document.getElementById("interface"),
|
||||
["test", "another", "google"]
|
||||
);
|
||||
player.playlist('/files/');
|
||||
if (location.search) {
|
||||
const player = new Annotator(
|
||||
document.getElementById("interface"),
|
||||
["test", "another", "google"],
|
||||
location.search.substring(1)
|
||||
);
|
||||
} else {
|
||||
const playlist = new Playlist(document.getElementById("interface"), '/files/');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -110,7 +110,7 @@ class StrokeSlice {
|
|||
}
|
||||
|
||||
class Annotator {
|
||||
constructor(wrapperEl, tags) {
|
||||
constructor(wrapperEl, tags, fileurl) {
|
||||
this.wrapperEl = wrapperEl;
|
||||
this.svgEl = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
this.wrapperEl.appendChild(this.svgEl);
|
||||
|
@ -184,7 +184,9 @@ class Annotator {
|
|||
this.strokeGroups[group] = new StrokeGroup(groupEl, this);
|
||||
});
|
||||
|
||||
this.annotations = []
|
||||
this.annotations = [];
|
||||
|
||||
this.play(fileurl);
|
||||
}
|
||||
|
||||
updateAnnotations(save) {
|
||||
|
@ -263,41 +265,6 @@ class Annotator {
|
|||
this.updateAnnotations(false); // selects the right tag & highlights the annotation
|
||||
}
|
||||
|
||||
// TODO: to separate class which then instantiates a player for the given file
|
||||
playlist(url) {
|
||||
const request = new Request(url, {
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
|
||||
fetch(request)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
let playlist = this.wrapperEl.querySelector('.playlist');
|
||||
if (!playlist) {
|
||||
playlist = document.createElement('nav');
|
||||
playlist.classList.add('playlist');
|
||||
this.wrapperEl.appendChild(playlist)
|
||||
}
|
||||
else {
|
||||
playlist.innerHTML = "";
|
||||
}
|
||||
|
||||
const listEl = document.createElement("ul");
|
||||
for (let fileUrl of data) {
|
||||
const liEl = document.createElement("li");
|
||||
liEl.innerText = fileUrl
|
||||
liEl.addEventListener('click', (e) => {
|
||||
this.play(fileUrl);
|
||||
playlist.style.display = "none";
|
||||
});
|
||||
listEl.appendChild(liEl);
|
||||
}
|
||||
playlist.appendChild(listEl);
|
||||
// do something with the data sent in the request
|
||||
});
|
||||
}
|
||||
|
||||
play(file) {
|
||||
const request = new Request(file, {
|
||||
method: 'GET',
|
||||
|
@ -491,11 +458,11 @@ class Annotator {
|
|||
this.updateAnnotations(false);
|
||||
|
||||
this.setupAudioConfig();
|
||||
|
||||
|
||||
// this.playStrokePosition(0, 1);
|
||||
}
|
||||
|
||||
setupAudioConfig(){
|
||||
setupAudioConfig() {
|
||||
// audio config
|
||||
let audioConfigEl = document.createElement('div');
|
||||
audioConfigEl.classList.add('audioconfig')
|
||||
|
@ -532,7 +499,7 @@ class Annotator {
|
|||
|
||||
|
||||
this.audioEl = document.createElement('audio');
|
||||
if(this.audioFile) {
|
||||
if (this.audioFile) {
|
||||
this.audioEl.setAttribute('src', this.audioFile);
|
||||
}
|
||||
this.audioEl.addEventListener('canplaythrough', (ev) => {
|
||||
|
|
57
www/core.css
Normal file
57
www/core.css
Normal file
|
@ -0,0 +1,57 @@
|
|||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.playlist {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
/* font-size: 15px; */
|
||||
}
|
||||
|
||||
.playlist::before {
|
||||
content: 'files';
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
font-size: 300%;
|
||||
/* display: list-item?; */
|
||||
}
|
||||
|
||||
.playlist li {
|
||||
/* cursor: pointer; */
|
||||
list-style: none;
|
||||
;
|
||||
line-height: 1.5;
|
||||
/* margin: 20px; */
|
||||
border-bottom: solid darkgray 1px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.playlist li a:hover {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.playlist .links {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.playlist li .name {
|
||||
padding-left: 20px
|
||||
}
|
||||
|
||||
.playlist .links::before {
|
||||
content: '[';
|
||||
}
|
||||
|
||||
.playlist .links::after {
|
||||
content: ']';
|
||||
}
|
||||
|
||||
.playlist .links a {
|
||||
margin: 0 10px;
|
||||
}
|
|
@ -62,37 +62,27 @@
|
|||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.playlist {
|
||||
|
||||
input[type='range'] {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
right: 0;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
.playlist li{
|
||||
cursor: pointer;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.playlist li:hover{
|
||||
color: blue;
|
||||
}
|
||||
|
||||
input[type='range']{
|
||||
.scrubber {
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
bottom: 0;
|
||||
left:0;
|
||||
right: 0;width: 90%;
|
||||
}
|
||||
.scrubber{
|
||||
position: absolute;
|
||||
z-index: 100;
|
||||
bottom: 0;
|
||||
left:0;
|
||||
right: 0;width: 90%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 90%;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="assets/nouislider-15.5.0.css">
|
||||
<link rel="stylesheet" href="core.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -100,9 +90,16 @@
|
|||
</div>
|
||||
<script src="assets/nouislider-15.5.0.js"></script>
|
||||
<script src="play.js"></script>
|
||||
<script src="playlist.js"></script>
|
||||
<script type='text/javascript'>
|
||||
const player = new Player(document.getElementById("interface"));
|
||||
player.playlist('/files/');
|
||||
if (location.search) {
|
||||
const player = new Player(
|
||||
document.getElementById("interface"),
|
||||
location.search.substring(1)
|
||||
);
|
||||
} else {
|
||||
const playlist = new Playlist(document.getElementById("interface"), '/files/');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
36
www/play.js
36
www/play.js
|
@ -1,6 +1,6 @@
|
|||
|
||||
class Player {
|
||||
constructor(wrapperEl) {
|
||||
constructor(wrapperEl, fileurl) {
|
||||
this.wrapperEl = wrapperEl;
|
||||
this.svgEl = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
|
||||
this.wrapperEl.appendChild(this.svgEl);
|
||||
|
@ -23,40 +23,8 @@ class Player {
|
|||
this.outPointPosition = null;
|
||||
this.currentTime = 0;
|
||||
this.isPlaying = false;
|
||||
}
|
||||
|
||||
playlist(url) {
|
||||
const request = new Request(url, {
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
|
||||
fetch(request)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
let playlist = this.wrapperEl.querySelector('.playlist');
|
||||
if (!playlist) {
|
||||
playlist = document.createElement('nav');
|
||||
playlist.classList.add('playlist');
|
||||
this.wrapperEl.appendChild(playlist)
|
||||
}
|
||||
else {
|
||||
playlist.innerHTML = "";
|
||||
}
|
||||
|
||||
const listEl = document.createElement("ul");
|
||||
for (let fileUrl of data) {
|
||||
const liEl = document.createElement("li");
|
||||
liEl.innerText = fileUrl
|
||||
liEl.addEventListener('click', (e) => {
|
||||
this.play(fileUrl);
|
||||
playlist.style.display = "none";
|
||||
});
|
||||
listEl.appendChild(liEl);
|
||||
}
|
||||
playlist.appendChild(listEl);
|
||||
// do something with the data sent in the request
|
||||
});
|
||||
this.play(fileurl);
|
||||
}
|
||||
|
||||
play(file) {
|
||||
|
|
67
www/playlist.js
Normal file
67
www/playlist.js
Normal file
|
@ -0,0 +1,67 @@
|
|||
class Playlist {
|
||||
constructor(wrapperEl, url) {
|
||||
this.wrapperEl = wrapperEl;
|
||||
|
||||
const request = new Request(url, {
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
fetch(request)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
let playlist = this.wrapperEl.querySelector('.playlist');
|
||||
if (!playlist) {
|
||||
playlist = document.createElement('nav');
|
||||
playlist.classList.add('playlist');
|
||||
this.wrapperEl.appendChild(playlist)
|
||||
}
|
||||
else {
|
||||
playlist.innerHTML = "";
|
||||
}
|
||||
|
||||
const listEl = document.createElement("ul");
|
||||
for (let file of data) {
|
||||
const liEl = document.createElement("li");
|
||||
|
||||
const dateEl = document.createElement("span");
|
||||
dateEl.classList.add('date');
|
||||
dateEl.innerText = file.time;
|
||||
liEl.append(dateEl);
|
||||
|
||||
const nameEl = document.createElement("span");
|
||||
nameEl.classList.add('name');
|
||||
nameEl.innerText = file.name;
|
||||
liEl.append(nameEl);
|
||||
|
||||
const linksEl = document.createElement("span");
|
||||
linksEl.classList.add('links');
|
||||
liEl.append(linksEl);
|
||||
|
||||
const playEl = document.createElement("a");
|
||||
playEl.classList.add('play');
|
||||
playEl.innerText = "Play";
|
||||
playEl.href = location;
|
||||
playEl.pathname = "play.html";
|
||||
playEl.search = "?"+file.name;
|
||||
linksEl.append(playEl);
|
||||
|
||||
const annotateEl = document.createElement("a");
|
||||
annotateEl.classList.add('annotate');
|
||||
annotateEl.innerText = "Annotate";
|
||||
annotateEl.href = location;
|
||||
annotateEl.pathname = "annotate.html";
|
||||
annotateEl.search = "?"+file.name;
|
||||
linksEl.append(annotateEl);
|
||||
|
||||
// liEl.addEventListener('click', (e) => {
|
||||
// this.play(fileUrl);
|
||||
// playlist.style.display = "none";
|
||||
// });
|
||||
listEl.appendChild(liEl);
|
||||
}
|
||||
playlist.appendChild(listEl);
|
||||
// do something with the data sent in the request
|
||||
});
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue