mirror of
https://github.com/TeamPiped/Piped.git
synced 2024-12-13 22:00:28 +05:30
Fix seekbar preview aspect ratio and cropping
This PR fixes two issue observed with the seekbar preview: - sometimes images got cropped incorrectly at the end of the video due to image having less frames that server tells us - so calculate it in place; - set canvas width and height based on actual frame data so it follows the video aspect ratio rather than hard-coded value.
This commit is contained in:
parent
2b951bfb5e
commit
25818ae89f
@ -6,7 +6,7 @@
|
|||||||
:class="{ 'player-container': !isEmbed }"
|
:class="{ 'player-container': !isEmbed }"
|
||||||
>
|
>
|
||||||
<video ref="videoEl" class="w-full" data-shaka-player :autoplay="shouldAutoPlay" :loop="selectedAutoLoop" />
|
<video ref="videoEl" class="w-full" data-shaka-player :autoplay="shouldAutoPlay" :loop="selectedAutoLoop" />
|
||||||
<canvas height="130" width="230" id="preview" />
|
<canvas id="preview" />
|
||||||
<button
|
<button
|
||||||
v-if="inSegment"
|
v-if="inSegment"
|
||||||
class="skip-segment-button"
|
class="skip-segment-button"
|
||||||
@ -697,24 +697,37 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
async showSeekbarPreview(position) {
|
async showSeekbarPreview(position) {
|
||||||
let frame = this.getFrame(position);
|
const frame = this.getFrame(position);
|
||||||
let originalImage = await this.loadImage(frame.url);
|
const originalImage = await this.loadImage(frame.url);
|
||||||
if (!this.isHoveringTimebar) return;
|
if (!this.isHoveringTimebar) return;
|
||||||
|
|
||||||
let seekBar = document.querySelector(".shaka-seek-bar");
|
const seekBar = document.querySelector(".shaka-seek-bar");
|
||||||
let canvas = document.querySelector("#preview");
|
const canvas = document.querySelector("#preview");
|
||||||
let ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
|
|
||||||
// get the new sizes for the image to be drawn into the canvas
|
// get the new sizes for the image to be drawn into the canvas
|
||||||
const originalWidth = originalImage.naturalWidth;
|
const originalWidth = originalImage.naturalWidth;
|
||||||
const originalHeight = originalImage.naturalHeight;
|
const originalHeight = originalImage.naturalHeight;
|
||||||
const offsetX = originalWidth * (frame.positionX / frame.framesPerPageX);
|
// image can have less frames than server told us so calculate them ourselves
|
||||||
const offsetY = originalHeight * (frame.positionY / frame.framesPerPageY);
|
const imageFramesPerPageX = originalImage.naturalWidth / frame.frameWidth;
|
||||||
const newWidth = originalWidth / frame.framesPerPageX;
|
const imageFramesPerPageY = originalImage.naturalHeight / frame.frameHeight;
|
||||||
const newHeight = originalHeight / frame.framesPerPageY;
|
const offsetX = originalWidth * (frame.positionX / imageFramesPerPageX);
|
||||||
|
const offsetY = originalHeight * (frame.positionY / imageFramesPerPageY);
|
||||||
|
|
||||||
|
canvas.width = frame.frameWidth > 100 ? frame.frameWidth : frame.frameWidth * 2;
|
||||||
|
canvas.height = frame.frameWidth > 100 ? frame.frameHeight : frame.frameHeight * 2;
|
||||||
// draw the thumbnail preview into the canvas by cropping only the relevant part
|
// draw the thumbnail preview into the canvas by cropping only the relevant part
|
||||||
ctx.drawImage(originalImage, offsetX, offsetY, newWidth, newHeight, 0, 0, canvas.width, canvas.height);
|
ctx.drawImage(
|
||||||
|
originalImage,
|
||||||
|
offsetX,
|
||||||
|
offsetY,
|
||||||
|
frame.frameWidth,
|
||||||
|
frame.frameHeight,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
canvas.width,
|
||||||
|
canvas.height,
|
||||||
|
);
|
||||||
|
|
||||||
// calculate the thumbnail preview offset and display it
|
// calculate the thumbnail preview offset and display it
|
||||||
const seekbarPadding = 2; // percentage of seekbar padding
|
const seekbarPadding = 2; // percentage of seekbar padding
|
||||||
@ -727,7 +740,7 @@ export default {
|
|||||||
// ineffective algorithm to find the thumbnail corresponding to the currently hovered position in the video
|
// ineffective algorithm to find the thumbnail corresponding to the currently hovered position in the video
|
||||||
getFrame(position) {
|
getFrame(position) {
|
||||||
let startPosition = 0;
|
let startPosition = 0;
|
||||||
let framePage = this.video.previewFrames.at(-1);
|
const framePage = this.video.previewFrames.at(-1);
|
||||||
for (let i = 0; i < framePage.urls.length; i++) {
|
for (let i = 0; i < framePage.urls.length; i++) {
|
||||||
for (let positionY = 0; positionY < framePage.framesPerPageY; positionY++) {
|
for (let positionY = 0; positionY < framePage.framesPerPageY; positionY++) {
|
||||||
for (let positionX = 0; positionX < framePage.framesPerPageX; positionX++) {
|
for (let positionX = 0; positionX < framePage.framesPerPageX; positionX++) {
|
||||||
@ -737,8 +750,8 @@ export default {
|
|||||||
url: framePage.urls[i],
|
url: framePage.urls[i],
|
||||||
positionX: positionX,
|
positionX: positionX,
|
||||||
positionY: positionY,
|
positionY: positionY,
|
||||||
framesPerPageX: framePage.framesPerPageX,
|
frameWidth: framePage.frameWidth,
|
||||||
framesPerPageY: framePage.framesPerPageY,
|
frameHeight: framePage.frameHeight,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
startPosition = endPosition;
|
startPosition = endPosition;
|
||||||
@ -750,7 +763,7 @@ export default {
|
|||||||
// creates a new image from an URL
|
// creates a new image from an URL
|
||||||
loadImage(url) {
|
loadImage(url) {
|
||||||
return new Promise(r => {
|
return new Promise(r => {
|
||||||
let i = new Image();
|
const i = new Image();
|
||||||
i.onload = () => r(i);
|
i.onload = () => r(i);
|
||||||
i.src = url;
|
i.src = url;
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user