Mark video chapters on progress bar

This commit is contained in:
Rafostar
2021-01-12 18:26:28 +01:00
parent b71aa0a84a
commit 83bec8e834
3 changed files with 105 additions and 5 deletions

View File

@@ -23,6 +23,7 @@ class ClapperPlayer extends PlayerBase
this.playOnFullscreen = false; this.playOnFullscreen = false;
this.quitOnStop = false; this.quitOnStop = false;
this.needsTocUpdate = true;
this.posX = 0; this.posX = 0;
this.posY = 0; this.posY = 0;
@@ -191,6 +192,10 @@ class ClapperPlayer extends PlayerBase
seek(position) seek(position)
{ {
/* avoid seek emits when position bar is altered */
if(this.needsTocUpdate)
return;
this.seek_done = false; this.seek_done = false;
if(this.state === GstPlayer.PlayerState.STOPPED) if(this.state === GstPlayer.PlayerState.STOPPED)
@@ -417,6 +422,7 @@ class ClapperPlayer extends PlayerBase
_onUriLoaded(player, uri) _onUriLoaded(player, uri)
{ {
debug(`URI loaded: ${uri}`); debug(`URI loaded: ${uri}`);
this.needsTocUpdate = true;
if(!this.doneStartup) { if(!this.doneStartup) {
this.doneStartup = true; this.doneStartup = true;

View File

@@ -205,6 +205,14 @@ class ClapperWidget extends Gtk.Grid
this.isSeekable = mediaInfo.is_seekable(); this.isSeekable = mediaInfo.is_seekable();
this.controls.setLiveMode(isLive, this.isSeekable); this.controls.setLiveMode(isLive, this.isSeekable);
if(this.player.needsTocUpdate) {
/* FIXME: Remove `get_toc` check after required GstPlay(er) ver bump */
if(!isLive && mediaInfo.get_toc)
this.updateChapters(mediaInfo.get_toc());
this.player.needsTocUpdate = false;
}
const streamList = mediaInfo.get_stream_list(); const streamList = mediaInfo.get_stream_list();
const parsedInfo = { const parsedInfo = {
videoTracks: [], videoTracks: [],
@@ -342,6 +350,50 @@ class ClapperWidget extends Gtk.Grid
return nextUpdate; return nextUpdate;
} }
updateChapters(toc)
{
if(!toc) return;
const entries = toc.get_entries();
if(!entries) return;
for(let entry of entries) {
const subentries = entry.get_sub_entries();
if(!subentries) continue;
for(let subentry of subentries)
this._parseTocSubentry(subentry);
}
}
_parseTocSubentry(subentry)
{
const [success, start, stop] = subentry.get_start_stop_times();
if(!success) {
debug('could not obtain toc subentry start/stop times');
return;
}
/* FIXME: Use higher precision for position scale */
const pos = Math.floor(start / 1000000) / 1000;
this.controls.positionScale.add_mark(pos, Gtk.PositionType.TOP, null);
this.controls.positionScale.add_mark(pos, Gtk.PositionType.BOTTOM, null);
const tags = subentry.get_tags();
if(!tags) {
debug('could not obtain toc subentry tags');
return;
}
const [isString, title] = tags.get_string('title');
if(!isString) {
debug('toc subentry tag does not have a title');
return;
}
debug(`chapter at ${pos}: ${title}`);
}
showVisualizationsButton(isShow) showVisualizationsButton(isShow)
{ {
if(isShow && !this.controls.visualizationsButton.isVisList) { if(isShow && !this.controls.visualizationsButton.isVisList) {
@@ -386,6 +438,8 @@ class ClapperWidget extends Gtk.Grid
switch(state) { switch(state) {
case GstPlayer.PlayerState.BUFFERING: case GstPlayer.PlayerState.BUFFERING:
debug('player state changed to: BUFFERING'); debug('player state changed to: BUFFERING');
if(player.needsTocUpdate)
this.controls.positionScale.clear_marks();
if(!player.is_local_file) { if(!player.is_local_file) {
this.needsTracksUpdate = true; this.needsTracksUpdate = true;
} }

View File

@@ -72,6 +72,13 @@ radio {
} }
/* Position Scale */ /* Position Scale */
.positionscale {
margin-top: -2px;
margin-bottom: -2px;
}
.osd .positionscale {
margin-top: -1px;
}
.positionscale trough highlight { .positionscale trough highlight {
min-height: 4px; min-height: 4px;
} }
@@ -81,14 +88,39 @@ radio {
border-color: transparent; border-color: transparent;
box-shadow: none; box-shadow: none;
} }
.osd .positionscale { .positionscale mark indicator {
margin-top: 1px; min-height: 6px;
}
.positionscale.fine-tune mark indicator {
min-height: 6px;
}
.osd .positionscale mark indicator {
min-height: 7px;
min-width: 2px;
}
.osd .positionscale.fine-tune mark indicator {
min-height: 7px;
min-width: 2px;
}
.positionscale marks.top {
margin-top: -6px;
margin-bottom: 4px;
}
.positionscale marks.bottom {
margin-top: 4px;
margin-bottom: -6px;
}
.osd .positionscale marks.top {
margin-bottom: 2px;
}
.osd .positionscale marks.bottom {
margin-top: 2px;
} }
.osd .positionscale trough highlight { .osd .positionscale trough highlight {
border-radius: 3px; border-radius: 3px;
min-height: 20px; min-height: 20px;
} }
.osd .positionscale.dragging trough highlight { .osd .positionscale.fine-tune trough highlight {
border-radius: 3px; border-radius: 3px;
min-height: 20px; min-height: 20px;
} }
@@ -134,16 +166,24 @@ radio {
min-height: 24px; min-height: 24px;
} }
.osd.floatingcontrols .positionscale { .osd.floatingcontrols .positionscale {
margin-top: 0px; margin-top: -2px;
} }
.osd.floatingcontrols .positionscale trough highlight { .osd.floatingcontrols .positionscale trough highlight {
border-radius: 3px; border-radius: 3px;
min-height: 12px; min-height: 12px;
} }
.osd.floatingcontrols .positionscale.dragging trough highlight { .osd.floatingcontrols .positionscale.fine-tune trough highlight {
border-radius: 3px; border-radius: 3px;
min-height: 12px; min-height: 12px;
} }
.osd.floatingcontrols .positionscale mark indicator {
min-height: 5px;
min-width: 1px;
}
.osd.floatingcontrols .positionscale.fine-tune mark indicator {
min-height: 5px;
min-width: 1px;
}
.narrowbutton { .narrowbutton {
min-width: 8px; min-width: 8px;