155 lines
5.7 KiB
Python
155 lines
5.7 KiB
Python
from flask import Flask, render_template, jsonify
|
|
from flask_socketio import SocketIO, emit
|
|
from flask_cors import CORS
|
|
import yt_dlp
|
|
import vlc
|
|
import os
|
|
import eyed3
|
|
import time
|
|
|
|
home_directory = os.path.expanduser("~")
|
|
music_directory = os.path.expanduser('~/Music') # Adjust path as necessary
|
|
|
|
#app = Flask(__name__,template_folder=home_directory)
|
|
app = Flask(__name__, template_folder=f"{home_directory}/Code/GR/GR-Jukebox")
|
|
CORS(app, resources={r"/*": {"origins": "*"}})
|
|
socketio = SocketIO(app)
|
|
player = vlc.MediaPlayer()
|
|
music_queue = []
|
|
title_queue = []
|
|
|
|
@socketio.on('connect')
|
|
def handle_connect():
|
|
emit('response', {'message': 'Connected to WebSocket server'})
|
|
|
|
@socketio.on('list_music')
|
|
def handle_list_music():
|
|
music_files = []
|
|
for filename in os.listdir(music_directory):
|
|
if filename.endswith('.mp3'):
|
|
path = os.path.join(music_directory, filename)
|
|
audiofile = eyed3.load(path)
|
|
title = audiofile.tag.title if audiofile.tag else 'Unknown Title'
|
|
music_files.append({'id': filename.split('.')[0], 'title': title})
|
|
print({'music_files':music_files})
|
|
emit('music_list', {'music_files': music_files})
|
|
|
|
@socketio.on('download')
|
|
def handle_download(data):
|
|
url = data['youtube_url']
|
|
if 'youtube.com' in url:
|
|
video_id = url.split('=')[1][:11] # Extract the video ID from the YouTube URL
|
|
elif 'youtu.be' in url:
|
|
video_id = url.split('youtu.be/')[1][:11]
|
|
else:
|
|
#return jsonify({'status': 'error', 'message': 'Invalid YouTube URL'})
|
|
emit('download_status', {'status': 'error', 'message': 'Invalid YouTube URL'})
|
|
output_path = os.path.expanduser(f'{home_directory}/Music/{video_id}.mp3') # Path where the file will be saved
|
|
|
|
if not os.path.exists(output_path):
|
|
print("Downloading...")
|
|
# Configure yt-dlp to download best audio quality
|
|
ydl_opts = {
|
|
'format': 'bestaudio/best',
|
|
'postprocessors': [{
|
|
'key': 'FFmpegExtractAudio',
|
|
'preferredcodec': 'mp3',
|
|
'preferredquality': '192',
|
|
}],
|
|
'noplaylist': True,
|
|
'quiet': True,
|
|
'outtmpl': output_path[:-4] # Use the custom path as the output template
|
|
}
|
|
|
|
# Use yt-dlp to extract information and download the audio file
|
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
info = ydl.extract_info(url, download=True)
|
|
title = info.get('title') # Extract the title from video information
|
|
|
|
# Load the downloaded file using eyed3 and add ID3 tags
|
|
audiofile = eyed3.load(output_path)
|
|
if audiofile.tag is None: # Create an ID3 tag if none exist
|
|
audiofile.tag = eyed3.id3.Tag()
|
|
audiofile.tag.file_info = eyed3.id3.FileInfo(output_path)
|
|
|
|
print(f"Downloaded: {title}")
|
|
audiofile.tag.title = title
|
|
audiofile.tag.save() # Save the metadata
|
|
emit('download_status', {'status': 'success', 'message': 'Song added successfully'})
|
|
|
|
playing_thread = False
|
|
@socketio.on('play')
|
|
def handle_play(data):
|
|
global music_queue
|
|
global title_queue
|
|
global playing_thread
|
|
global player
|
|
music_queue.append(data['songId'])
|
|
title_queue.append(data['songTitle'])
|
|
if not playing_thread:
|
|
while len(music_queue) > 0:
|
|
playing_thread = True
|
|
player = vlc.MediaPlayer(f'{home_directory}/Music/{music_queue[0]}.mp3')
|
|
player.play()
|
|
print(f"Playing: {title_queue[0]}")
|
|
emit('current', {'title': title_queue[0]})
|
|
emit('queue', [{'id': idx, 'title': title} for idx, title in enumerate(title_queue)])
|
|
# Wait for the audio to start playing and check periodically if it is still playing
|
|
time.sleep(1) # Short initial delay to allow playback to start
|
|
while player.is_playing():
|
|
#print('Playing...')
|
|
time.sleep(0.5) # Check every second if it is still playing
|
|
#emit('time', {'time': player.get_time()})
|
|
#print(player.get_time())
|
|
#print(player.get_length())
|
|
#print((player.get_time()/player.get_length()))
|
|
emit('time', {'time': (player.get_time()/player.get_length())})
|
|
player.stop()
|
|
music_queue.pop(0)
|
|
title_queue.pop(0)
|
|
playing_thread = False
|
|
emit('play_return', {'status': 'success', 'message': 'Playing song'})
|
|
|
|
@socketio.on('get_queue')
|
|
def handle_get_queue():
|
|
emit('queue', [{'id': idx, 'title': title} for idx, title in enumerate(title_queue)])
|
|
|
|
@socketio.on('remove_from_queue')
|
|
def handle_remove_from_queue(data):
|
|
global music_queue
|
|
global title_queue
|
|
global player
|
|
#data = request.json
|
|
song_id = int(data['songId'])
|
|
try:
|
|
#del music_queue[song_id]
|
|
#del title_queue[song_id]
|
|
if song_id == 0:
|
|
player.stop()
|
|
else:
|
|
music_queue.pop(song_id)
|
|
title_queue.pop(song_id)
|
|
#return jsonify({'status': 'success', 'message': 'Song removed successfully'})
|
|
emit('remove_return', {'status': 'success', 'message': 'Song removed successfully'})
|
|
except IndexError:
|
|
#return jsonify({'status': 'error', 'message': 'Invalid song ID'}), 400
|
|
emit('remove_return', {'status': 'error', 'message': 'Invalid song ID'})
|
|
|
|
@socketio.on('current_song')
|
|
def handle_current_song():
|
|
if title_queue:
|
|
emit('current', {'title': title_queue[0]})
|
|
else:
|
|
emit('current', {'title': 'Nothing is playing'})
|
|
|
|
@app.route('/')
|
|
def index():
|
|
return render_template('manage2.html')
|
|
|
|
@app.route('/display')
|
|
def display():
|
|
return render_template('display2.html')
|
|
|
|
if __name__ == '__main__':
|
|
socketio.run(app, host='0.0.0.0', debug=True, port=5000)
|