From 87e8333d05448879a36020e8a6807ea9d190734c Mon Sep 17 00:00:00 2001 From: ElementalAlchemist Date: Sun, 10 Nov 2024 20:50:10 -0600 Subject: [PATCH] Add video load time fields to restreamer --- thrimbletrimmer/src/common/convertTime.tsx | 6 + thrimbletrimmer/src/common/video.module.scss | 11 ++ thrimbletrimmer/src/common/video.tsx | 179 ++++++++++++++++++ thrimbletrimmer/src/common/videoData.tsx | 3 - .../src/common/videoKeyboardShortcuts.tsx | 45 ----- thrimbletrimmer/src/index.tsx | 2 +- .../src/restreamer/Restreamer.module.scss | 2 +- thrimbletrimmer/src/restreamer/Restreamer.tsx | 66 ++++++- .../src/utilities/TimeConverter.tsx | 7 +- 9 files changed, 261 insertions(+), 60 deletions(-) create mode 100644 thrimbletrimmer/src/common/video.module.scss create mode 100644 thrimbletrimmer/src/common/video.tsx delete mode 100644 thrimbletrimmer/src/common/videoData.tsx delete mode 100644 thrimbletrimmer/src/common/videoKeyboardShortcuts.tsx diff --git a/thrimbletrimmer/src/common/convertTime.tsx b/thrimbletrimmer/src/common/convertTime.tsx index 5b0785b..d4d749c 100644 --- a/thrimbletrimmer/src/common/convertTime.tsx +++ b/thrimbletrimmer/src/common/convertTime.tsx @@ -1,5 +1,11 @@ import { DateTime } from "luxon"; +export enum TimeType { + UTC, + BusTime, + TimeAgo, +} + export function dateTimeFromWubloaderTime(wubloaderTime: string): DateTime | null { const dt = DateTime.fromISO(wubloaderTime, { zone: "UTC" }); if (dt.isValid) { diff --git a/thrimbletrimmer/src/common/video.module.scss b/thrimbletrimmer/src/common/video.module.scss new file mode 100644 index 0000000..f40dd5c --- /dev/null +++ b/thrimbletrimmer/src/common/video.module.scss @@ -0,0 +1,11 @@ +.streamTimeSettings { + display: flex; + align-items: flex-end; + gap: 5px; + margin-bottom: 10px; + margin-top: 5px; +} + +.streamTimeSettingLabel { + margin-right: 3px; +} \ No newline at end of file diff --git a/thrimbletrimmer/src/common/video.tsx b/thrimbletrimmer/src/common/video.tsx new file mode 100644 index 0000000..86aa053 --- /dev/null +++ b/thrimbletrimmer/src/common/video.tsx @@ -0,0 +1,179 @@ +import { Accessor, Component, createSignal, Setter, Show } from "solid-js"; +import { DateTime } from "luxon"; +import { + TimeType, + wubloaderTimeFromDateTime, + busTimeFromDateTime, + timeAgoFromDateTime, +} from "./convertTime"; +import styles from "./video.module.scss"; + +export const VIDEO_FRAMES_PER_SECOND = 30; + +export const PLAYBACK_RATES = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 4, 8]; + +export class StreamVideoInfo { + streamName: string; + streamStartTime: DateTime; + streamEndTime: DateTime | null; +} + +export interface StreamTimeSettingsProps { + busStartTime: Accessor; + streamVideoInfo: Accessor; + setStreamVideoInfo: Setter; + showTimeRangeLink: boolean; +} + +export const StreamTimeSettings: Component = (props) => { + const [timeType, setTimeType] = createSignal(TimeType.UTC); + + const submitHandler = (event: SubmitEvent) => { + const form = event.currentTarget as HTMLFormElement; + const formData = new FormData(form); + + // TODO + }; + + const startTimeDisplay = () => { + const startTime = props.streamVideoInfo().streamStartTime; + switch (timeType()) { + case TimeType.UTC: + return wubloaderTimeFromDateTime(startTime); + case TimeType.BusTime: + return busTimeFromDateTime(props.busStartTime(), startTime); + case TimeType.TimeAgo: + return timeAgoFromDateTime(startTime); + } + }; + + const endTimeDisplay = () => { + const endTime = props.streamVideoInfo().streamEndTime; + if (endTime === null) { + return ""; + } + switch (timeType()) { + case TimeType.UTC: + return wubloaderTimeFromDateTime(endTime); + case TimeType.BusTime: + return busTimeFromDateTime(props.busStartTime(), endTime); + case TimeType.TimeAgo: + return timeAgoFromDateTime(endTime); + } + }; + + const timeRangeLink = () => { + const streamInfo = props.streamVideoInfo(); + const startTime = wubloaderTimeFromDateTime(streamInfo.streamStartTime); + const query = new URLSearchParams({ + stream: streamInfo.streamName, + start: startTime, + }); + if (streamInfo.streamEndTime) { + const endTime = wubloaderTimeFromDateTime(streamInfo.streamEndTime); + query.append("end", endTime); + } + return `?${query}`; + }; + + return ( +
+ + + +
+ + + +
+
+ +
+ + + +
+ ); +}; + +export interface KeyboardShortcutProps { + includeEditorShortcuts: boolean; +} + +export const KeyboardShortcuts: Component = ( + props: KeyboardShortcutProps, +) => { + return ( +
+ Keyboard Shortcuts +
    +
  • Number keys (0-9): Jump to that 10% interval of the video (0% - 90%)
  • +
  • K or Space: Toggle pause
  • +
  • M: Toggle mute
  • +
  • J: Back 10 seconds
  • +
  • L: Forward 10 seconds
  • +
  • Left arrow: Back 5 seconds
  • +
  • Right arrow: Forward 5 seconds
  • +
  • Shift+J: Back 1 second
  • +
  • Shift+L: Forward 1 second
  • +
  • Comma (,): Back 1 frame
  • +
  • Period (.): Forward 1 frame
  • +
  • Equals (=): Increase playback speed 1 step
  • +
  • Hyphen (-): Decrease playback speed 1 step
  • +
  • Shift+=: 2x or maximum playback speed
  • +
  • Shift+-: Minimum playback speed
  • +
  • Backspace: Reset playback speed to 1x
  • + +
  • + Left bracket ([): Set start point for active range (indicated by arrow) to current video + time +
  • +
  • Right bracket (]): Set end point for active range to current video time
  • +
  • O: Set active range one above current active range
  • +
  • + P: Set active range one below current active range, adding a new range if the current + range is the last one +
  • +
    +
+
+ ); +}; diff --git a/thrimbletrimmer/src/common/videoData.tsx b/thrimbletrimmer/src/common/videoData.tsx deleted file mode 100644 index b75e4a8..0000000 --- a/thrimbletrimmer/src/common/videoData.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export const VIDEO_FRAMES_PER_SECOND = 30; - -export const PLAYBACK_RATES = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, 4, 8]; diff --git a/thrimbletrimmer/src/common/videoKeyboardShortcuts.tsx b/thrimbletrimmer/src/common/videoKeyboardShortcuts.tsx deleted file mode 100644 index c7174c8..0000000 --- a/thrimbletrimmer/src/common/videoKeyboardShortcuts.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { Component, Show } from "solid-js"; - -export interface KeyboardShortcutProps { - includeEditorShortcuts: boolean; -} - -export const KeyboardShortcuts: Component = ( - props: KeyboardShortcutProps, -) => { - return ( -
- Keyboard Shortcuts -
    -
  • Number keys (0-9): Jump to that 10% interval of the video (0% - 90%)
  • -
  • K or Space: Toggle pause
  • -
  • M: Toggle mute
  • -
  • J: Back 10 seconds
  • -
  • L: Forward 10 seconds
  • -
  • Left arrow: Back 5 seconds
  • -
  • Right arrow: Forward 5 seconds
  • -
  • Shift+J: Back 1 second
  • -
  • Shift+L: Forward 1 second
  • -
  • Comma (,): Back 1 frame
  • -
  • Period (.): Forward 1 frame
  • -
  • Equals (=): Increase playback speed 1 step
  • -
  • Hyphen (-): Decrease playback speed 1 step
  • -
  • Shift+=: 2x or maximum playback speed
  • -
  • Shift+-: Minimum playback speed
  • -
  • Backspace: Reset playback speed to 1x
  • - -
  • - Left bracket ([): Set start point for active range (indicated by arrow) to current video - time -
  • -
  • Right bracket (]): Set end point for active range to current video time
  • -
  • O: Set active range one above current active range
  • -
  • - P: Set active range one below current active range, adding a new range if the current - range is the last one -
  • -
    -
-
- ); -}; diff --git a/thrimbletrimmer/src/index.tsx b/thrimbletrimmer/src/index.tsx index f77959c..5ff2f37 100644 --- a/thrimbletrimmer/src/index.tsx +++ b/thrimbletrimmer/src/index.tsx @@ -1,6 +1,6 @@ import "./globalStyle.scss"; import { render } from "solid-js/web"; -import Restreamer from "./restreamer/Restreamer"; +import { Restreamer } from "./restreamer/Restreamer"; const root = document.getElementById("root"); diff --git a/thrimbletrimmer/src/restreamer/Restreamer.module.scss b/thrimbletrimmer/src/restreamer/Restreamer.module.scss index 469d082..d00753c 100644 --- a/thrimbletrimmer/src/restreamer/Restreamer.module.scss +++ b/thrimbletrimmer/src/restreamer/Restreamer.module.scss @@ -18,4 +18,4 @@ position: absolute; top: 0; right: 0; -} \ No newline at end of file +} diff --git a/thrimbletrimmer/src/restreamer/Restreamer.tsx b/thrimbletrimmer/src/restreamer/Restreamer.tsx index 954ffc2..ca31f94 100644 --- a/thrimbletrimmer/src/restreamer/Restreamer.tsx +++ b/thrimbletrimmer/src/restreamer/Restreamer.tsx @@ -1,9 +1,38 @@ -import { Accessor, Component, createSignal, For } from "solid-js"; +import { Accessor, Component, createResource, createSignal, For, Show, Suspense } from "solid-js"; +import { DateTime } from "luxon"; import styles from "./Restreamer.module.scss"; -import { KeyboardShortcuts } from "../common/videoKeyboardShortcuts"; +import { dateTimeFromWubloaderTime } from "../common/convertTime"; +import { KeyboardShortcuts, StreamTimeSettings, StreamVideoInfo } from "../common/video"; -const Restreamer: Component = () => { +export interface DefaultsData { + video_channel: string; + bustime_start: string; + title_prefix: string; + title_max_length: string; + upload_locations: string[]; +} + +export const Restreamer: Component = () => { const [pageErrors, setPageErrors] = createSignal([]); + const [defaultsData] = createResource( + async (source, { value, refetching }) => { + const response = await fetch("/thrimshim/defaults"); + if (!response.ok) { + return null; + } + return await response.json(); + }, + ); + + const busStartTime = () => { + const defaults = defaultsData(); + if (defaults && defaults.hasOwnProperty("bustime_start")) { + return dateTimeFromWubloaderTime(defaults.bustime_start); + } + return null; + }; + + const now = DateTime.utc(); return ( <> @@ -20,8 +49,37 @@ const Restreamer: Component = () => {
+ + + + + ); }; -export default Restreamer; +interface RestreamerDefaultProps { + defaults: DefaultsData; +} + +const RestreamerWithDefaults: Component = (props) => { + const [busStartTime, setBusStartTime] = createSignal( + dateTimeFromWubloaderTime(props.defaults.bustime_start), + ); + const [streamVideoInfo, setStreamVideoInfo] = createSignal({ + streamName: props.defaults.video_channel, + streamStartTime: DateTime.utc().minus({ minutes: 10 }), + streamEndTime: null, + }); + + return ( + <> + + + ); +}; diff --git a/thrimbletrimmer/src/utilities/TimeConverter.tsx b/thrimbletrimmer/src/utilities/TimeConverter.tsx index a4c0e69..42cd6fd 100644 --- a/thrimbletrimmer/src/utilities/TimeConverter.tsx +++ b/thrimbletrimmer/src/utilities/TimeConverter.tsx @@ -7,18 +7,13 @@ import { wubloaderTimeFromDateTime, busTimeFromDateTime, timeAgoFromDateTime, + TimeType, } from "../common/convertTime"; interface TimeConverterProps { busStartTime: Accessor; } -enum TimeType { - UTC, - BusTime, - TimeAgo, -} - const TimeConverter: Component = (props) => { const [enteredTime, setEnteredTime] = createSignal(""); const [startTimeType, setStartTimeType] = createSignal(TimeType.UTC);