Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Video trimming UI plugin #1798

Open
wants to merge 24 commits into
base: develop
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ba312b2
Structural code for video trimming UI
Danielh112 Apr 2, 2020
72f1568
Merge remote-tracking branch 'origin/develop' into video-trimming-plugin
Danielh112 Apr 2, 2020
4c75bcc
Trim tool icons added
DanielHuntleySBG Apr 3, 2020
c82fa73
If the user is using the trimming tool, check if the seek position is…
DanielHuntleySBG Apr 3, 2020
f5bc729
Improved styling of Trimming timeline
DanielHuntleySBG Apr 4, 2020
13d15b6
Fix to only update the current time when the user has finished settin…
DanielHuntleySBG Apr 4, 2020
ef5bccf
Trimming tool: Implementation of timestamp above each thumb to displa…
DanielHuntleySBG Apr 5, 2020
d8ae6e2
Improve accessiblity: Inclusion of aria metadata
DanielHuntleySBG Apr 6, 2020
c9f8329
Nit pick fixes for trimming tool PR
DanielHuntleySBG Apr 6, 2020
5780e0d
Remove plyr.svg from pull request
DanielHuntleySBG Apr 6, 2020
e13be14
Trimming: On source change update whether or not to show the trimming…
DanielHuntleySBG Apr 6, 2020
5bb96f3
Merge branch 'video-trimming-plugin' of https://github.com/SBGSports/…
DanielHuntleySBG Apr 6, 2020
2ab8a88
Video trimming bug fix: When switching sources a new trimming object …
DanielHuntleySBG Apr 7, 2020
c0fa6d5
Trimming: Change structure of triggerevent messages so that they are …
DanielHuntleySBG Apr 8, 2020
81d77eb
Remove Timeupdate event listener when changing source as two instance…
DanielHuntleySBG Apr 9, 2020
ee73dc4
Convert the default trim length to percent as for longer videos it wa…
DanielHuntleySBG Apr 9, 2020
5e53137
Addition of a couple additional api endpoints to get and set the star…
DanielHuntleySBG Apr 9, 2020
83ab236
Update to use the existing clamp function | Improve commenting for se…
DanielHuntleySBG Apr 9, 2020
bc2fbc4
Remove getter and setter for trimming from plyr.js as it can be acces…
DanielHuntleySBG Apr 11, 2020
bdf4718
Remove settrimstart and settrimend from plyr.js as they can be set fr…
DanielHuntleySBG Apr 11, 2020
04941a0
Calling trim.enter or trim.exit did not update the video trim control…
DanielHuntleySBG Apr 14, 2020
64dc1fd
Fix to Trimming tool, to prevent the start time being before the end …
DanielHuntleySBG Apr 20, 2020
6f06907
Merge develop branch back into video trimming branch
DanielHuntleySBG Apr 24, 2020
3aed88e
resolve merge conflicts
DanielHuntleySBG Nov 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
If the user is using the trimming tool, check if the seek position is…
… outside of the trimming region and set to the start of the trimming region
DanielHuntleySBG committed Apr 3, 2020
commit c82fa7352cab6276d170d2437bb63d61113a59a2
86 changes: 58 additions & 28 deletions src/js/plugins/trim.js
Original file line number Diff line number Diff line change
@@ -13,7 +13,9 @@ class Trim {
this.config = player.config.trim;
this.loaded = false;
this.trimming = false;
this.trimLength = 30;
this.defaultTrimLength = 30;
this.startTime = 0;
this.endTime = 0;
this.tool = {
bar: null,
leftThumb: null,
@@ -29,14 +31,7 @@ class Trim {
// Update the UI
this.update();

// Prevent the trim tool from being added until the player is in a playable state
// If the user has pressed the trim tool before this event has fired, show the tool
this.player.once('canplay', () => {
this.loaded = true;
if (this.trimming) {
this.createTrimTool();
}
});
this.listeners();
}

// Determine if trim is enabled
@@ -54,14 +49,18 @@ class Trim {
return this.trimming;
}

// Get trim range in seconds
getTrimRange() {
const { left, width } = this.tool.bar.style;
const start = this.player.media.duration * (parseFloat(left) / 100);
const end = this.player.media.duration * ((parseFloat(left) + parseFloat(width)) / 100);
get trimTime() {
return { startTime: this.startTime, endTime: this.endTime };
}

this.player.debug.log(`Set trimming range from ${start}seconds to ${end}seconds`);
return { start, end };
// Store the trim start time in seconds
setStartTime(percentage) {
this.startTime = this.player.media.duration * (parseFloat(percentage) / 100);
}

// Store the trim end time in seconds
setEndTime(percentage) {
this.endTime = this.startTime + this.player.media.duration * (parseFloat(percentage) / 100);
}

// Show the trim toolbar from the timeline
@@ -88,13 +87,14 @@ class Trim {

// Add trim bar to the timeline
createTrimBar(seekElement) {
// Set the trim bar from the current seek time to the trimlength
// Set the trim bar from the current seek time percentage to x number of seconds after and limit the end percentage to 100%
const start = this.player.elements.inputs.seek.value;
// Set the trim bar to be x number of seconds after start and prevent from overflowing
const end = Math.min(
parseFloat(start) + (100 / this.player.duration) * this.trimLength,
100 - parseFloat(start),
);
const end = Math.min(parseFloat(start) + (100 / this.player.duration) * this.defaultTrimLength, 100 - start);

// Store the start and end video percentages in seconds
this.setStartTime(start);
this.setEndTime(end);

this.tool.bar = createElement('span', {
class: this.player.config.classNames.trim.trimTool,
});
@@ -103,7 +103,7 @@ class Trim {
this.tool.bar.style.width = `${end.toString()}%`;
seekElement.appendChild(this.tool.bar);

triggerEvent.call(this.player, this.getTrimRange(), 'trimchange');
triggerEvent.call(this.player, this.trimTime, 'trimchange');
}

// Add trim length thumbs to the timeline
@@ -139,7 +139,7 @@ class Trim {

if (type === 'mouseup' || type === 'touchend') {
this.tool.editing = null;
triggerEvent.call(this.player, this.getTrimRange(), 'trimchange');
triggerEvent.call(this.player, this.trimTime, 'trimchange');
} else if ((type === 'mousedown' || type === 'touchstart') && target.classList.contains(leftThumb)) {
this.tool.editing = leftThumb;
} else if ((type === 'mousedown' || type === 'touchstart') && target.classList.contains(rightThumb)) {
@@ -150,25 +150,55 @@ class Trim {
setTrimLength(event) {
if (!this.tool.editing) return;

const { leftThumb, rightThumb } = this.player.config.classNames.trim;
const { bar, editing } = this.tool;
const clientRect = this.player.elements.progress.getBoundingClientRect();
// Mouse Position
const xPos = event.type === 'touchmove' ? event.touches[0].pageX : event.pageX;
// Percentage must be between 0 and 100
const percentage = Math.max(Math.min((100 / clientRect.width) * (xPos - clientRect.left), 100), 0);

/* Alter width of the trim region
- If left thumb selected increase width and keep right hand side in same position
- If right thumb selected just decrease the width */
const { leftThumb, rightThumb } = this.player.config.classNames.trim;
const { bar, editing } = this.tool;
if (editing === leftThumb) {
bar.style.width = `${parseFloat(bar.style.width) - (percentage - parseFloat(bar.style.left))}%`;
bar.style.left = `${percentage}%`;
this.setStartTime(percentage);
// Update seek position to match the left thumbs position if less than the current left thumb position
} else if (editing === rightThumb) {
bar.style.width = `${percentage - parseFloat(bar.style.left)}%`;
const end = percentage - parseFloat(bar.style.left);
bar.style.width = `${end}%`;
this.setEndTime(end);
}
}

listeners() {
/* Prevent the trim tool from being added until the player is in a playable state
If the user has pressed the trim tool before this event has fired, show the tool */
this.player.once('canplay', () => {
this.loaded = true;
if (this.trimming) {
this.createTrimTool();
}
});

// Set the seektime to the start of the trim timeline, if the seektime is outside of the region.
this.player.on('timeupdate', () => {
if (!(this.active && this.trimming && this.player.playing)) {
return;
}

const { currentTime } = this.player;
if (currentTime < this.startTime || currentTime >= this.endTime) {
this.player.currentTime = this.startTime;

if (currentTime >= this.endTime) {
this.player.pause();
}
}
});
}

// On toggle of trim control, trigger event
onChange() {
if (!this.enabled) {
9 changes: 7 additions & 2 deletions src/js/plyr.d.ts
Original file line number Diff line number Diff line change
@@ -453,8 +453,7 @@ declare namespace Plyr {
captions?: CaptionOptions;

/**
* enabled: Toggles whether fullscreen should be enabled. fallback: Allow fallback to a full-window solution.
* iosNative: whether to use native iOS fullscreen when entering fullscreen (no custom controls)
* enabled: Toggles whether trimming should be enabled.
*/
trim?: TrimOptions;

@@ -538,6 +537,12 @@ declare namespace Plyr {
interface TrimOptions {
enabled?: boolean;
active?: boolean;
trimTime?: TrimTime;
}

interface TrimTime {
startTime: number;
endTime: number;
}

interface FullScreenOptions {