nice
This commit is contained in:
parent
713ab9c44a
commit
54e2cd0714
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
venv/
|
venv/
|
||||||
node_modules/
|
node_modules/
|
||||||
|
media/
|
130
main.py
130
main.py
|
@ -2,39 +2,110 @@ from fastapi import FastAPI, HTTPException
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
import yt_dlp
|
import yt_dlp
|
||||||
import vlc
|
import vlc
|
||||||
import threading
|
import os
|
||||||
import time
|
import json
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
# Define a data model for the queue item
|
# Define a data model for the queue item
|
||||||
class VideoLink(BaseModel):
|
class VideoLink(BaseModel):
|
||||||
url: str
|
url: str
|
||||||
|
|
||||||
|
# Create media directory if it doesn't exist
|
||||||
|
MEDIA_DIR = 'media'
|
||||||
|
if not os.path.exists(MEDIA_DIR):
|
||||||
|
os.makedirs(MEDIA_DIR)
|
||||||
|
|
||||||
# Queue to store video URLs
|
# File to store video info dictionaries
|
||||||
video_queue = []
|
INFO_FILE = os.path.join(MEDIA_DIR, 'downloaded_info.json')
|
||||||
current_video = None
|
try:
|
||||||
|
if os.path.exists(INFO_FILE) and os.path.getsize(INFO_FILE) > 0:
|
||||||
|
with open(INFO_FILE, 'r') as f:
|
||||||
|
downloaded_info = json.load(f)
|
||||||
|
else:
|
||||||
|
downloaded_info = {}
|
||||||
|
except (json.JSONDecodeError, IOError) as e:
|
||||||
|
downloaded_info = {}
|
||||||
|
|
||||||
# VLC player instance
|
# VLC player instance
|
||||||
vlc_instance = vlc.Instance()
|
vlc_instance = vlc.Instance('--quiet')
|
||||||
player = vlc_instance.media_player_new()
|
player = vlc_instance.media_player_new()
|
||||||
player.set_fullscreen(True)
|
playlist = []
|
||||||
|
|
||||||
|
# Function to download video or use existing file
|
||||||
|
def get_media_file(url):
|
||||||
|
ydl_opts = {
|
||||||
|
'format': 'best',
|
||||||
|
'quiet': True,
|
||||||
|
'outtmpl': os.path.join(MEDIA_DIR, '%(title)s.%(ext)s'),
|
||||||
|
'overwrites': False,
|
||||||
|
# 'verbose': True
|
||||||
|
}
|
||||||
|
|
||||||
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||||
|
info_dict = ydl.extract_info(url, download=False)
|
||||||
|
video_id = info_dict['id']
|
||||||
|
|
||||||
|
# Check if video ID already exists in downloaded info
|
||||||
|
if video_id in downloaded_info:
|
||||||
|
print(f"\nVideo {video_id} already downloaded\n\n")
|
||||||
|
video_file = downloaded_info[video_id]['filepath']
|
||||||
|
else:
|
||||||
|
print(f"\nDownloading video {video_id}\n\n")
|
||||||
|
video_file = ydl.prepare_filename(info_dict) # Fixed line
|
||||||
|
ydl.download([url])
|
||||||
|
minimal_info_dict = {
|
||||||
|
'id': video_id,
|
||||||
|
'title': info_dict['title'],
|
||||||
|
# 'release_date': info_dict.get('release_date'),
|
||||||
|
'filepath': video_file
|
||||||
|
}
|
||||||
|
downloaded_info[video_id] = minimal_info_dict
|
||||||
|
with open(INFO_FILE, 'w') as f:
|
||||||
|
json.dump(downloaded_info, f, indent=4)
|
||||||
|
return video_file
|
||||||
|
|
||||||
# Add video URL to the queue
|
# Function to add video to VLC playlist
|
||||||
|
def add_to_playlist(url):
|
||||||
|
video_file = get_media_file(url)
|
||||||
|
media = vlc_instance.media_new_path(video_file)
|
||||||
|
playlist.append(media)
|
||||||
|
|
||||||
|
# Function to play the next video in the playlist
|
||||||
|
def play_next():
|
||||||
|
if playlist:
|
||||||
|
media = playlist.pop(0)
|
||||||
|
player.set_media(media)
|
||||||
|
player.play()
|
||||||
|
|
||||||
|
# Add video URL to the playlist
|
||||||
@app.post("/add")
|
@app.post("/add")
|
||||||
def add_video(video_link: VideoLink):
|
def add_video(video_link: VideoLink):
|
||||||
video_queue.append(video_link.url)
|
add_to_playlist(video_link.url)
|
||||||
return {"message": "Video added to the queue"}
|
if player.get_state() not in [vlc.State.Playing, vlc.State.Paused]:
|
||||||
|
play_next()
|
||||||
|
return {"message": "Video added to the playlist"}
|
||||||
|
|
||||||
|
# Remove video URL from the playlist
|
||||||
|
@app.delete("/remove/{index}")
|
||||||
|
def remove_video(index: int):
|
||||||
|
if 0 <= index < len(playlist):
|
||||||
|
removed_video = playlist.pop(index)
|
||||||
|
return {"message": "Video removed from the playlist", "url": removed_video.get_mrl()}
|
||||||
|
else:
|
||||||
|
raise HTTPException(status_code=404, detail="Index out of range")
|
||||||
|
|
||||||
# Get current queue
|
# Skip current video and play next
|
||||||
@app.get("/queue")
|
@app.post("/skip")
|
||||||
def get_queue():
|
def skip_video():
|
||||||
return {"queue": video_queue}
|
player.stop()
|
||||||
|
play_next()
|
||||||
|
return {"message": "Skipped to the next video"}
|
||||||
|
|
||||||
|
# Get current playlist
|
||||||
|
@app.get("/playlist")
|
||||||
|
def get_playlist():
|
||||||
|
return {"playlist": [media.get_mrl() for media in playlist]}
|
||||||
|
|
||||||
# Control playback: play, pause, stop
|
# Control playback: play, pause, stop
|
||||||
@app.post("/control/{action}")
|
@app.post("/control/{action}")
|
||||||
|
@ -47,11 +118,6 @@ def control_playback(action: str):
|
||||||
player.stop()
|
player.stop()
|
||||||
elif action == "mute":
|
elif action == "mute":
|
||||||
player.audio_toggle_mute()
|
player.audio_toggle_mute()
|
||||||
elif action == "fullscreen":
|
|
||||||
if player.get_fullscreen():
|
|
||||||
player.set_fullscreen(False)
|
|
||||||
else:
|
|
||||||
player.set_fullscreen(True)
|
|
||||||
else:
|
else:
|
||||||
raise HTTPException(status_code=400, detail="Invalid action")
|
raise HTTPException(status_code=400, detail="Invalid action")
|
||||||
return {"message": f"Player action {action} executed"}
|
return {"message": f"Player action {action} executed"}
|
||||||
|
@ -62,29 +128,7 @@ def seek(seconds: int):
|
||||||
player.set_time(seconds * 1000)
|
player.set_time(seconds * 1000)
|
||||||
return {"message": f"Seeked to {seconds} seconds"}
|
return {"message": f"Seeked to {seconds} seconds"}
|
||||||
|
|
||||||
|
|
||||||
# Function to play videos from the queue
|
|
||||||
def play_videos():
|
|
||||||
global current_video
|
|
||||||
while True:
|
|
||||||
if video_queue and player.get_state() not in [vlc.State.Playing, vlc.State.Paused]:
|
|
||||||
current_video = video_queue.pop(0)
|
|
||||||
ydl_opts = {'format': 'best', 'quiet': True}
|
|
||||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
||||||
info_dict = ydl.extract_info(current_video, download=False)
|
|
||||||
video_url = info_dict.get("url", None)
|
|
||||||
media = vlc_instance.media_new(video_url)
|
|
||||||
player.set_media(media)
|
|
||||||
player.play()
|
|
||||||
time.sleep(1) # Give some time for the player to start
|
|
||||||
time.sleep(1)
|
|
||||||
|
|
||||||
|
|
||||||
# Start the video playing thread
|
|
||||||
video_thread = threading.Thread(target=play_videos, daemon=True)
|
|
||||||
video_thread.start()
|
|
||||||
|
|
||||||
# Run FastAPI
|
# Run FastAPI
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import uvicorn
|
import uvicorn
|
||||||
uvicorn.run(app, host="127.0.0.1", port=1337)
|
uvicorn.run(app, host="0.0.0.0", port=1337)
|
||||||
|
|
14
readme.md
14
readme.md
|
@ -35,9 +35,9 @@ Your SpaceInvaderz API should now be running on `http://0.0.0.0:1337`.
|
||||||
|
|
||||||
## 🌌 API Endpoints
|
## 🌌 API Endpoints
|
||||||
|
|
||||||
### 1. Add Video to Queue
|
### 1. Add Video to playlist
|
||||||
|
|
||||||
**Description:** Adds a video to the playback queue.
|
**Description:** Adds a video to the playback playlist.
|
||||||
|
|
||||||
- **URL:** `/add`
|
- **URL:** `/add`
|
||||||
- **Method:** `POST`
|
- **Method:** `POST`
|
||||||
|
@ -59,21 +59,21 @@ Invoke-RestMethod -Uri http://localhost:1337/add -Method Post -Body (@{url = $vi
|
||||||
curl -X POST "http://localhost:1337/add" -H "Content-Type: application/json" -d "{\"url\":\"YOUR_VIDEO_URL\"}"
|
curl -X POST "http://localhost:1337/add" -H "Content-Type: application/json" -d "{\"url\":\"YOUR_VIDEO_URL\"}"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Get Current Queue
|
### 2. Get Current playlist
|
||||||
|
|
||||||
**Description:** Retrieves the current queue of videos.
|
**Description:** Retrieves the current playlist of videos.
|
||||||
|
|
||||||
- **URL:** `/queue`
|
- **URL:** `/playlist`
|
||||||
- **Method:** `GET`
|
- **Method:** `GET`
|
||||||
|
|
||||||
#### PowerShell:
|
#### PowerShell:
|
||||||
```powershell
|
```powershell
|
||||||
Invoke-RestMethod -Uri http://localhost:1337/queue -Method Get
|
Invoke-RestMethod -Uri http://localhost:1337/playlist -Method Get
|
||||||
```
|
```
|
||||||
|
|
||||||
#### cURL:
|
#### cURL:
|
||||||
```sh
|
```sh
|
||||||
curl -X GET "http://localhost:1337/queue"
|
curl -X GET "http://localhost:1337/playlist"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Control Playback
|
### 3. Control Playback
|
||||||
|
|
Loading…
Reference in New Issue
Block a user