Skip to content

Commit

Permalink
Add "show previous frame" and "show next frame" buttons in video navi…
Browse files Browse the repository at this point in the history
…gation

Add "show previous frame" and "show next frame" buttons in video navigation

Add "show previous frame" and "show next frame" buttons in video navigation
  • Loading branch information
ToukL committed May 3, 2024
1 parent 833d15d commit 61f9fa9
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 8 deletions.
30 changes: 22 additions & 8 deletions resources/assets/js/videos/components/videoScreen.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,20 @@
:position="mousePosition"
></label-tooltip>
<div class="controls">
<div class="btn-group">
<div class="btn-group"
v-if="showPrevNext">
<control-button
v-if="showPrevNext"
icon="fa-step-backward"
title="Previous video 𝗟𝗲𝗳𝘁 𝗮𝗿𝗿𝗼𝘄"
icon="fa-chevron-left"
title="Previous video"
@click="emitPrevious"
></control-button>
</div>
<div class="btn-group">
<control-button
icon="fa-step-backward"
title="Previous frame 𝗟𝗲𝗳𝘁 𝗮𝗿𝗿𝗼𝘄"
v-on:click="showPreviousFrame"
></control-button>
<control-button
v-if="playing"
icon="fa-pause"
Expand All @@ -33,9 +40,16 @@
@click="play"
></control-button>
<control-button
v-if="showPrevNext"
icon="fa-step-forward"
title="Next video 𝗥𝗶𝗴𝗵𝘁 𝗮𝗿𝗿𝗼𝘄"
title="Next frame Right 𝗮𝗿𝗿𝗼𝘄"
v-on:click="showNextFrame"
></control-button>
</div>
<div class="btn-group"
v-if="showPrevNext">
<control-button
icon="fa-chevron-right"
title="Next video"
@click="emitNext"
></control-button>
</div>
Expand Down Expand Up @@ -550,8 +564,8 @@ export default {
this.map.on('moveend', this.emitMoveend);
Keyboard.on('Escape', this.resetInteractionMode, 0, this.listenerSet);
Keyboard.on('ArrowRight', this.emitNext, 0, this.listenerSet);
Keyboard.on('ArrowLeft', this.emitPrevious, 0, this.listenerSet);
Keyboard.on('ArrowRight', this.showNextFrame, 0, this.listenerSet);
Keyboard.on('ArrowLeft', this.showPreviousFrame, 0, this.listenerSet);
},
mounted() {
this.map.setTarget(this.$el);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,50 @@ export default {
handleSeeked() {
this.renderVideo(true);
},
// 3 next methods are a workaround to get previous and next frames, adapted from here: https://github.com/angrycoding/requestVideoFrameCallback-prev-next/tree/main
frameInfoCallback() {
let promise = new Vue.Promise((resolve, reject) => {
if ("requestVideoFrameCallback" in HTMLVideoElement.prototype) {
this.video.requestVideoFrameCallback((now, metadata) => {
resolve(metadata);
})
}
else {
reject("Your browser does not support requestVideoFrameCallback().");
}
})
return promise;
},
async showPreviousFrame() {
// force rerender
this.video.currentTime += 1;
this.video.currentTime -= 1;
// get current frame time
const firstMetadata = await this.frameInfoCallback();
for (;;) {
// now adjust video's current time until actual frame time changes
this.video.currentTime -= 0.01;
let metadata = await this.frameInfoCallback();
if (metadata.mediaTime !== firstMetadata.mediaTime) break;
}
},
async showNextFrame() {
// force rerender
this.video.currentTime += 1;
this.video.currentTime -= 1;
// get current frame time
const firstMetadata = await this.frameInfoCallback();
for (;;) {
// now adjust video's current time until actual frame time changes
this.video.currentTime += 0.01;
let metadata = await this.frameInfoCallback();
if (metadata.mediaTime !== firstMetadata.mediaTime) break;
}
},
},
watch: {
seeking(seeking) {
Expand Down

0 comments on commit 61f9fa9

Please sign in to comment.