Spaces:
Running
Running
Commit
•
63769e0
1
Parent(s):
d708a3a
updating the README.md
Browse files- .env +3 -0
- README.md +59 -1
- package-lock.json +14 -0
- package.json +1 -0
- src/app/interface/left-menu/index.tsx +11 -0
- src/app/music/index.tsx +0 -0
- src/app/views/public-music-videos-view/index.tsx +46 -0
- src/app/views/public-video-view/index.tsx +0 -1
- src/types.ts +1 -0
.env
CHANGED
@@ -6,6 +6,9 @@ ADMIN_HUGGING_FACE_USERNAME=""
|
|
6 |
|
7 |
AI_TUBE_ROBOT_API="https://jbilcke-hf-ai-tube-robot.hf.space"
|
8 |
|
|
|
|
|
|
|
9 |
# ----------- CENSORSHIP -------
|
10 |
ENABLE_CENSORSHIP=
|
11 |
FINGERPRINT_KEY=
|
|
|
6 |
|
7 |
AI_TUBE_ROBOT_API="https://jbilcke-hf-ai-tube-robot.hf.space"
|
8 |
|
9 |
+
UPSTASH_REDIS_REST_URL=""
|
10 |
+
UPSTASH_REDIS_REST_TOKEN=""
|
11 |
+
|
12 |
# ----------- CENSORSHIP -------
|
13 |
ENABLE_CENSORSHIP=
|
14 |
FINGERPRINT_KEY=
|
README.md
CHANGED
@@ -10,4 +10,62 @@ app_port: 3000
|
|
10 |
|
11 |
# 🍿 AI Tube
|
12 |
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
# 🍿 AI Tube
|
12 |
|
13 |
+
## FAQ
|
14 |
+
|
15 |
+
### I don't like having to manually create a Hugging Face Dataset and edit files
|
16 |
+
|
17 |
+
There will be a UI to edit them in the future
|
18 |
+
|
19 |
+
### How often videos are generated?
|
20 |
+
|
21 |
+
There is a script (call AI Tube Robot) which check the Hugging Face platform every 5 minutes for new content.
|
22 |
+
However, once it starts generating a video, it will be kept busy for an hour or so (sometimes more),
|
23 |
+
and during this time the other videos will wait patiently.
|
24 |
+
|
25 |
+
### My video failed to generate! Is it lost?
|
26 |
+
|
27 |
+
That's the beauty of the dataset system: as long as you keep your video in your dataset,
|
28 |
+
and is not published yet (is not visible on the AI Tube home page), then for the AI Tube Robot it will still be marked as "TODO".
|
29 |
+
|
30 |
+
So.. you have nothing to do! Things should repair themselves automatically at some point,
|
31 |
+
although it can take a couple of days if the issue is more complex than it looks
|
32 |
+
(eg. a server is down, there is a bug somewhere, disk is full etc)
|
33 |
+
|
34 |
+
### I created a channel, but I don't see it in the list
|
35 |
+
|
36 |
+
It can take multiple hours for a channel to be made publicly visible.
|
37 |
+
This delay will be reduced in the future.
|
38 |
+
|
39 |
+
### Videos are taking too long to generate
|
40 |
+
|
41 |
+
AI Tube is about generating videos in the background, slowly.
|
42 |
+
|
43 |
+
It's the whole concept: to generate multi-minutes videos, with lot of stuff like audio, speech etc
|
44 |
+
(if you are only interested in generate a 2 to 4 sec silent video, I suggest you use RunwayML or Pika Labs).
|
45 |
+
|
46 |
+
Moreover, currently there are only a few servers available:
|
47 |
+
|
48 |
+
- text to speech: 1 server
|
49 |
+
- sdxl: multi servers (hugging face cloud inference api)
|
50 |
+
- stable video diffusion: 1 server
|
51 |
+
- lavie: 1 server
|
52 |
+
- hotshot xl: 1 server
|
53 |
+
- musicgen: 1 server
|
54 |
+
|
55 |
+
Which is why some time there is a longue queue of videos waiting to be generated, one after one.
|
56 |
+
If this project gains traction, it might get more ressources in the future.
|
57 |
+
|
58 |
+
### I don't hear music in my videos
|
59 |
+
|
60 |
+
Could be two reasons, either you are missing a "# Music" paragraph block in your Channel and/or Video, or there just was a network or computing issue when your video was generated.
|
61 |
+
|
62 |
+
This is all new technology based on research tools, so sometimes they can crash, be out of memory etc.. and not always restart automatically. I'm a team of one and I don't have the ressources to look into it right now, but I understand it can be a pain.
|
63 |
+
|
64 |
+
### There are large gaps of silence between speech / commentary / dialogue
|
65 |
+
|
66 |
+
This is a bug, it will be fixed in the future but I haven't had the opportunity to take a look yet (the cause is that I don't generate the video based on audio length yet).
|
67 |
+
|
68 |
+
### Can I clone AI Tube or download it to run on my machine?
|
69 |
+
|
70 |
+
AI Tube is designed to be a unique community and platform, not a downloadable tool or app.
|
71 |
+
Maybe one day there will be an offline version (similar to how my latent browser project worked), but for the moment the focus is on developing it as a community rather than a tool that can be cloned, rebranded, wrapped into ads by someone else etc.
|
package-lock.json
CHANGED
@@ -31,6 +31,7 @@
|
|
31 |
"@types/react": "18.2.15",
|
32 |
"@types/react-dom": "18.2.7",
|
33 |
"@types/uuid": "^9.0.2",
|
|
|
34 |
"autoprefixer": "10.4.14",
|
35 |
"class-variance-authority": "^0.6.1",
|
36 |
"clsx": "^2.0.0",
|
@@ -1921,6 +1922,14 @@
|
|
1921 |
"url": "https://opencollective.com/typescript-eslint"
|
1922 |
}
|
1923 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1924 |
"node_modules/acorn": {
|
1925 |
"version": "8.11.2",
|
1926 |
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
|
@@ -2863,6 +2872,11 @@
|
|
2863 |
"node": ">= 8"
|
2864 |
}
|
2865 |
},
|
|
|
|
|
|
|
|
|
|
|
2866 |
"node_modules/css-color-keywords": {
|
2867 |
"version": "1.0.0",
|
2868 |
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
|
|
|
31 |
"@types/react": "18.2.15",
|
32 |
"@types/react-dom": "18.2.7",
|
33 |
"@types/uuid": "^9.0.2",
|
34 |
+
"@upstash/redis": "^1.25.2",
|
35 |
"autoprefixer": "10.4.14",
|
36 |
"class-variance-authority": "^0.6.1",
|
37 |
"clsx": "^2.0.0",
|
|
|
1922 |
"url": "https://opencollective.com/typescript-eslint"
|
1923 |
}
|
1924 |
},
|
1925 |
+
"node_modules/@upstash/redis": {
|
1926 |
+
"version": "1.25.2",
|
1927 |
+
"resolved": "https://registry.npmjs.org/@upstash/redis/-/redis-1.25.2.tgz",
|
1928 |
+
"integrity": "sha512-iI3jgvmDIbe4Px0PskB8lrn1NXz7ZQyGpW9Ehmonk6SEFqhqssqIB04VmlNh8zZUXwzy6G9DaIa5gIUM6B7DwA==",
|
1929 |
+
"dependencies": {
|
1930 |
+
"crypto-js": "^4.2.0"
|
1931 |
+
}
|
1932 |
+
},
|
1933 |
"node_modules/acorn": {
|
1934 |
"version": "8.11.2",
|
1935 |
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
|
|
|
2872 |
"node": ">= 8"
|
2873 |
}
|
2874 |
},
|
2875 |
+
"node_modules/crypto-js": {
|
2876 |
+
"version": "4.2.0",
|
2877 |
+
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz",
|
2878 |
+
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
|
2879 |
+
},
|
2880 |
"node_modules/css-color-keywords": {
|
2881 |
"version": "1.0.0",
|
2882 |
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
|
package.json
CHANGED
@@ -32,6 +32,7 @@
|
|
32 |
"@types/react": "18.2.15",
|
33 |
"@types/react-dom": "18.2.7",
|
34 |
"@types/uuid": "^9.0.2",
|
|
|
35 |
"autoprefixer": "10.4.14",
|
36 |
"class-variance-authority": "^0.6.1",
|
37 |
"clsx": "^2.0.0",
|
|
|
32 |
"@types/react": "18.2.15",
|
33 |
"@types/react-dom": "18.2.7",
|
34 |
"@types/uuid": "^9.0.2",
|
35 |
+
"@upstash/redis": "^1.25.2",
|
36 |
"autoprefixer": "10.4.14",
|
37 |
"class-variance-authority": "^0.6.1",
|
38 |
"clsx": "^2.0.0",
|
src/app/interface/left-menu/index.tsx
CHANGED
@@ -5,6 +5,7 @@ import { MdVideoLibrary } from "react-icons/md"
|
|
5 |
import { RiHome8Line } from "react-icons/ri"
|
6 |
import { PiRobot } from "react-icons/pi"
|
7 |
import { CgProfile } from "react-icons/cg"
|
|
|
8 |
|
9 |
import { useStore } from "@/app/state/useStore"
|
10 |
import { cn } from "@/lib/utils"
|
@@ -45,6 +46,16 @@ export function LeftMenu() {
|
|
45 |
Channels
|
46 |
</MenuItem>
|
47 |
</Link>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
</div>
|
49 |
<div className={cn(
|
50 |
`flex flex-col w-full`,
|
|
|
5 |
import { RiHome8Line } from "react-icons/ri"
|
6 |
import { PiRobot } from "react-icons/pi"
|
7 |
import { CgProfile } from "react-icons/cg"
|
8 |
+
import { HiOutlineMusicNote } from "react-icons/hi"
|
9 |
|
10 |
import { useStore } from "@/app/state/useStore"
|
11 |
import { cn } from "@/lib/utils"
|
|
|
46 |
Channels
|
47 |
</MenuItem>
|
48 |
</Link>
|
49 |
+
{/*
|
50 |
+
<Link href="/music">
|
51 |
+
<MenuItem
|
52 |
+
icon={<HiOutlineMusicNote className="h-5 w-5" />}
|
53 |
+
selected={view === "public_music_videos"}
|
54 |
+
>
|
55 |
+
Music
|
56 |
+
</MenuItem>
|
57 |
+
</Link>
|
58 |
+
*/}
|
59 |
</div>
|
60 |
<div className={cn(
|
61 |
`flex flex-col w-full`,
|
src/app/music/index.tsx
ADDED
File without changes
|
src/app/views/public-music-videos-view/index.tsx
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"use client"
|
2 |
+
|
3 |
+
import { useEffect, useTransition } from "react"
|
4 |
+
|
5 |
+
import { useStore } from "@/app/state/useStore"
|
6 |
+
import { cn } from "@/lib/utils"
|
7 |
+
import { VideoInfo } from "@/types"
|
8 |
+
import { getVideos } from "@/app/server/actions/ai-tube-hf/getVideos"
|
9 |
+
import { VideoList } from "@/app/interface/video-list"
|
10 |
+
|
11 |
+
export function PublicMusicVideosView() {
|
12 |
+
const [_isPending, startTransition] = useTransition()
|
13 |
+
const setView = useStore(s => s.setView)
|
14 |
+
const currentTag = useStore(s => s.currentTag)
|
15 |
+
const setPublicVideos = useStore(s => s.setPublicVideos)
|
16 |
+
const setPublicVideo = useStore(s => s.setPublicVideo)
|
17 |
+
const publicVideos = useStore(s => s.publicVideos)
|
18 |
+
|
19 |
+
useEffect(() => {
|
20 |
+
startTransition(async () => {
|
21 |
+
const videos = await getVideos({
|
22 |
+
sortBy: "date",
|
23 |
+
mandatoryTags: currentTag ? [currentTag] : [],
|
24 |
+
maxVideos: 25
|
25 |
+
})
|
26 |
+
|
27 |
+
setPublicVideos(videos)
|
28 |
+
})
|
29 |
+
}, [currentTag])
|
30 |
+
|
31 |
+
const handleSelect = (video: VideoInfo) => {
|
32 |
+
setView("public_video")
|
33 |
+
setPublicVideo(video)
|
34 |
+
}
|
35 |
+
|
36 |
+
return (
|
37 |
+
<div className={cn(
|
38 |
+
`sm:pr-4`
|
39 |
+
)}>
|
40 |
+
<VideoList
|
41 |
+
videos={publicVideos}
|
42 |
+
onSelect={handleSelect}
|
43 |
+
/>
|
44 |
+
</div>
|
45 |
+
)
|
46 |
+
}
|
src/app/views/public-video-view/index.tsx
CHANGED
@@ -21,7 +21,6 @@ const DefaultAvatar = dynamic(() => import("../../interface/default-avatar"), {
|
|
21 |
loading: () => null,
|
22 |
})
|
23 |
|
24 |
-
|
25 |
export function PublicVideoView() {
|
26 |
const video = useStore(s => s.publicVideo)
|
27 |
|
|
|
21 |
loading: () => null,
|
22 |
})
|
23 |
|
|
|
24 |
export function PublicVideoView() {
|
25 |
const video = useStore(s => s.publicVideo)
|
26 |
|
src/types.ts
CHANGED
@@ -431,6 +431,7 @@ export type InterfaceView =
|
|
431 |
| "public_channels"
|
432 |
| "public_channel" // public view of a channel
|
433 |
| "public_video" // public view of a video
|
|
|
434 |
| "not_found"
|
435 |
|
436 |
export type Settings = {
|
|
|
431 |
| "public_channels"
|
432 |
| "public_channel" // public view of a channel
|
433 |
| "public_video" // public view of a video
|
434 |
+
| "public_music_videos" // public music videos - it's a special category, because music is *cool*
|
435 |
| "not_found"
|
436 |
|
437 |
export type Settings = {
|