use external mpv bindings, new ox version, new tornado api
This commit is contained in:
parent
776dcc52f9
commit
3896ee097d
5 changed files with 42 additions and 1886 deletions
1869
cdoseaplay/mpv.py
1869
cdoseaplay/mpv.py
File diff suppressed because it is too large
Load diff
|
@ -22,6 +22,12 @@ def q_binding(*args):
|
||||||
player = None
|
player = None
|
||||||
|
|
||||||
|
|
||||||
|
def get_path(path):
|
||||||
|
if isinstance(path, bytes):
|
||||||
|
path = path.decode()
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global player
|
global player
|
||||||
playlist = os.path.expanduser('~/Videos/cdosea.m3u')
|
playlist = os.path.expanduser('~/Videos/cdosea.m3u')
|
||||||
|
@ -60,6 +66,9 @@ def main():
|
||||||
|
|
||||||
pause_next = False
|
pause_next = False
|
||||||
play_lights = True
|
play_lights = True
|
||||||
|
path = ''
|
||||||
|
if player.path:
|
||||||
|
path = get_path(player.path)
|
||||||
while True:
|
while True:
|
||||||
if not player:
|
if not player:
|
||||||
break
|
break
|
||||||
|
@ -68,12 +77,12 @@ def main():
|
||||||
player.pause = True
|
player.pause = True
|
||||||
pause_next = False
|
pause_next = False
|
||||||
play_lights = False
|
play_lights = False
|
||||||
elif player.path and player.path.decode().endswith('black.mp4'):
|
elif player.path and get_path(player.path).endswith('black.mp4'):
|
||||||
pause_next = True
|
pause_next = True
|
||||||
play_lights = False
|
play_lights = False
|
||||||
|
|
||||||
if play_lights and config.lights and player.path:
|
if play_lights and config.lights and player.path:
|
||||||
trigger_lights(player.path.decode())
|
trigger_lights(get_path(player.path))
|
||||||
|
|
||||||
play_lights = True
|
play_lights = True
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -5,6 +5,7 @@ import logging
|
||||||
import mimetypes
|
import mimetypes
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import asyncio
|
||||||
|
|
||||||
from tornado.httpserver import HTTPServer
|
from tornado.httpserver import HTTPServer
|
||||||
from tornado import gen
|
from tornado import gen
|
||||||
|
@ -48,7 +49,9 @@ class Subtitles():
|
||||||
self.path = None
|
self.path = None
|
||||||
self.next_path = None
|
self.next_path = None
|
||||||
if self.player.path:
|
if self.player.path:
|
||||||
path = self.player.path.decode()
|
path = self.player.path
|
||||||
|
if isinstance(path, bytes):
|
||||||
|
path = path.decode()
|
||||||
self.path = path
|
self.path = path
|
||||||
self.update_next()
|
self.update_next()
|
||||||
self.load_subtitles()
|
self.load_subtitles()
|
||||||
|
@ -58,12 +61,17 @@ class Subtitles():
|
||||||
data['subtitles'][os.path.basename(self.next_path)] = self.next
|
data['subtitles'][os.path.basename(self.next_path)] = self.next
|
||||||
self.trigger(data)
|
self.trigger(data)
|
||||||
|
|
||||||
def update(self, pos):
|
def update(self, *args):
|
||||||
|
pos = args[0]
|
||||||
|
if pos == 'time-pos' and len(args) > 1:
|
||||||
|
pos = args[1]
|
||||||
if pos is None:
|
if pos is None:
|
||||||
return
|
return
|
||||||
if self.player and self.playlist and self.player.path:
|
if self.player and self.playlist and self.player.path:
|
||||||
self.position = pos
|
self.position = pos
|
||||||
path = self.player.path.decode()
|
path = self.player.path
|
||||||
|
if isinstance(path, bytes):
|
||||||
|
path = path.decode()
|
||||||
trigger_path = path != self.path
|
trigger_path = path != self.path
|
||||||
self.path = path
|
self.path = path
|
||||||
self.update_next()
|
self.update_next()
|
||||||
|
@ -115,8 +123,9 @@ class Subtitles():
|
||||||
|
|
||||||
class Socket(WebSocketHandler):
|
class Socket(WebSocketHandler):
|
||||||
|
|
||||||
def initialize(self, sub):
|
def initialize(self, sub, main):
|
||||||
self.sub = sub
|
self.sub = sub
|
||||||
|
self.main = main
|
||||||
|
|
||||||
def check_origin(self, origin):
|
def check_origin(self, origin):
|
||||||
# bypass same origin check
|
# bypass same origin check
|
||||||
|
@ -143,8 +152,7 @@ class Socket(WebSocketHandler):
|
||||||
except:
|
except:
|
||||||
logger.debug('failed to serialize data %s', data)
|
logger.debug('failed to serialize data %s', data)
|
||||||
return
|
return
|
||||||
main = IOLoop.instance()
|
self.main.add_callback(lambda: self.write_message(message))
|
||||||
main.add_callback(lambda: self.write_message(message))
|
|
||||||
|
|
||||||
|
|
||||||
class StaticFileHandler(RequestHandler):
|
class StaticFileHandler(RequestHandler):
|
||||||
|
@ -155,7 +163,6 @@ class StaticFileHandler(RequestHandler):
|
||||||
def head(self):
|
def head(self):
|
||||||
self.get(include_body=False)
|
self.get(include_body=False)
|
||||||
|
|
||||||
@tornado.web.asynchronous
|
|
||||||
@gen.coroutine
|
@gen.coroutine
|
||||||
def get(self, include_body=True):
|
def get(self, include_body=True):
|
||||||
|
|
||||||
|
@ -185,7 +192,7 @@ class StaticFileHandler(RequestHandler):
|
||||||
while p < length:
|
while p < length:
|
||||||
chunk = max(chunk_size, length-p)
|
chunk = max(chunk_size, length-p)
|
||||||
self.write(fd.read(chunk))
|
self.write(fd.read(chunk))
|
||||||
yield gen.Task(self.flush, include_footers=False)
|
self.flush()
|
||||||
p += chunk
|
p += chunk
|
||||||
else:
|
else:
|
||||||
self.set_header('Content-Length', str(size))
|
self.set_header('Content-Length', str(size))
|
||||||
|
@ -195,7 +202,6 @@ class StaticFileHandler(RequestHandler):
|
||||||
while p < length:
|
while p < length:
|
||||||
chunk = max(chunk_size, length-p)
|
chunk = max(chunk_size, length-p)
|
||||||
self.write(fd.read(chunk))
|
self.write(fd.read(chunk))
|
||||||
yield gen.Task(self.flush, include_footers=False)
|
|
||||||
self.flush()
|
self.flush()
|
||||||
p += chunk
|
p += chunk
|
||||||
self.finish()
|
self.finish()
|
||||||
|
@ -210,6 +216,7 @@ class NotFoundHandler(RequestHandler):
|
||||||
|
|
||||||
class SubtitleServer(Thread):
|
class SubtitleServer(Thread):
|
||||||
sub = None
|
sub = None
|
||||||
|
main = None
|
||||||
|
|
||||||
def __init__(self, player, playlist):
|
def __init__(self, player, playlist):
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
|
@ -219,9 +226,14 @@ class SubtitleServer(Thread):
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
self.main = asyncio.new_event_loop()
|
||||||
|
asyncio.set_event_loop(self.main)
|
||||||
main(self.player, self.playlist, self)
|
main(self.player, self.playlist, self)
|
||||||
|
|
||||||
def join(self):
|
def join(self):
|
||||||
|
if self.main:
|
||||||
|
self.main.close()
|
||||||
|
self.main.stop()
|
||||||
IOLoop.instance().stop()
|
IOLoop.instance().stop()
|
||||||
return Thread.join(self)
|
return Thread.join(self)
|
||||||
|
|
||||||
|
@ -239,9 +251,10 @@ def main(player, playlist, parent=None):
|
||||||
'debug': DEBUG,
|
'debug': DEBUG,
|
||||||
'gzip': False
|
'gzip': False
|
||||||
}
|
}
|
||||||
|
main = IOLoop.instance()
|
||||||
handlers = [
|
handlers = [
|
||||||
(r'/favicon.ico', NotFoundHandler),
|
(r'/favicon.ico', NotFoundHandler),
|
||||||
(r'/ws/', Socket, dict(sub=sub)),
|
(r'/ws/', Socket, dict(sub=sub, main=main)),
|
||||||
(r'/.*', StaticFileHandler, dict(root=STATIC_ROOT))
|
(r'/.*', StaticFileHandler, dict(root=STATIC_ROOT))
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -251,7 +264,6 @@ def main(player, playlist, parent=None):
|
||||||
http_server = HTTPServer(Application(handlers, **options))
|
http_server = HTTPServer(Application(handlers, **options))
|
||||||
if parent:
|
if parent:
|
||||||
parent.server = http_server
|
parent.server = http_server
|
||||||
main = IOLoop.instance()
|
|
||||||
|
|
||||||
def shutdown():
|
def shutdown():
|
||||||
http_server.stop()
|
http_server.stop()
|
||||||
|
|
|
@ -9,7 +9,7 @@ import subprocess
|
||||||
|
|
||||||
import ox
|
import ox
|
||||||
|
|
||||||
from . import mpv
|
import mpv
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -51,7 +51,10 @@ def update_playlist(playlist, prefix, position=None, shift=True):
|
||||||
|
|
||||||
for i in range(10):
|
for i in range(10):
|
||||||
for letter in string.ascii_uppercase:
|
for letter in string.ascii_uppercase:
|
||||||
|
if len(videos[letter]) > i:
|
||||||
files.append(videos[letter][i])
|
files.append(videos[letter][i])
|
||||||
|
else:
|
||||||
|
print("warning some video files are missing %s%s%02d.mp4" % prefix, letter.lower(), i)
|
||||||
|
|
||||||
if not shift:
|
if not shift:
|
||||||
black = os.path.normpath(os.path.join(prefix, '..', 'black.mp4'))
|
black = os.path.normpath(os.path.join(prefix, '..', 'black.mp4'))
|
||||||
|
|
5
setup.py
5
setup.py
|
@ -3,7 +3,7 @@ from setuptools import setup, find_packages
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="cdoseaplay",
|
name="cdoseaplay",
|
||||||
version="1",
|
version="2",
|
||||||
description="play cdosea.org",
|
description="play cdosea.org",
|
||||||
author="j",
|
author="j",
|
||||||
author_email="j@mailb.org",
|
author_email="j@mailb.org",
|
||||||
|
@ -15,11 +15,12 @@ setup(
|
||||||
packages=find_packages(exclude=['tests', 'tests.*']),
|
packages=find_packages(exclude=['tests', 'tests.*']),
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'ox >= 2.1.541,<3',
|
'ox >= 3',
|
||||||
'requests >= 1.1.0',
|
'requests >= 1.1.0',
|
||||||
'tornado',
|
'tornado',
|
||||||
'mpmath',
|
'mpmath',
|
||||||
'lanbox',
|
'lanbox',
|
||||||
|
'mpv',
|
||||||
],
|
],
|
||||||
keywords=[],
|
keywords=[],
|
||||||
classifiers=[
|
classifiers=[
|
||||||
|
|
Loading…
Reference in a new issue