radio api
This commit is contained in:
parent
72706c2b6a
commit
802c364525
@ -4,5 +4,5 @@ pkgs.python3Packages.buildPythonApplication {
|
||||
pname = "radio";
|
||||
src = self;
|
||||
version = "0.1";
|
||||
propagatedBuildInputs = with pkgs.python3Packages; [ pip ffmpeg-python ];
|
||||
propagatedBuildInputs = with pkgs.python3Packages; [ pip ffmpeg-python flask ];
|
||||
}
|
@ -64,7 +64,7 @@ class Downloader(Thread):
|
||||
if self.isAlive():
|
||||
os.killpg(os.getpgid(self.popen.pid), signal.SIGTERM)
|
||||
self.popen.stdout.close()
|
||||
self.popen.wait()
|
||||
# self.popen.wait()
|
||||
self.exit = True
|
||||
|
||||
# checks to see if the current download has finished
|
||||
|
22
nullsrc.py
Normal file
22
nullsrc.py
Normal file
@ -0,0 +1,22 @@
|
||||
import ffmpeg
|
||||
from logger import logger
|
||||
|
||||
# A null audio source
|
||||
|
||||
class NullSrc(object):
|
||||
|
||||
def __init__(self):
|
||||
self.process = ( ffmpeg
|
||||
.input('anullsrc', format='lavfi')
|
||||
.output('pipe:', format='mp3')
|
||||
.run_async(pipe_stdout=True, pipe_stderr=True)
|
||||
)
|
||||
logger.add(self.process.stderr, "nullsrc.log")
|
||||
|
||||
def stop(self):
|
||||
self.process.stdout.close()
|
||||
self.process.stderr.close()
|
||||
# self.process.wait()
|
||||
|
||||
def getStream(self):
|
||||
return self.process.stdout
|
113
radio.py
113
radio.py
@ -1,29 +1,102 @@
|
||||
import downloader
|
||||
import uploader
|
||||
import transcoder
|
||||
import nullsrc
|
||||
from time import sleep
|
||||
from flask import Flask, request
|
||||
from queue import Queue
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
class Radio(object):
|
||||
def __init__(self):
|
||||
self.downloader = None
|
||||
self.transcoder = None
|
||||
self.uploader = uploader.Uploader()
|
||||
self.playingUrl = None
|
||||
self.nullsrc = False
|
||||
self.queue = Queue()
|
||||
|
||||
# plays the next song in the queue
|
||||
def play(self):
|
||||
self.stopPlaying()
|
||||
self.nullsrc = False
|
||||
self.playingUrl = self.queue.get()
|
||||
self.downloader = downloader.Downloader(self.playingUrl, self.downloadFinished)
|
||||
self.transcoder = transcoder.Transcoder(self.downloader)
|
||||
self.uploader.setUpstream(self.transcoder)
|
||||
|
||||
def playNullSrc(self):
|
||||
self.stopPlaying()
|
||||
self.nullsrc = True
|
||||
self.playingUrl = None
|
||||
self.downloader = nullsrc.NullSrc()
|
||||
self.transcoder = transcoder.Transcoder(self.downloader)
|
||||
self.uploader.setUpstream(self.transcoder)
|
||||
|
||||
def isPlaying(self):
|
||||
return not self.playingUrl is None
|
||||
|
||||
# blocks the caller until the uploader and trancoder recieve no more data
|
||||
# if this is a livestream, the end might never come!
|
||||
def blockUntilDonePlaying(self):
|
||||
if not self.nullsrc:
|
||||
self.transcoder.listener.blockUntilEmpty()
|
||||
self.uploader.listener.blockUntilEmpty()
|
||||
|
||||
# add to queue or play right now if queue is empty
|
||||
def addToQueue(self,url):
|
||||
self.queue.put(url)
|
||||
|
||||
def playIfSongAvailable(self):
|
||||
if not self.isPlaying():
|
||||
if self.queue.empty():
|
||||
self.playNullSrc()
|
||||
else:
|
||||
self.play()
|
||||
|
||||
# stops playing immediately and cleans up
|
||||
def stopPlaying(self):
|
||||
if not self.downloader is None:
|
||||
self.downloader.stop()
|
||||
if not self.transcoder is None:
|
||||
self.transcoder.stop()
|
||||
self.playingUrl = None
|
||||
|
||||
# downloader callback function, called when the downloader is finished
|
||||
# but may still have bytes left that need to be read and played
|
||||
def downloadFinished(self):
|
||||
self.blockUntilDonePlaying()
|
||||
self.stopPlaying()
|
||||
self.playIfSongAvailable()
|
||||
|
||||
r = Radio()
|
||||
|
||||
@app.route('/play', methods=['POST'])
|
||||
def queueNext():
|
||||
next = request.form['url']
|
||||
r.addToQueue(next)
|
||||
r.playIfSongAvailable()
|
||||
return "Added"
|
||||
|
||||
@app.route('/skip', methods=['POST'])
|
||||
def skipCurrent():
|
||||
r.stopPlaying()
|
||||
r.playIfSongAvailable()
|
||||
return "Skipped"
|
||||
|
||||
@app.route('/current', methods=['GET'])
|
||||
def current():
|
||||
return r.playingUrl or 'nothing'
|
||||
|
||||
@app.route('/queue', methods=['GET'])
|
||||
def queue():
|
||||
return str(list(r.queue.queue))
|
||||
|
||||
def run():
|
||||
def cb():
|
||||
global d
|
||||
global t
|
||||
global u
|
||||
print("----------------FINISHED-----------")
|
||||
t.listener.blockUntilEmpty()
|
||||
u.listener.blockUntilEmpty()
|
||||
d.stop()
|
||||
t.stop()
|
||||
d = downloader.Downloader('https://www.youtube.com/watch?v=BQQ3qZ9FC70', cb)
|
||||
t = transcoder.Transcoder(d)
|
||||
u.setUpstream(t)
|
||||
|
||||
u = uploader.Uploader()
|
||||
d = downloader.Downloader('https://www.youtube.com/watch?v=kgBcg4uBd9Q', cb)
|
||||
t = transcoder.Transcoder(d)
|
||||
u.setUpstream(t)
|
||||
|
||||
while True:
|
||||
sleep(1)
|
||||
r.addToQueue('https://www.youtube.com/watch?v=BaW_jenozKc')
|
||||
r.playIfSongAvailable()
|
||||
app.run(host="0.0.0.0")
|
||||
|
||||
if __name__ == "__main__":
|
||||
run()
|
23
setup.py
23
setup.py
@ -1,12 +1,21 @@
|
||||
from setuptools import setup
|
||||
|
||||
requires = ["pip","ffmpeg-python"]
|
||||
requires = ["pip","ffmpeg-python","flask"]
|
||||
|
||||
setup(
|
||||
name='radio',
|
||||
version='0.1',
|
||||
py_modules=['radio','downloader','uploader','logger','util','stream_listener','transcoder'],
|
||||
entry_points={
|
||||
'console_scripts': ['radio = radio:run']
|
||||
},
|
||||
name='radio',
|
||||
version='0.1',
|
||||
py_modules=[
|
||||
'radio',
|
||||
'downloader',
|
||||
'uploader',
|
||||
'logger',
|
||||
'util',
|
||||
'stream_listener',
|
||||
'transcoder',
|
||||
'nullsrc'
|
||||
],
|
||||
entry_points={
|
||||
'console_scripts': ['radio = radio:run']
|
||||
},
|
||||
)
|
@ -20,7 +20,7 @@ class Transcoder(object):
|
||||
self.process.stdin.close()
|
||||
self.process.stdout.close()
|
||||
self.process.stderr.close()
|
||||
self.process.wait()
|
||||
# self.process.wait()
|
||||
|
||||
def getStream(self):
|
||||
return self.process.stdout
|
||||
|
Loading…
x
Reference in New Issue
Block a user