mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-05 17:58:55 +00:00
voice clone request page (wip)
This commit is contained in:
1 parent
a314fab0bc
commit
b9eb7eccd8
4 files changed
+420
No files matched your search
@@ -0,0 +1,86 @@
|
||||
|
||||
import { ApiConfig } from "@storyteller/components";
|
||||
|
||||
export interface CreateVoiceCloneApplicationRequest {
|
||||
|
||||
idempotency_token: string,
|
||||
|
||||
// Contact
|
||||
email_address: string,
|
||||
discord_username: string,
|
||||
|
||||
// TODO: Make enum.
|
||||
// Visibility
|
||||
is_for_private_use: boolean,
|
||||
is_for_public_use: boolean,
|
||||
|
||||
// Use
|
||||
is_for_studio: boolean,
|
||||
is_for_twitch_tts: boolean,
|
||||
is_for_api_use: boolean,
|
||||
is_for_music: boolean,
|
||||
is_for_games: boolean,
|
||||
is_for_other: boolean,
|
||||
optional_notes_on_use?: string,
|
||||
|
||||
// Subject/Ownership
|
||||
is_own_voice: boolean,
|
||||
is_third_party_voice: boolean,
|
||||
optional_notes_on_subject?: string,
|
||||
|
||||
// Equipment
|
||||
has_clean_audio_recordings: boolean,
|
||||
has_good_microphone: boolean,
|
||||
|
||||
// Comments
|
||||
optional_questions?: string,
|
||||
optional_extra_comments?: string,
|
||||
}
|
||||
|
||||
export interface CreateVoiceCloneApplicationSuccessResponse {
|
||||
success: boolean,
|
||||
}
|
||||
|
||||
export interface CreateVoiceCloneApplicationErrorResponse {
|
||||
success: boolean,
|
||||
}
|
||||
|
||||
type CreateVoiceCloneApplicationResponse = CreateVoiceCloneApplicationSuccessResponse | CreateVoiceCloneApplicationErrorResponse;
|
||||
|
||||
export function CreateVoiceCloneApplicationIsSuccess(response: CreateVoiceCloneApplicationResponse): response is CreateVoiceCloneApplicationSuccessResponse {
|
||||
return response?.success === true;
|
||||
}
|
||||
|
||||
export function CreateVoiceCloneApplicationIsError(response: CreateVoiceCloneApplicationResponse): response is CreateVoiceCloneApplicationErrorResponse {
|
||||
return response?.success === false;
|
||||
}
|
||||
|
||||
export async function CreateVoiceCloneApplication(request: CreateVoiceCloneApplicationRequest) : Promise<CreateVoiceCloneApplicationResponse>
|
||||
{
|
||||
const endpoint = new ApiConfig().createVoiceCloneRequest();
|
||||
|
||||
return await fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
credentials: 'include',
|
||||
body: JSON.stringify(request),
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(res => {
|
||||
if (!res) {
|
||||
return { success : false };
|
||||
}
|
||||
|
||||
if (res && 'success' in res) {
|
||||
return res;
|
||||
} else {
|
||||
return { success : false };
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
return { success : false };
|
||||
});
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 180 KiB |
@@ -0,0 +1,8 @@
|
||||
|
||||
.checkbox-block {
|
||||
margin: 5px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.checkbox-block label {
|
||||
margin: 0 0 10px;
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
import './VoiceCloneRequestPage.css';
|
||||
|
||||
import { faEnvelope } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
interface Props {
|
||||
}
|
||||
|
||||
function VoiceCloneRequestPage(props: Props) {
|
||||
//const [leaderboard, setLeaderboard] = useState<Leaderboard|undefined>(undefined);
|
||||
//const [ttsLeaderboard, setTtsLeaderboard] = useState<Array<LeaderboardEntryForList>|undefined>(undefined);
|
||||
//const [w2lLeaderboard, setW2lLeaderboard] = useState<Array<LeaderboardEntryForList>|undefined>(undefined);
|
||||
//const [retryCount, setRetryCount] = useState(0);
|
||||
|
||||
//const getLeaderboard = useCallback(async () => {
|
||||
// const leaderboardReponse = await GetLeaderboard();
|
||||
|
||||
// if (GetLeaderboardIsOk(leaderboardReponse)) {
|
||||
// setLeaderboard(leaderboardReponse);
|
||||
// setTtsLeaderboard(leaderboardReponse.tts_leaderboard);
|
||||
// setW2lLeaderboard(leaderboardReponse.w2l_leaderboard);
|
||||
// } else if (GetLeaderboardIsErr(leaderboardReponse)) {
|
||||
// switch(leaderboardReponse) {
|
||||
// // TODO: There's an issue with the queries not returning before the deadline.
|
||||
// // I should add a Redis TTL cache to store the results and an async job to warm the cache.
|
||||
// case LeaderboardLookupError.NotFound:
|
||||
// if (retryCount < 3) {
|
||||
// setTimeout(() => getLeaderboard(), 1000);
|
||||
// setRetryCount(retryCount+1);
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//}, [retryCount]);
|
||||
|
||||
//useEffect(() => {
|
||||
// getLeaderboard();
|
||||
//}, [getLeaderboard]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
<section className="hero is-small">
|
||||
<div className="hero-body">
|
||||
|
||||
<div className="columns is-vcentered">
|
||||
|
||||
<div className="column is-one-third">
|
||||
<div className="mascot">
|
||||
<img src="/mascot/kitsune_pose4_black_2000.webp" alt="FakeYou's mascot!" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="column">
|
||||
<p className="title is-1">
|
||||
Professionally Clone Your Voice
|
||||
</p>
|
||||
<p className="subtitle is-3">
|
||||
(or any voice) for just $70
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="section">
|
||||
<div className="container">
|
||||
|
||||
<h1 className="title is-2">Want a Custom Voice You Can Use?</h1>
|
||||
<h1 className="subtitle is-4">For Music, Videos, Twitch Rewards, API, friends, family… whatever you want!</h1>
|
||||
|
||||
<p>
|
||||
We have an extremely talented staff that will personally handle your voice clone request.
|
||||
Please help us understand more about your voice and how you want to use it, and we'll be in touch
|
||||
shortly.
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
<h1 className="title is-3">First, how should we get in touch?</h1>
|
||||
|
||||
<div className="field">
|
||||
<label className="label">Email Address</label>
|
||||
<div className="control has-icons-left">
|
||||
<input className="input is-medium is-fullwidth" type="text" placeholder="Email Address" value="" />
|
||||
<span className="icon is-small is-left">
|
||||
<FontAwesomeIcon icon={faEnvelope} />
|
||||
</span>
|
||||
</div>
|
||||
<p className="help is-success"></p>
|
||||
<p className="help is-danger"></p>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<label className="label">
|
||||
Discord Username (Optional, but an alternate way to reach you.)
|
||||
<br />
|
||||
</label>
|
||||
<div className="control has-icons-left">
|
||||
<input className="input is-medium is-fullwidth" type="text" placeholder="Discord" value="" />
|
||||
<span className="icon is-small is-left">
|
||||
<FontAwesomeIcon icon={faEnvelope} />
|
||||
</span>
|
||||
</div>
|
||||
<p className="help">
|
||||
Don't forget the <em>#0000</em> part of your username!
|
||||
</p>
|
||||
<p className="help is-danger"></p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<h1 className="title is-3">How will you use it?</h1>
|
||||
|
||||
<p>Click as many as you plan to use!</p>
|
||||
|
||||
<br />
|
||||
|
||||
<div className="checkbox-block">
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" />
|
||||
For Music (for creating new songs)
|
||||
</label>
|
||||
|
||||
<br />
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" />
|
||||
For Games (because NPCs won't talk by themselves)
|
||||
</label>
|
||||
|
||||
<br />
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" />
|
||||
For Twitch TTS (creating rewards for my stream, helping me engage and monetize)
|
||||
</label>
|
||||
|
||||
<br />
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" />
|
||||
For API use (unlimited use of the FakeYou.com API for anything you want to build)
|
||||
</label>
|
||||
|
||||
<br />
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" />
|
||||
Other (Oooh, now we're curious!)
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div className="field">
|
||||
<label className="label">Let us know more about your use (optional)</label>
|
||||
<div className="control has-icons-left">
|
||||
<input className="input is-medium is-fullwidth" type="text" placeholder="Optional details" value="" />
|
||||
<span className="icon is-small is-left">
|
||||
<FontAwesomeIcon icon={faEnvelope} />
|
||||
</span>
|
||||
</div>
|
||||
<p className="help is-success"></p>
|
||||
<p className="help is-danger"></p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<h1 className="title is-3">Who's voice is this?</h1>
|
||||
|
||||
<p>If it's your voice, you'll be able to do anything you want with it. If it's another person's voice, you may have
|
||||
limits on how you can use it (eg. limits on commercialization.) That doesn't mean we can't help you. Even if you
|
||||
just want your favorite character so you can make Twitter memes, that's fine!</p>
|
||||
|
||||
<br />
|
||||
|
||||
<div className="checkbox-block">
|
||||
<div className="control">
|
||||
<label className="radio">
|
||||
<input type="radio" name="answer" />
|
||||
My own voice
|
||||
</label>
|
||||
<br />
|
||||
<label className="radio">
|
||||
<input type="radio" name="answer" />
|
||||
A family member's voice
|
||||
</label>
|
||||
<br />
|
||||
<label className="radio">
|
||||
<input type="radio" name="answer" />
|
||||
Another person's voice
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<h1 className="title is-3">How's your audio quality?</h1>
|
||||
|
||||
<p>It's okay if you don't have a quality source of audio, but the results are top notch only with a good recording setup.</p>
|
||||
|
||||
<br />
|
||||
|
||||
<div className="checkbox-block">
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" />
|
||||
I have a good microphone (and I know what a condenser microphone is)
|
||||
</label>
|
||||
|
||||
<br />
|
||||
|
||||
<label className="checkbox">
|
||||
<input type="checkbox" />
|
||||
I have really good preexisting recordings.
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<h1 className="title is-3">Anything else?</h1>
|
||||
|
||||
|
||||
<div className="field">
|
||||
<label className="label">Do you have any questions for us?</label>
|
||||
<div className="control">
|
||||
<textarea className="textarea" placeholder="Optional Questions"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="field">
|
||||
<label className="label">Do you have any important notes or details?</label>
|
||||
<div className="control">
|
||||
<textarea className="textarea" placeholder="Optional Notes"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{/*
|
||||
<p>Once you've linked Twitch with Storyteller, you can add the following page as an <em>OBS Browser Source</em>:</p>
|
||||
|
||||
<br />
|
||||
|
||||
<div className="field">
|
||||
<p className="control has-icons-left">
|
||||
<input className="input is-large" type="text" value={obsUrl} readOnly={true} />
|
||||
<span className="icon is-small is-left">
|
||||
<FontAwesomeIcon icon={faDiscord} />
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<a
|
||||
href={obsUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="button is-large is-info is-fullwidth"
|
||||
>
|
||||
Open In New Tab <FontAwesomeIcon icon={faExternalLinkAlt} />
|
||||
</a>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<h1 className="title is-2">Setup Instructions</h1>
|
||||
|
||||
<p>If you're not familiar with OBS or you need a refresher, here's a quick glance at the setup.</p>
|
||||
|
||||
<br />
|
||||
|
||||
<h1 className="title is-4">Step 1) Click <FontAwesomeIcon icon={faPlus} /> to add a new Browser Source</h1>
|
||||
|
||||
<img src="/obs-tutorial/obs-step1.webp" alt="step 1" />
|
||||
|
||||
<p>The bottom of OBS should have a plus icon (<FontAwesomeIcon icon={faPlus} />) to add new sources.
|
||||
You'll want to add a new <strong>Browser Source</strong>.</p>
|
||||
|
||||
<br />
|
||||
|
||||
<h1 className="title is-4">Step 2) Paste the URL into the configuration window</h1>
|
||||
|
||||
<img src="/obs-tutorial/obs-step2.webp" alt="step 2" />
|
||||
|
||||
<br />
|
||||
|
||||
<p>Remember, the URL is <code>{obsUrl}</code></p>
|
||||
|
||||
<br />
|
||||
|
||||
<h1 className="title is-4">Step 3) Activate the Page</h1>
|
||||
|
||||
<img src="/obs-tutorial/obs-step3.webp" alt="step 3" />
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<p>Right click the layer and select <em>“Interact”</em>.
|
||||
This will let you click the button and activate the service.</p>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<h1 className="title is-2">Good to go! <FontAwesomeIcon icon={faTwitch} /></h1>
|
||||
|
||||
<p>You can now hide the layer and make it invisible. The audio levels are also independently adjustable.</p>
|
||||
|
||||
<br />
|
||||
|
||||
<p>Have fun! We'll be back soon with some even more jaw-dropping utilities.</p>
|
||||
*/}
|
||||
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export { VoiceCloneRequestPage }
|
||||
Reference in new issue
Block a user