Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add support for HTTP audio output streaming #56

Open
jodal opened this Issue · 3 comments

2 participants

@jodal
Owner

If one provided a stream of the audio played by Mopidy over HTTP, it could be used by both MPD clients with support for HTTP streams and devices like e.g. Squeezeboxes.

The stream encoding should probably be Ogg Vorbis and/or MP3.

@adamcik
Owner

Asssuming the follwing code:

import logging
from BaseHTTPServer import BaseHTTPRequestHandler

from mopidy import get_version

logger = logging.getLogger('mopidy.outputs.http')

class StreamingHTTPRequestHandler(BaseHTTPRequestHandler):
    server_version = 'HTTPOutput/%s' % get_version()

    def do_GET(self):
        self.send_response(200)
        self.send_header('content-type', 'audio/mpeg')
        self.end_headers()

        register_fd_with_output(self.wfile.fileno())

        self.close_connection = 0

    def log_message(self, format, *args):
        logger.info(format, *args)

where register_fd_with_output() is a function that emits the add signal on the fd sink in a HTTPOutput (audioconvert ! lame ! multifdsink) and we have a BaseHTTPServer.HTTPServer running in a ThreadingActor with the StreamingHTTPRequestHandler we should have working HTTP streaming.

For additional features like metadata the following links should be useful:

@adamcik
Owner

The code above should probably not be used for solving this issue. With the current state of the code base we want something that builds on cherrypy.

First thing that needs to be done is to create and register a GStreamer element we can use in the OUTPUT setting. Using the mixers, the code in #152 or Pitivi examples should be enough to get started. The element will basically be wrapping a multifdsink, handling the cherrypy stuff and passing the FDs between them.

As for the HTTP part, there is at least to ways of going about it. First one is probably the easiest, start an independent cherrypy server to the frontend one and use that. The second one, the one I think we want is having a singleton HTTP server shared between the frontend and streaming parts of the code. This part is currently the big unknown as far as I am concerned.

Once a HTTP server is in place we need to detach the socket from cherrypy, looking at ws4py it seems setting request.rfile.rfile._sock = None is the most likely workaround we can manage. Before we detach we probably want to emit some headers, then we detach and emit the fd to the sink and we should be streaming. Looking at how ws4py takes over sockets should enable us to figure out the details.

Other part the is slightly unknown is if we extend our core audio API to allow for emitting the FDs. That is either something specialized for just that case or something more general that gives access to the output bin we are using.

@adamcik
Owner

Why I never thought of this earlier I have no idea, but as for stealing sockets, we should just us socket.fromfd to create new copy so that the original can be closed with no ill effects.

@jodal jodal added this to the v0.20 - Audio and mixer cleanup milestone
@adamcik adamcik removed this from the v0.20 - Audio cleanup milestone
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.