Lee Min Waan commited on
Commit
eedbd5e
·
1 Parent(s): bcb459b

dasasdasd

Browse files
Files changed (7) hide show
  1. .gitattributes +35 -35
  2. .gitignore +1 -0
  3. Dockerfile +13 -0
  4. README.md +10 -10
  5. index.ts +159 -0
  6. package-lock.json +0 -0
  7. package.json +25 -0
.gitattributes CHANGED
@@ -1,35 +1,35 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ /node_modules
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:latest
2
+
3
+ WORKDIR /usr/src/app
4
+
5
+ COPY package*.json ./
6
+
7
+ RUN npm install
8
+
9
+ COPY . .
10
+
11
+ EXPOSE 3000
12
+
13
+ CMD [ "node", "index.js" ]
README.md CHANGED
@@ -1,10 +1,10 @@
1
- ---
2
- title: YoutubeStreamAPI
3
- emoji: 🐠
4
- colorFrom: indigo
5
- colorTo: blue
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ ---
2
+ title: YoutubeStreamAPI
3
+ emoji: 🐠
4
+ colorFrom: indigo
5
+ colorTo: blue
6
+ sdk: docker
7
+ pinned: false
8
+ ---
9
+
10
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.ts ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import YTMusic from "ytmusic-api"
2
+ import ystream from 'yt-stream'
3
+ import fs from 'fs'
4
+ import process from 'process'
5
+ import express, { Request, Response } from 'express'
6
+
7
+ const ytmusic = new YTMusic()
8
+ ytmusic.initialize()
9
+ const app = express()
10
+ const PORT = process.env.PORT || 3000
11
+
12
+ interface SongType {
13
+ type: "SONG";
14
+ name: string;
15
+ videoId: string;
16
+ artist: {
17
+ artistId: string | null;
18
+ name: string;
19
+ };
20
+ album: {
21
+ name: string;
22
+ albumId: string;
23
+ } | null;
24
+ duration: number | null;
25
+ thumbnails: {
26
+ url: string;
27
+ width: number;
28
+ height: number;
29
+ }[];
30
+ }
31
+
32
+ interface VideoType {
33
+ type: "VIDEO";
34
+ name: string;
35
+ videoId: string;
36
+ artist: {
37
+ artistId: string | null;
38
+ name: string;
39
+ };
40
+ duration: number | null;
41
+ thumbnails: {
42
+ url: string;
43
+ width: number;
44
+ height: number;
45
+ }[];
46
+ }
47
+
48
+ type MusicType = SongType
49
+
50
+ function bestMatch(query: MusicType[], targetName: string, duration?: number) {
51
+ // Helper function to calculate a match score
52
+ const calculateScore = (song: MusicType) => {
53
+ let score = 0;
54
+ // Prioritize exact name match
55
+ if (song.name === targetName) score += 50;
56
+ else if (song.name.includes(targetName)) score += 20;
57
+
58
+ // Bonus for artist or album relevance
59
+ if (song.artist.name === "Phong Max") score += 20;
60
+ if(song.artist.name.includes("Phong Max")) score += 10;
61
+ if(song.album) {
62
+ score += 5
63
+ if(song.album.name.includes(targetName)) score += 10;
64
+ }
65
+
66
+ if(duration) {
67
+ // Duration proximity (ideal around 200-250 seconds)
68
+ const idealDuration = 211;
69
+
70
+ if(song.duration === null) return 0
71
+ score -= Math.abs(song.duration - idealDuration) / 10; // Penalize for duration deviation
72
+ }
73
+
74
+ return score;
75
+ };
76
+
77
+ // Rank songs by score
78
+ query.sort((a, b) => calculateScore(b) - calculateScore(a));
79
+
80
+ // Return the best match
81
+ return query[0];
82
+ }
83
+
84
+
85
+ // Middleware to parse JSON bodies
86
+ app.use(express.json())
87
+
88
+ app.post('/search-stream', async (req: Request, res: Response) => {
89
+ try {
90
+ // Extract query from request body
91
+ const { query } = req.body
92
+
93
+ if (!query) {
94
+ return res.status(400).json({ error: 'Query is required' })
95
+ }
96
+
97
+ // Search for songs
98
+ let songs = await ytmusic.searchSongs(query)
99
+
100
+ console.log(songs)
101
+
102
+ let musics: MusicType[] = songs.filter((song) => {
103
+ return song.duration !== null && song.name.toLowerCase().includes(query.toLowerCase())
104
+ })
105
+
106
+ // sort song by their duration
107
+ musics.sort((a, b) => {
108
+ if (!a.duration || !b.duration) {
109
+ return 0
110
+ }
111
+
112
+ return b.duration - a.duration
113
+ })
114
+
115
+ console.log(musics)
116
+
117
+ const firstSong = bestMatch(musics, query)
118
+
119
+ if (!firstSong) {
120
+ return res.status(404).json({ error: 'No songs found' })
121
+ }
122
+
123
+ if (firstSong.type !== "SONG" && firstSong.type !== "VIDEO") {
124
+ return res.status(400).json({ error: 'Invalid song type' })
125
+ }
126
+
127
+ // console.log(firstSong)
128
+
129
+ // Get stream URL
130
+ const stream = await ystream.stream(`https://www.youtube.com/watch?v=` + firstSong.videoId, {
131
+ quality: 'high',
132
+ type: 'audio',
133
+ highWaterMark: 1048576 * 32,
134
+ download: true
135
+ })
136
+
137
+ // Return stream URL and song details
138
+ res.json({
139
+ streamUrl: stream.url,
140
+ songDetails: firstSong
141
+ })
142
+ } catch (error: any) {
143
+ if (error.response) {
144
+ console.log('Error status:', error.response.status)
145
+ // console.log('Error message:', error.response)
146
+ } else if (error.request) {
147
+ console.log('Error:', error.request)
148
+ } else {
149
+ console.log('Error:', error.message)
150
+ }
151
+
152
+ res.status(500).json({ error: 'Internal server error' })
153
+ }
154
+ })
155
+
156
+ // Start the server
157
+ app.listen(PORT, () => {
158
+ console.log(`Server running on port ${PORT}`)
159
+ })
package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
package.json ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "youtubescrapper",
3
+ "version": "1.0.0",
4
+ "main": "index.ts",
5
+ "scripts": {
6
+ "test": "echo \"Error: no test specified\" && exit 1",
7
+ "start": "ts-node index.ts"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "ISC",
12
+ "description": "",
13
+ "devDependencies": {
14
+ "@types/express": "^4.17.21",
15
+ "ts-node": "^10.9.2",
16
+ "typescript": "^5.7.2"
17
+ },
18
+ "dependencies": {
19
+ "@types/node": "^22.10.2",
20
+ "cors": "^2.8.5",
21
+ "express": "^4.19.2",
22
+ "yt-stream": "^1.7.4",
23
+ "ytmusic-api": "^5.2.2"
24
+ }
25
+ }