GR-Jukebox/main2.py
2024-08-06 20:52:02 -04:00

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)