audio: Start adding playlist typefinder code.

This allows gstreamer pipelines to determine when they are getting m3u, pls or
xspf files and distinguish them from text/plain content.
This commit is contained in:
Thomas Adamcik 2013-05-28 22:58:13 +02:00
parent 9fc319fd1d
commit c376ac4183
2 changed files with 54 additions and 1 deletions

View File

@ -11,13 +11,14 @@ import pykka
from mopidy.utils import process
from . import mixers, utils
from . import mixers, playlists, utils
from .constants import PlaybackState
from .listener import AudioListener
logger = logging.getLogger('mopidy.audio')
mixers.register_mixers()
playlists.register_typefinders()
MB = 1 << 20

52
mopidy/audio/playlists.py Normal file
View File

@ -0,0 +1,52 @@
from __future__ import unicode_literals
import pygst
pygst.require('0.10')
import gst
import xml.dom.pulldom
# TODO: make detect_FOO_header reusable in general mopidy code.
# i.e. give it just a "peek" like function.
def detect_m3u_header(typefind):
return typefind.peek(0, 8) == b'#EXTM3U\n'
def detect_pls_header(typefind):
print repr(typefind.peek(0, 11) == b'[playlist]\n')
return typefind.peek(0, 11) == b'[playlist]\n'
def detect_xspf_header(typefind):
# Get more data than the 90 needed for header in case spacing is funny.
data = typefind.peek(0, 150)
# Bail early if the words xml and playlist are not present.
if not data or b'xml' not in data or b'playlist' not in data:
return False
# TODO: handle parser errors.
# Try parsing what we have, bailing on first element.
for event, node in xml.dom.pulldom.parseString(data):
if event == xml.dom.pulldom.START_ELEMENT:
return (node.tagName == 'playlist' and
node.node.namespaceURI == 'http://xspf.org/ns/0/')
return False
def playlist_typefinder(typefind, func, caps):
if func(typefind):
typefind.suggest(gst.TYPE_FIND_MAXIMUM, caps)
def register_typefind(mimetype, func, extensions):
caps = gst.caps_from_string(mimetype)
gst.type_find_register(mimetype, gst.RANK_PRIMARY, playlist_typefinder,
extensions, caps, func, caps)
def register_typefinders():
register_typefind('audio/x-mpegurl', detect_m3u_header, [b'm3u', b'm3u8'])
register_typefind('audio/x-scpls', detect_pls_header, [b'pls'])
register_typefind('application/xspf+xml', detect_xspf_header, [b'xspf'])