Spaces:
Running
Running
test sharing function
Browse files- app/page.tsx +0 -1
- components/form.tsx +32 -3
- utils/index.ts +15 -1
app/page.tsx
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
import { Form } from "@/components/form";
|
2 |
-
import Image from "next/image";
|
3 |
|
4 |
export default function Home() {
|
5 |
return (
|
|
|
1 |
import { Form } from "@/components/form";
|
|
|
2 |
|
3 |
export default function Home() {
|
4 |
return (
|
components/form.tsx
CHANGED
@@ -11,8 +11,8 @@ import { Length } from "@/components/length";
|
|
11 |
import { Styles } from "@/components/styles";
|
12 |
import { Moods } from "@/components/moods";
|
13 |
import { useGeneration } from "@/components/hooks/useGeneration";
|
14 |
-
import { useState, useRef, useEffect } from "react";
|
15 |
-
import { encodeWAV, MODEL_ID } from "@/utils";
|
16 |
import classNames from "classnames";
|
17 |
|
18 |
class CallbackStreamer extends BaseStreamer {
|
@@ -38,6 +38,7 @@ export const Form = ({ children }: { children: React.ReactNode }) => {
|
|
38 |
const [statusText, setStatusText] = useState("Loading model (656MB)...");
|
39 |
const [loadProgress, setLoadProgress] = useState({});
|
40 |
const [track, setTrack] = useState("");
|
|
|
41 |
|
42 |
const {
|
43 |
form,
|
@@ -53,6 +54,8 @@ export const Form = ({ children }: { children: React.ReactNode }) => {
|
|
53 |
const modelPromise = useRef(null);
|
54 |
const tokenizerPromise = useRef(null);
|
55 |
|
|
|
|
|
56 |
useEffect(() => {
|
57 |
modelPromise.current ??= MusicgenForConditionalGeneration.from_pretrained(
|
58 |
MODEL_ID,
|
@@ -205,8 +208,34 @@ export const Form = ({ children }: { children: React.ReactNode }) => {
|
|
205 |
)}
|
206 |
{modelLoaded &&
|
207 |
(track !== "" ? (
|
208 |
-
<div className="mx-auto">
|
209 |
<audio controls src={track} />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
</div>
|
211 |
) : (
|
212 |
<div className="mx-auto w-full max-w-sm border rounded-xl p-6 bg-amber-900/10 border-white/10 overflow-hidden transition-all duration-200">
|
|
|
11 |
import { Styles } from "@/components/styles";
|
12 |
import { Moods } from "@/components/moods";
|
13 |
import { useGeneration } from "@/components/hooks/useGeneration";
|
14 |
+
import { useState, useRef, useEffect, useMemo } from "react";
|
15 |
+
import { encodeWAV, MODEL_ID, share } from "@/utils";
|
16 |
import classNames from "classnames";
|
17 |
|
18 |
class CallbackStreamer extends BaseStreamer {
|
|
|
38 |
const [statusText, setStatusText] = useState("Loading model (656MB)...");
|
39 |
const [loadProgress, setLoadProgress] = useState({});
|
40 |
const [track, setTrack] = useState("");
|
41 |
+
const [shareLoading, setShareLoading] = useState(false);
|
42 |
|
43 |
const {
|
44 |
form,
|
|
|
54 |
const modelPromise = useRef(null);
|
55 |
const tokenizerPromise = useRef(null);
|
56 |
|
57 |
+
const SHARING_ENABLED = window?.location?.host.endsWith(".hf.space");
|
58 |
+
|
59 |
useEffect(() => {
|
60 |
modelPromise.current ??= MusicgenForConditionalGeneration.from_pretrained(
|
61 |
MODEL_ID,
|
|
|
208 |
)}
|
209 |
{modelLoaded &&
|
210 |
(track !== "" ? (
|
211 |
+
<div className="mx-auto flex flex-col gap-5 justify-center">
|
212 |
<audio controls src={track} />
|
213 |
+
{SHARING_ENABLED && (
|
214 |
+
<button
|
215 |
+
className={classNames(
|
216 |
+
"rounded-xl bg-amber-500/10 border-amber-500 border px-6 py-3 font-semibold text-base text-amber-500 mt-6 hover:bg-amber-500 hover:text-white transition-all duration-200 relative",
|
217 |
+
{
|
218 |
+
"animate-pulse": shareLoading,
|
219 |
+
}
|
220 |
+
)}
|
221 |
+
onClick={async (e) => {
|
222 |
+
if (shareLoading) return;
|
223 |
+
await share(
|
224 |
+
track,
|
225 |
+
{
|
226 |
+
mood: form.mood,
|
227 |
+
style: form.style,
|
228 |
+
duration: form.length,
|
229 |
+
prompt: form.prompt,
|
230 |
+
formatted_prompt: formattedPrompt,
|
231 |
+
},
|
232 |
+
results
|
233 |
+
);
|
234 |
+
}}
|
235 |
+
>
|
236 |
+
Share my song
|
237 |
+
</button>
|
238 |
+
)}
|
239 |
</div>
|
240 |
) : (
|
241 |
<div className="mx-auto w-full max-w-sm border rounded-xl p-6 bg-amber-900/10 border-white/10 overflow-hidden transition-all duration-200">
|
utils/index.ts
CHANGED
@@ -266,4 +266,18 @@ function writeString(view: any, offset: number, string: string) {
|
|
266 |
}
|
267 |
}
|
268 |
|
269 |
-
export const MODEL_ID = 'Xenova/musicgen-small';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
266 |
}
|
267 |
}
|
268 |
|
269 |
+
export const MODEL_ID = 'Xenova/musicgen-small';
|
270 |
+
|
271 |
+
export async function share(body: any, settings: Record<string, any>, results: Record<string, any>) {
|
272 |
+
const response = await fetch('https://huggingface.co/uploads', { method: 'POST', body });
|
273 |
+
if (!response.ok) throw new Error(`Failed to upload audio: ${response.statusText}`);
|
274 |
+
const url = await response.text();
|
275 |
+
|
276 |
+
const params = new URLSearchParams({
|
277 |
+
title: `🎵 ${results.title}`,
|
278 |
+
description: `<audio controls src="${url}"></audio>\n${JSON.stringify(settings, null, 2)}`,
|
279 |
+
});
|
280 |
+
|
281 |
+
const shareURL = `https://huggingface.co/spaces/enzostvs/ai-jukebox/discussions/new?${params.toString()}`;
|
282 |
+
window.open(shareURL, '_blank');
|
283 |
+
}
|