mirror of
https://github.com/p-stream/p-stream.git
synced 2026-03-11 17:55:33 +00:00
Merge branch 'p-stream:production' into substranslate
This commit is contained in:
commit
a2446cf931
1 changed files with 107 additions and 6 deletions
|
|
@ -6,6 +6,7 @@ import { Toggle } from "@/components/buttons/Toggle";
|
||||||
import { Dropdown } from "@/components/form/Dropdown";
|
import { Dropdown } from "@/components/form/Dropdown";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icon, Icons } from "@/components/Icon";
|
||||||
import { usePlayer } from "@/components/player/hooks/usePlayer";
|
import { usePlayer } from "@/components/player/hooks/usePlayer";
|
||||||
|
import { convertProviderCaption } from "@/components/player/utils/captions";
|
||||||
import { Title } from "@/components/text/Title";
|
import { Title } from "@/components/text/Title";
|
||||||
import { AuthInputBox } from "@/components/text-inputs/AuthInputBox";
|
import { AuthInputBox } from "@/components/text-inputs/AuthInputBox";
|
||||||
import { TextInputControl } from "@/components/text-inputs/TextInputControl";
|
import { TextInputControl } from "@/components/text-inputs/TextInputControl";
|
||||||
|
|
@ -140,6 +141,101 @@ export default function VideoTesterView() {
|
||||||
[playMedia, setMeta, headersEnabled, headers, extensionState],
|
[playMedia, setMeta, headersEnabled, headers, extensionState],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const startFromCli = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
const clipboardText = await navigator.clipboard.readText();
|
||||||
|
|
||||||
|
// Parse JavaScript object notation by evaluating it safely
|
||||||
|
let cliData;
|
||||||
|
try {
|
||||||
|
// Try to parse as JSON first (in case it's already valid JSON)
|
||||||
|
cliData = JSON.parse(clipboardText);
|
||||||
|
} catch {
|
||||||
|
// If JSON parsing fails, try to evaluate as JavaScript object
|
||||||
|
try {
|
||||||
|
// Use Function constructor to safely evaluate the JavaScript object
|
||||||
|
// eslint-disable-next-line no-new-func
|
||||||
|
cliData = new Function(`return (${clipboardText})`)();
|
||||||
|
} catch {
|
||||||
|
throw new Error(
|
||||||
|
"Invalid JavaScript object format. Please ensure the CLI output is properly formatted.",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!cliData.stream ||
|
||||||
|
!Array.isArray(cliData.stream) ||
|
||||||
|
cliData.stream.length === 0
|
||||||
|
) {
|
||||||
|
throw new Error("Invalid CLI output: no stream data found");
|
||||||
|
}
|
||||||
|
|
||||||
|
const streamData = cliData.stream[0]; // Take the first stream
|
||||||
|
|
||||||
|
let source: SourceSliceSource;
|
||||||
|
if (streamData.type === "hls") {
|
||||||
|
source = {
|
||||||
|
type: "hls",
|
||||||
|
url: streamData.playlist,
|
||||||
|
...(streamData.headers && { headers: streamData.headers }),
|
||||||
|
};
|
||||||
|
} else if (streamData.type === "file") {
|
||||||
|
// Handle file type streams
|
||||||
|
const qualities = streamData.qualities || {};
|
||||||
|
const qualityKeys = Object.keys(qualities);
|
||||||
|
if (qualityKeys.length === 0) {
|
||||||
|
throw new Error("Invalid file stream: no qualities found");
|
||||||
|
}
|
||||||
|
source = {
|
||||||
|
type: "file",
|
||||||
|
qualities,
|
||||||
|
...(streamData.headers && { headers: streamData.headers }),
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unsupported stream type: ${streamData.type}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert captions
|
||||||
|
const captions = streamData.captions
|
||||||
|
? convertProviderCaption(streamData.captions)
|
||||||
|
: [];
|
||||||
|
|
||||||
|
// Prepare stream headers if extension is active and headers are present
|
||||||
|
if (
|
||||||
|
extensionState === "success" &&
|
||||||
|
streamData.headers &&
|
||||||
|
Object.keys(streamData.headers).length > 0
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
await prepareStream(streamData);
|
||||||
|
} catch (error) {
|
||||||
|
console.warn("Failed to prepare stream headers:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setMeta(testMeta);
|
||||||
|
playMedia(source, captions, streamData.id);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Failed to parse CLI data:", error);
|
||||||
|
|
||||||
|
let errorMessage =
|
||||||
|
error instanceof Error ? error.message : "Unknown error";
|
||||||
|
|
||||||
|
// Check for common JSON/JavaScript formatting issues
|
||||||
|
if (
|
||||||
|
errorMessage.includes("Expected property name") ||
|
||||||
|
errorMessage.includes("Unexpected token")
|
||||||
|
) {
|
||||||
|
errorMessage +=
|
||||||
|
"\n\nThe CLI output should be in JavaScript object format. Make sure you're copying the complete output from your CLI tool.";
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-alert
|
||||||
|
alert(`Failed to parse CLI data: ${errorMessage}`);
|
||||||
|
}
|
||||||
|
}, [playMedia, setMeta, extensionState]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PlayerPart backUrl="/dev">
|
<PlayerPart backUrl="/dev">
|
||||||
{status === playerStatus.IDLE ? (
|
{status === playerStatus.IDLE ? (
|
||||||
|
|
@ -172,7 +268,7 @@ export default function VideoTesterView() {
|
||||||
<div className="flex-1 mb-4">
|
<div className="flex-1 mb-4">
|
||||||
<div className="flex justify-between items-center gap-4">
|
<div className="flex justify-between items-center gap-4">
|
||||||
<div className="my-3">
|
<div className="my-3">
|
||||||
<p className="text-white font-bold">Headers (Beta)</p>
|
<p className="text-white font-bold">Headers</p>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Toggle
|
<Toggle
|
||||||
|
|
@ -228,11 +324,16 @@ export default function VideoTesterView() {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<Button
|
<div className="flex gap-2">
|
||||||
onClick={() => start(inputSource, selected as StreamType)}
|
<Button
|
||||||
>
|
onClick={() => start(inputSource, selected as StreamType)}
|
||||||
Start stream
|
>
|
||||||
</Button>
|
Start stream
|
||||||
|
</Button>
|
||||||
|
<Button onClick={startFromCli} className="col-span-2">
|
||||||
|
Paste from CLI
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<Title>Preset tests</Title>
|
<Title>Preset tests</Title>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue