modified: app.py
modified: templates/quiz.html
This commit is contained in:
50
app.py
50
app.py
@@ -11,7 +11,8 @@ import random
|
|||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.secret_key = os.getenv("SECRET_KEY")
|
app.secret_key = os.getenv("SECRET_KEY")
|
||||||
|
|
||||||
SCOPE = "user-library-read playlist-read-private"
|
# Erweiterte Berechtigungen für Web Playback SDK
|
||||||
|
SCOPE = "user-library-read playlist-read-private streaming user-read-email user-read-private"
|
||||||
|
|
||||||
def get_spotify_client():
|
def get_spotify_client():
|
||||||
return spotipy.Spotify(auth_manager=SpotifyOAuth(
|
return spotipy.Spotify(auth_manager=SpotifyOAuth(
|
||||||
@@ -62,12 +63,53 @@ def quiz(playlist_id):
|
|||||||
sp = get_spotify_client()
|
sp = get_spotify_client()
|
||||||
items = sp.playlist_items(playlist_id, additional_types=["track"])["items"]
|
items = sp.playlist_items(playlist_id, additional_types=["track"])["items"]
|
||||||
|
|
||||||
tracks = [item["track"] for item in items if item["track"]["preview_url"]]
|
tracks = [item["track"] for item in items]
|
||||||
if not tracks:
|
if not tracks:
|
||||||
return "Keine Tracks mit Vorschau verfügbar!"
|
return "Keine Tracks verfügbar!"
|
||||||
|
|
||||||
track = random.choice(tracks)
|
track = random.choice(tracks)
|
||||||
return render_template("quiz.html", track=track)
|
|
||||||
|
# Token aus der Sitzung holen für das Web Playback SDK
|
||||||
|
token_info = session.get('token_info', None)
|
||||||
|
if not token_info:
|
||||||
|
return redirect('/login')
|
||||||
|
|
||||||
|
# Zugriff auf access_token
|
||||||
|
access_token = token_info['access_token']
|
||||||
|
|
||||||
|
return render_template("quiz.html", track=track, access_token=access_token, playlist_id=playlist_id)
|
||||||
|
|
||||||
|
@app.route("/play_track", methods=["POST"])
|
||||||
|
def play_track():
|
||||||
|
device_id = request.args.get('device_id')
|
||||||
|
track_uri = request.args.get('track_uri')
|
||||||
|
|
||||||
|
if not device_id or not track_uri:
|
||||||
|
return {"error": "Missing device_id or track_uri"}, 400
|
||||||
|
|
||||||
|
sp = get_spotify_client()
|
||||||
|
sp.start_playback(device_id=device_id, uris=[track_uri])
|
||||||
|
|
||||||
|
return {"success": True}
|
||||||
|
|
||||||
|
@app.route("/toggle_playback", methods=["POST"])
|
||||||
|
def toggle_playback():
|
||||||
|
data = request.json
|
||||||
|
device_id = data.get('device_id')
|
||||||
|
|
||||||
|
if not device_id:
|
||||||
|
return {"error": "Missing device_id"}, 400
|
||||||
|
|
||||||
|
sp = get_spotify_client()
|
||||||
|
# Aktuellen Playback-Status abrufen
|
||||||
|
current_playback = sp.current_playback()
|
||||||
|
|
||||||
|
if current_playback and current_playback.get('is_playing'):
|
||||||
|
sp.pause_playback(device_id=device_id)
|
||||||
|
else:
|
||||||
|
sp.start_playback(device_id=device_id)
|
||||||
|
|
||||||
|
return {"success": True}
|
||||||
|
|
||||||
@app.route('/logout')
|
@app.route('/logout')
|
||||||
def logout():
|
def logout():
|
||||||
|
|||||||
@@ -1,13 +1,103 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head><title>Musik Quiz</title></head>
|
<head>
|
||||||
|
<title>Musik Quiz</title>
|
||||||
|
<!-- Spotify Web Playback SDK -->
|
||||||
|
<script src="https://sdk.scdn.co/spotify-player.js"></script>
|
||||||
|
<script>
|
||||||
|
window.onSpotifyWebPlaybackSDKReady = () => {
|
||||||
|
const token = '{{ access_token }}';
|
||||||
|
const player = new Spotify.Player({
|
||||||
|
name: 'Musik Quiz Player',
|
||||||
|
getOAuthToken: cb => { cb(token); },
|
||||||
|
volume: 0.5
|
||||||
|
});
|
||||||
|
|
||||||
|
// Error handling
|
||||||
|
player.addListener('initialization_error', ({ message }) => { console.error(message); });
|
||||||
|
player.addListener('authentication_error', ({ message }) => { console.error(message); });
|
||||||
|
player.addListener('account_error', ({ message }) => { console.error(message); });
|
||||||
|
player.addListener('playback_error', ({ message }) => { console.error(message); });
|
||||||
|
|
||||||
|
// Playback status updates
|
||||||
|
player.addListener('player_state_changed', state => {
|
||||||
|
console.log(state);
|
||||||
|
// Hier könntest du UI-Updates basierend auf dem Playback-Status hinzufügen
|
||||||
|
});
|
||||||
|
|
||||||
|
// Ready
|
||||||
|
player.addListener('ready', ({ device_id }) => {
|
||||||
|
console.log('Ready with Device ID', device_id);
|
||||||
|
document.getElementById('device_id').value = device_id;
|
||||||
|
|
||||||
|
// Starte die Wiedergabe, wenn der Player bereit ist
|
||||||
|
fetch('/play_track?device_id=' + device_id + '&track_uri={{ track.uri }}', {
|
||||||
|
method: 'POST'
|
||||||
|
}).then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
}).catch(error => {
|
||||||
|
console.error('Error starting playback:', error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Not Ready
|
||||||
|
player.addListener('not_ready', ({ device_id }) => {
|
||||||
|
console.log('Device ID has gone offline', device_id);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Connect to the player!
|
||||||
|
player.connect();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.controls {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
padding: 10px 15px;
|
||||||
|
margin: 5px;
|
||||||
|
background-color: #1DB954;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.btn:hover {
|
||||||
|
background-color: #1ed760;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h2>Wer ist der Künstler dieses Songs?</h2>
|
<h2>Wer ist der Künstler dieses Songs?</h2>
|
||||||
<audio controls autoplay>
|
|
||||||
<source src="{{ track.preview_url }}" type="audio/mpeg">
|
<!-- Verstecktes Feld für device_id -->
|
||||||
Dein Browser unterstützt keine Audio-Wiedergabe.
|
<input type="hidden" id="device_id" value="">
|
||||||
</audio>
|
|
||||||
|
<!-- Player Controls -->
|
||||||
|
<div class="controls">
|
||||||
|
<button class="btn" onclick="togglePlay()">Play/Pause</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p><strong>Antwort:</strong> {{ track.artists[0].name }} (für Demo-Zwecke)</p>
|
<p><strong>Antwort:</strong> {{ track.artists[0].name }} (für Demo-Zwecke)</p>
|
||||||
<a href="/quiz/{{ track.id }}">Neue Frage</a>
|
<a href="/quiz/{{ playlist_id }}" class="btn">Neue Frage</a>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let isPlaying = true;
|
||||||
|
|
||||||
|
function togglePlay() {
|
||||||
|
fetch('/toggle_playback', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
device_id: document.getElementById('device_id').value
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user