mirror of
https://github.com/ente-io/ente.git
synced 2025-08-06 14:43:20 +00:00
Include playlist info
This commit is contained in:
parent
41a688357c
commit
223043e75c
@ -45,7 +45,6 @@ import {
|
|||||||
ImageEditorOverlay,
|
ImageEditorOverlay,
|
||||||
type ImageEditorOverlayProps,
|
type ImageEditorOverlayProps,
|
||||||
} from "ente-new/photos/components/ImageEditorOverlay";
|
} from "ente-new/photos/components/ImageEditorOverlay";
|
||||||
import { settingsSnapshot } from "ente-new/photos/services/settings";
|
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import React, {
|
import React, {
|
||||||
useCallback,
|
useCallback,
|
||||||
@ -64,6 +63,7 @@ import {
|
|||||||
moreButtonID,
|
moreButtonID,
|
||||||
moreMenuID,
|
moreMenuID,
|
||||||
resetMoreMenuButtonOnMenuClose,
|
resetMoreMenuButtonOnMenuClose,
|
||||||
|
shouldUsePlayerV2,
|
||||||
type FileViewerPhotoSwipeDelegate,
|
type FileViewerPhotoSwipeDelegate,
|
||||||
} from "./photoswipe";
|
} from "./photoswipe";
|
||||||
|
|
||||||
@ -1154,14 +1154,14 @@ const Shortcuts: React.FC<ShortcutsProps> = ({
|
|||||||
action={formattedListJoin([t("previous"), t("next")])}
|
action={formattedListJoin([t("previous"), t("next")])}
|
||||||
shortcut={
|
shortcut={
|
||||||
// TODO(HLS):
|
// TODO(HLS):
|
||||||
settingsSnapshot().isInternalUser
|
shouldUsePlayerV2()
|
||||||
? `${formattedListJoin([ut("←"), ut("→")])} (Option/Alt)`
|
? `${formattedListJoin([ut("←"), ut("→")])} (Option/Alt)`
|
||||||
: formattedListJoin([ut("←"), ut("→")])
|
: formattedListJoin([ut("←"), ut("→")])
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{
|
{
|
||||||
/* TODO(HLS): */
|
/* TODO(HLS): */
|
||||||
settingsSnapshot().isInternalUser && (
|
shouldUsePlayerV2() && (
|
||||||
<Shortcut
|
<Shortcut
|
||||||
action={pt("Video seek")}
|
action={pt("Video seek")}
|
||||||
shortcut={formattedListJoin([ut("←"), ut("→")])}
|
shortcut={formattedListJoin([ut("←"), ut("→")])}
|
||||||
@ -1186,7 +1186,7 @@ const Shortcuts: React.FC<ShortcutsProps> = ({
|
|||||||
/>
|
/>
|
||||||
{
|
{
|
||||||
/* TODO(HLS): */
|
/* TODO(HLS): */
|
||||||
settingsSnapshot().isInternalUser && (
|
shouldUsePlayerV2() && (
|
||||||
<Shortcut
|
<Shortcut
|
||||||
action={pt("Play, Pause")}
|
action={pt("Play, Pause")}
|
||||||
shortcut={ut("Space")}
|
shortcut={ut("Space")}
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import { isDevBuild } from "ente-base/env";
|
|
||||||
import log from "ente-base/log";
|
import log from "ente-base/log";
|
||||||
import type { FileInfoExif } from "ente-gallery/components/FileInfo";
|
import type { FileInfoExif } from "ente-gallery/components/FileInfo";
|
||||||
import { downloadManager } from "ente-gallery/services/download";
|
import { downloadManager } from "ente-gallery/services/download";
|
||||||
import { extractRawExif, parseExif } from "ente-gallery/services/exif";
|
import { extractRawExif, parseExif } from "ente-gallery/services/exif";
|
||||||
import { hlsPlaylistDataForFile } from "ente-gallery/services/video";
|
import {
|
||||||
|
hlsPlaylistDataForFile,
|
||||||
|
type HLSPlaylistData,
|
||||||
|
} from "ente-gallery/services/video";
|
||||||
import type { EnteFile } from "ente-media/file";
|
import type { EnteFile } from "ente-media/file";
|
||||||
import { fileCaption } from "ente-media/file-metadata";
|
import { fileCaption } from "ente-media/file-metadata";
|
||||||
import { FileType } from "ente-media/file-type";
|
import { FileType } from "ente-media/file-type";
|
||||||
import { ensureString } from "ente-utils/ensure";
|
import { ensureString } from "ente-utils/ensure";
|
||||||
|
import { shouldUsePlayerV2 } from "./photoswipe";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a subset of the fields expected by PhotoSwipe itself (see the
|
* This is a subset of the fields expected by PhotoSwipe itself (see the
|
||||||
@ -412,6 +415,26 @@ const enqueueUpdates = async (
|
|||||||
_state.needsRefreshByFileID.get(file.id)?.();
|
_state.needsRefreshByFileID.get(file.id)?.();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateVideo = (
|
||||||
|
videoURL: string | undefined,
|
||||||
|
hlsPlaylistData: HLSPlaylistData | undefined,
|
||||||
|
) => {
|
||||||
|
const videoURLD = videoURL ? { videoURL } : {};
|
||||||
|
if (hlsPlaylistData) {
|
||||||
|
const {
|
||||||
|
playlistURL: videoPlaylistURL,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
} = hlsPlaylistData;
|
||||||
|
update(
|
||||||
|
{ ...videoURLD, videoPlaylistURL, width, height },
|
||||||
|
createHLSPlaylistItemDataValidity(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
update(videoURLD);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Use the last best available data, but stop showing the loading indicator
|
// Use the last best available data, but stop showing the loading indicator
|
||||||
// and instead show the error indicator.
|
// and instead show the error indicator.
|
||||||
const markFailed = () => {
|
const markFailed = () => {
|
||||||
@ -449,24 +472,15 @@ const enqueueUpdates = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (isDevBuild && process.env.NEXT_PUBLIC_ENTE_WIP_VIDEO_STREAMING) {
|
// TODO(HLS):
|
||||||
if (
|
let hlsPlaylistData: HLSPlaylistData | undefined;
|
||||||
file.metadata.fileType == FileType.video &&
|
if (shouldUsePlayerV2() && file.metadata.fileType == FileType.video) {
|
||||||
opts?.videoQuality != "original"
|
hlsPlaylistData = await hlsPlaylistDataForFile(file);
|
||||||
) {
|
// We have a HLS playlist, and the user didn't request the original.
|
||||||
const playlistData = await hlsPlaylistDataForFile(file);
|
// Early return so that we don't initiate a fetch for the original.
|
||||||
if (playlistData) {
|
if (hlsPlaylistData && opts?.videoQuality != "original") {
|
||||||
const {
|
updateVideo(undefined, hlsPlaylistData);
|
||||||
playlistURL: videoPlaylistURL,
|
return;
|
||||||
width,
|
|
||||||
height,
|
|
||||||
} = playlistData;
|
|
||||||
update(
|
|
||||||
{ videoPlaylistURL, width, height },
|
|
||||||
createHLSPlaylistItemDataValidity(),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,7 +496,7 @@ const enqueueUpdates = async (
|
|||||||
|
|
||||||
case "video": {
|
case "video": {
|
||||||
const { videoURL } = sourceURLs;
|
const { videoURL } = sourceURLs;
|
||||||
update({ videoURL });
|
updateVideo(videoURL, hlsPlaylistData);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,10 @@ import { pt } from "ente-base/i18n";
|
|||||||
import log from "ente-base/log";
|
import log from "ente-base/log";
|
||||||
import type { EnteFile } from "ente-media/file";
|
import type { EnteFile } from "ente-media/file";
|
||||||
import { FileType } from "ente-media/file-type";
|
import { FileType } from "ente-media/file-type";
|
||||||
import { settingsSnapshot } from "ente-new/photos/services/settings";
|
import {
|
||||||
|
isDevBuildAndUser,
|
||||||
|
settingsSnapshot,
|
||||||
|
} from "ente-new/photos/services/settings";
|
||||||
import "hls-video-element";
|
import "hls-video-element";
|
||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import "media-chrome";
|
import "media-chrome";
|
||||||
@ -164,6 +167,12 @@ export const moreButtonID = "ente-pswp-more-button";
|
|||||||
*/
|
*/
|
||||||
export const moreMenuID = "ente-pswp-more-menu";
|
export const moreMenuID = "ente-pswp-more-menu";
|
||||||
|
|
||||||
|
// TODO(HLS):
|
||||||
|
let _shouldUsePlayerV2: boolean | undefined;
|
||||||
|
export const shouldUsePlayerV2 = () =>
|
||||||
|
(_shouldUsePlayerV2 ??=
|
||||||
|
settingsSnapshot().isInternalUser && isDevBuildAndUser());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper over {@link PhotoSwipe} to tailor its interface for use by our file
|
* A wrapper over {@link PhotoSwipe} to tailor its interface for use by our file
|
||||||
* viewer.
|
* viewer.
|
||||||
@ -203,9 +212,6 @@ export class FileViewerPhotoSwipe {
|
|||||||
onDownload,
|
onDownload,
|
||||||
onMore,
|
onMore,
|
||||||
}: FileViewerPhotoSwipeOptions) {
|
}: FileViewerPhotoSwipeOptions) {
|
||||||
// TODO(HLS):
|
|
||||||
const showPlayerV2 = settingsSnapshot().isInternalUser;
|
|
||||||
|
|
||||||
const pswp = new PhotoSwipe({
|
const pswp = new PhotoSwipe({
|
||||||
// Opaque background.
|
// Opaque background.
|
||||||
bgOpacity: 1,
|
bgOpacity: 1,
|
||||||
@ -340,7 +346,7 @@ export class FileViewerPhotoSwipe {
|
|||||||
html: hlsVideoHTML(videoPlaylistURL, mcID),
|
html: hlsVideoHTML(videoPlaylistURL, mcID),
|
||||||
mediaControllerID: mcID,
|
mediaControllerID: mcID,
|
||||||
};
|
};
|
||||||
} else if (videoURL && showPlayerV2) {
|
} else if (videoURL && shouldUsePlayerV2()) {
|
||||||
const mcID = `ente-mc-orig-${file.id}`;
|
const mcID = `ente-mc-orig-${file.id}`;
|
||||||
return {
|
return {
|
||||||
...itemData,
|
...itemData,
|
||||||
@ -522,7 +528,7 @@ export class FileViewerPhotoSwipe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(HLS): Temporary gate
|
// TODO(HLS): Temporary gate
|
||||||
if (!showPlayerV2) return;
|
if (!shouldUsePlayerV2()) return;
|
||||||
|
|
||||||
const qualityMenu = container?.querySelector("#ente-quality-menu");
|
const qualityMenu = container?.querySelector("#ente-quality-menu");
|
||||||
if (qualityMenu instanceof MediaChromeMenu) {
|
if (qualityMenu instanceof MediaChromeMenu) {
|
||||||
@ -731,7 +737,7 @@ export class FileViewerPhotoSwipe {
|
|||||||
|
|
||||||
if (videoVideoEl) {
|
if (videoVideoEl) {
|
||||||
onVideoPlayback = () => {
|
onVideoPlayback = () => {
|
||||||
if (!showPlayerV2)
|
if (!shouldUsePlayerV2())
|
||||||
showIf(captionElement!, !!videoVideoEl?.paused);
|
showIf(captionElement!, !!videoVideoEl?.paused);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -763,7 +769,7 @@ export class FileViewerPhotoSwipe {
|
|||||||
*/
|
*/
|
||||||
const videoToggleMuteIfPossible = () => {
|
const videoToggleMuteIfPossible = () => {
|
||||||
// TODO(HLS): Temporary gate
|
// TODO(HLS): Temporary gate
|
||||||
if (!showPlayerV2) {
|
if (!shouldUsePlayerV2()) {
|
||||||
const video = videoVideoEl;
|
const video = videoVideoEl;
|
||||||
if (!video) return;
|
if (!video) return;
|
||||||
|
|
||||||
@ -1114,7 +1120,7 @@ export class FileViewerPhotoSwipe {
|
|||||||
const handleSeekBackOrPreviousSlide = () => {
|
const handleSeekBackOrPreviousSlide = () => {
|
||||||
// TODO(HLS): Behind temporary flag
|
// TODO(HLS): Behind temporary flag
|
||||||
// const vid = videoVideoEl;
|
// const vid = videoVideoEl;
|
||||||
const vid = showPlayerV2 ? videoVideoEl : undefined;
|
const vid = shouldUsePlayerV2() ? videoVideoEl : undefined;
|
||||||
if (vid) {
|
if (vid) {
|
||||||
vid.currentTime = Math.max(vid.currentTime - 5, 0);
|
vid.currentTime = Math.max(vid.currentTime - 5, 0);
|
||||||
} else {
|
} else {
|
||||||
@ -1125,7 +1131,7 @@ export class FileViewerPhotoSwipe {
|
|||||||
const handleSeekForwardOrNextSlide = () => {
|
const handleSeekForwardOrNextSlide = () => {
|
||||||
// TODO(HLS): Behind temporary flag
|
// TODO(HLS): Behind temporary flag
|
||||||
// const vid = videoVideoEl;
|
// const vid = videoVideoEl;
|
||||||
const vid = showPlayerV2 ? videoVideoEl : undefined;
|
const vid = shouldUsePlayerV2() ? videoVideoEl : undefined;
|
||||||
if (vid) {
|
if (vid) {
|
||||||
vid.currentTime = vid.currentTime + 5;
|
vid.currentTime = vid.currentTime + 5;
|
||||||
} else {
|
} else {
|
||||||
|
@ -7,7 +7,7 @@ import { ensurePrecondition } from "ente-utils/ensure";
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { fetchFileData, fetchFilePreviewData } from "./file-data";
|
import { fetchFileData, fetchFilePreviewData } from "./file-data";
|
||||||
|
|
||||||
interface HLSPlaylistData {
|
export interface HLSPlaylistData {
|
||||||
/** A data URL to a HLS playlist that streams the video. */
|
/** A data URL to a HLS playlist that streams the video. */
|
||||||
playlistURL: string;
|
playlistURL: string;
|
||||||
/** The width of the video (px). */
|
/** The width of the video (px). */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user