Musik/musik.py

117 lines
2.8 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Music streaming.
"""
import os
import json
import random
import subprocess
from urllib import parse
from flask import Flask, Response, render_template, send_file, url_for, request, abort
import database
FFMPEG_CMD = [
'ffmpeg', '-y',
'-loglevel', 'panic',
'-i', '',
'-b:a', '64k',
'-f', 'opus',
'-'
]
app = Flask(__name__)
database.init_database()
@app.route('/')
def index():
"""Main index page."""
artists = database.get_all_artists()
return render_template('index.html', **locals())
@app.route('/select')
def select():
"""Retrieve information about an artist, album or track."""
artist = request.args.get('artist')
album = request.args.get('album')
discnumber = request.args.get('discnumber')
tracknumber = request.args.get('tracknumber')
if tracknumber:
result = database.get_track(artist, album, discnumber, tracknumber)
if not result:
return ("Valid artist, album, discnumber and tracknumber "
"parameters must be supplied.")
else:
result.pop('filepath')
elif album:
result = database.get_album_tracks(artist, album)
if not result:
return "Valid artist and album parameters must be supplied."
elif artist:
result = database.get_artist_albums(artist)
if not result:
return "Valid artist parameter must be supplied."
else:
return "Invalid query."
return json.dumps(result)
@app.route('/select/random')
def select_random():
"""
Selects a random track.
"""
track = database.get_random_track()
track.pop('filepath')
return json.dumps(track)
@app.route('/stream')
def stream():
"""View for the raw audio file."""
artist = parse.unquote(request.args.get('artist'))
album = parse.unquote(request.args.get('album'))
discnumber = parse.unquote(request.args.get('discnumber'))
tracknumber = parse.unquote(request.args.get('tracknumber'))
track = database.get_track(artist, album, discnumber, tracknumber)
if not track:
return "Track does not exist."
FFMPEG_CMD[5] = track['filepath']
def generate():
with subprocess.Popen(FFMPEG_CMD, stdout=subprocess.PIPE) as proc:
data = proc.stdout.read(1024)
while data:
yield data
data = proc.stdout.read(1024)
return Response(generate(), mimetype="audio/ogg")
@app.route('/coverart')
def coverart():
"""View for the raw audio file."""
artist = parse.unquote(request.args.get('artist'))
album = parse.unquote(request.args.get('album'))
discnumber = parse.unquote(request.args.get('discnumber'))
tracknumber = parse.unquote(request.args.get('tracknumber'))
track = database.get_track(artist, album, discnumber, tracknumber)
if not track:
return "Track does not exist."
cover_path = os.path.join(os.path.dirname(track['filepath']), 'folder.jpg')
if os.path.isfile(cover_path):
return send_file(cover_path)
else:
return "No cover art for this track found."
if __name__ == "__main__":
app.run(host='0.0.0.0', port=5150)