Projects
Multimedia
pulseaudio-dlna
Sign Up
Log In
Username
Password
We truncated the diff of some files because they were too big. If you want to see the full diff for every file,
click here
.
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 6
View file
pulseaudio-dlna.changes
Changed
@@ -1,4 +1,17 @@ ------------------------------------------------------------------- +Tue Aug 4 16:30:20 UTC 2015 - antoine.belvire@laposte.net + +- Update to 0.4.3: + * Fix a bug when trying to terminate an encoder process + * Catch exceptions when trying to update pulseaudio sinks + * Fix a timing issue where the streamserver was not ready but + devices were already instructed to play +- Changes introduced in 0.4.2: + * The mp3 encoder is now prioritize over wav + * Add '--disable-switchback' option + * Wav encoders do not longer share their encoder process + +------------------------------------------------------------------- Wed Jul 29 19:00:12 UTC 2015 - antoine.belvire@laposte.net - Update to 0.4.1:
View file
pulseaudio-dlna.spec
Changed
@@ -17,7 +17,7 @@ Name: pulseaudio-dlna -Version: 0.4.1 +Version: 0.4.3 Release: 0 Summary: A DLNA server which brings DLNA/UPnP support to PulseAudio License: GPL-3.0
View file
pulseaudio-dlna-0.4.1.tar.gz/README.md -> pulseaudio-dlna-0.4.3.tar.gz/README.md
Changed
@@ -8,6 +8,8 @@ It's main goals are: easy to use, no configuration hassle, no big dependencies. +UPNP renderers in your network will show up as pulseaudio sinks. + ![Image of pulseaudio-dlna](https://github.com/masmu/pulseaudio-dlna/blob/master/samples/images/pavucontrol-sample.png) @@ -34,6 +36,16 @@ ## Changelog ## + * __0.4.3__ - (_2015-08-02_) + - Fixed a bug when trying to terminate an encoder process + - Catch exceptions when trying to update pulseaudio sinks + - Fixed a timing issue where the streamserver was not ready but devices were already instructed to play + + * __0.4.2__ - (_2015-08-02_) + - The mp3 encoder is now prioritize over wav + - Added '--disable-switchback' option + - Wav encoders do not longer share their encoder process + * __0.4.1__ - (_2015-07-27_) - Fixed Makefile for launchpad @@ -103,7 +115,6 @@ Supported Ubuntu releases: - 15.04 (Vivid Vervet) -- 14.10 (Utopic Unicorn) - 14.04.2 LTS (Trusty Tahr) Ubuntu users can install _pulseaudio-dlna_ via the following [repository](https://launchpad.net/~qos/+archive/ubuntu/pulseaudio-dlna). @@ -129,7 +140,8 @@ [https://aur.archlinux.org/packages/pulseaudio-dlna/](https://aur.archlinux.org/packages/pulseaudio-dlna/) - openSUSE (_.rpm_) [http://packman.links2linux.de/package/pulseaudio-dlna](http://packman.links2linux.de/package/pulseaudio-dlna) - +- Fedora - RHEL - CentOS - EPEL + [https://copr.fedoraproject.org/coprs/cygn/pulseaudio-dlna/](https://copr.fedoraproject.org/coprs/cygn/pulseaudio-dlna/) ## Installation via git ## @@ -248,15 +260,12 @@ your music. If you stop _pulseaudio-dlna_ it will cleanly remove the created UPNP devices from PulseAudio and your UPNP devices will stop playing. -Also note that _pulseaudio-dlna_ won't search for additional UPNP devices after -startup. It just does this once and (for me) there is no need in continuously -doing that. So if you added a new UPNP device to your network, restart -_pulseaudio-dlna_. +Since 0.4, new devices are automatically discovered as they appear on the network. ### CLI ### Usage: - pulseaudio-dlna [--host <host>] [--port <port>] [--encoder <encoder>] [--bit-rate=<rate>] [--filter-device=<filter-device>] [--renderer-urls <urls>] [--debug] [--fake-http10-content-length] + pulseaudio-dlna [--host <host>] [--port <port>] [--encoder <encoder>] [--bit-rate=<rate>] [--filter-device=<filter-device>] [--renderer-urls <urls>] [--debug] [--fake-http10-content-length] [--disable-switchback] pulseaudio-dlna [-h | --help | --version] Options: @@ -276,6 +285,7 @@ --renderer-urls=<urls> Set the renderer urls yourself. no discovery will commence. --debug enables detailed debug messages. --fake-http10-content-length If set, the content-length of HTTP 1.0 requests will be set to 100 GB. + --disable-switchback If set, streams won't switched back to the default sink if a device disconnects. -v --version Show the version. -h --help Show the help. @@ -311,7 +321,7 @@ ## Tested devices ## -_pulseaudio-dlna_ was successfully tested on the follwing devices / applications: +_pulseaudio-dlna_ was successfully tested on the following devices / applications: - D-Link DCH-M225/E - [Cocy UPNP media renderer](https://github.com/mnlipp/CoCy) @@ -329,9 +339,10 @@ - Hame Soundrouter - [Raumfeld Speaker M](http://raumfeld.com) - Pioneer VSX-824 (AV Receiver) -- [ROCKI] (http://www.myrocki.com/) +- [ROCKI](http://www.myrocki.com/) - Sony STR-DN1050 (AV Receiver) - Pure Jongo S3 +- [Volumio](http://volumio.org) ## Supported encoders ##
View file
pulseaudio-dlna-0.4.1.tar.gz/debian/changelog -> pulseaudio-dlna-0.4.3.tar.gz/debian/changelog
Changed
@@ -1,3 +1,21 @@ +pulseaudio-dlna (0.4.3) trusty; urgency=low + + * Fixed a bug when trying to terminate an encoder process + * Catch exceptions when trying to update pulseaudio sinks + * Fixed a timing issue where the streamserver was not ready but devices were already instructed to play + + -- Massimo Mund <mo@lancode.de> Sun, 02 Aug 2015 15:06:22 +0100 + + +pulseaudio-dlna (0.4.2) trusty; urgency=low + + * The mp3 encoder is now prioritize over wav + * Added '--disable-switchback' option + * Wav encoders do not longer share their encoder process + + -- Massimo Mund <mo@lancode.de> Sun, 02 Aug 2015 13:35:12 +0100 + + pulseaudio-dlna (0.4.1) trusty; urgency=low * Fixed Makefile for launchpad
View file
pulseaudio-dlna-0.4.1.tar.gz/debian/control -> pulseaudio-dlna-0.4.3.tar.gz/debian/control
Changed
@@ -7,7 +7,7 @@ python-pip, python-setuptools, python-dbus, - python-virtualenv, + python-virtualenv | virtualenv, git-core, ca-certificates, debhelper (>=9),
View file
pulseaudio-dlna-0.4.1.tar.gz/debian/pulseaudio-dlna.1 -> pulseaudio-dlna-0.4.3.tar.gz/debian/pulseaudio-dlna.1
Changed
@@ -1,12 +1,16 @@ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.44.1. -.TH PULSEAUDIO-DLNA "1" "July 2015" "pulseaudio-dlna 0.4.1" "User Commands" +.TH PULSEAUDIO-DLNA "1" "August 2015" "pulseaudio-dlna 0.4.3" "User Commands" .SH NAME -pulseaudio-dlna \- manual page for pulseaudio-dlna 0.4.1 +pulseaudio-dlna \- manual page for pulseaudio-dlna 0.4.3 .SH DESCRIPTION .SS "Usage:" .IP -pulseaudio\-dlna [\-\-host <host>] [\-\-port <port>] [\-\-encoder <encoder>] [\-\-bit\-rate=<rate>] [\-\-filter\-device=<filter\-device>] [\-\-renderer\-urls <urls>] [\-\-debug] [\-\-fake\-http10\-content\-length] +pulseaudio\-dlna [\-\-host <host>] [\-\-port <port>] [\-\-encoder <encoder>] [\-\-bit\-rate=<rate>] [\-\-filter\-device=<filter\-device>] [\-\-renderer\-urls <urls>] [\-\-debug] [\-\-fake\-http10\-content\-length] [\-\-disable\-switchback] pulseaudio\-dlna [\-h | \fB\-\-help\fR | \fB\-\-version]\fR +.IP +Note that _pulseaudio\-dlna_ has to run all the time while you are listening to your music. If you stop _pulseaudio\-dlna_ it will cleanly remove the created UPNP devices from PulseAudio and your UPNP devices will stop playing. +.IP +Since 0.4, new devices are automatically discovered as they appear on the network. .SH OPTIONS .TP \fB\-\-host=\fR<host> @@ -34,6 +38,9 @@ \- opus Opus Interactive Audio Codec (OPUS) .TP +\- aac +Advanced Audio Coding (FAAC) +.TP \fB\-b\fR \fB\-\-bit\-rate=\fR<rate> Set the audio encoder's bitrate. .TP @@ -51,11 +58,39 @@ \fB\-\-fake\-http10\-content\-length\fR If set, the content\-length of HTTP 1.0 requests will be set to 100 GB. .TP +\fB\-\-disable\-switchback\fR +If set, streams won't switched back to the default sink if a device disconnects. +.TP \fB\-v\fR \fB\-\-version\fR Show the version. .TP \fB\-h\fR \fB\-\-help\fR Show the help. +.SH EXAMPLES +.IP +\- pulseaudio\-dlna +.IP +will start pulseaudio\-dlna on port 8080 and stream your PulseAudio streams encoded with mp3. +.IP +\- pulseaudio\-dlna \-\-encoder ogg +.IP +will start pulseaudio\-dlna on port 8080 and stream your PulseAudio streams encoded with Ogg Vorbis. +.IP +\- pulseaudio\-dlna \-\-port 10291 \-\-encoder flac +.IP +will start pulseaudio\-dlna on port 10291 and stream your PulseAudio streams encoded with FLAC. +.IP +\- pulseaudio\-dlna \-\-filter\-device 'Nexus 5,TV' +.IP +will just use devices named Nexus 5 or TV even when more devices got discovered. +.IP +\- pulseaudio\-dlna \-\-renderer\-urls http://192.168.1.7:7676/smp_10_ +.IP +won't discover upnp devices by itself. Instead it will search for upnp renderers +at the specified locations. You can specify multiple locations via urls +separated by comma (,). Most users won't ever need this option, but since +UDP multicast packages won't work (most times) over VPN connections this is +very useful if you ever plan to stream to a UPNP device over VPN. .SH "SEE ALSO" The full documentation for .B pulseaudio-dlna
View file
pulseaudio-dlna-0.4.1.tar.gz/pulseaudio_dlna/__main__.py -> pulseaudio-dlna-0.4.3.tar.gz/pulseaudio_dlna/__main__.py
Changed
@@ -17,9 +17,13 @@ ''' Usage: - pulseaudio-dlna [--host <host>] [--port <port>] [--encoder <encoder>] [--bit-rate=<rate>] [--filter-device=<filter-device>] [--renderer-urls <urls>] [--debug] [--fake-http10-content-length] + pulseaudio-dlna [--host <host>] [--port <port>] [--encoder <encoder>] [--bit-rate=<rate>] [--filter-device=<filter-device>] [--renderer-urls <urls>] [--debug] [--fake-http10-content-length] [--disable-switchback] pulseaudio-dlna [-h | --help | --version] + Note that _pulseaudio-dlna_ has to run all the time while you are listening to your music. If you stop _pulseaudio-dlna_ it will cleanly remove the created UPNP devices from PulseAudio and your UPNP devices will stop playing. + + Since 0.4, new devices are automatically discovered as they appear on the network. + Options: --host=<host> Set the server ip. -p --port=<port> Set the server port [default: 8080]. @@ -30,6 +34,7 @@ - flac Free Lossless Audio Codec (FLAC) - wav Waveform Audio File Format (WAV) - opus Opus Interactive Audio Codec (OPUS) + - aac Advanced Audio Coding (FAAC) -b --bit-rate=<rate> Set the audio encoder's bitrate. --filter-device=<filter-device> Set a name filter for devices which should be added. Devices which get discovered, but won't match the @@ -37,10 +42,38 @@ --renderer-urls=<urls> Set the renderer urls yourself. no discovery will commence. --debug enables detailed debug messages. --fake-http10-content-length If set, the content-length of HTTP 1.0 requests will be set to 100 GB. + --disable-switchback If set, streams won't switched back to the default sink if a device disconnects. -v --version Show the version. -h --help Show the help. + +Examples: + - pulseaudio-dlna + + will start pulseaudio-dlna on port 8080 and stream your PulseAudio streams encoded with mp3. + + - pulseaudio-dlna --encoder ogg + + will start pulseaudio-dlna on port 8080 and stream your PulseAudio streams encoded with Ogg Vorbis. + + - pulseaudio-dlna --port 10291 --encoder flac + + will start pulseaudio-dlna on port 10291 and stream your PulseAudio streams encoded with FLAC. + + - pulseaudio-dlna --filter-device 'Nexus 5,TV' + + will just use devices named Nexus 5 or TV even when more devices got discovered. + + - pulseaudio-dlna --renderer-urls http://192.168.1.7:7676/smp_10_ + + won't discover upnp devices by itself. Instead it will search for upnp renderers + at the specified locations. You can specify multiple locations via urls + separated by comma (,). Most users won't ever need this option, but since + UDP multicast packages won't work (most times) over VPN connections this is + very useful if you ever plan to stream to a UPNP device over VPN. + ''' + from __future__ import unicode_literals import sys
View file
pulseaudio-dlna-0.4.1.tar.gz/pulseaudio_dlna/application.py -> pulseaudio-dlna-0.4.3.tar.gz/pulseaudio_dlna/application.py
Changed
@@ -119,10 +119,15 @@ if options['--fake-http10-content-length']: fake_http10_content_length = True + disable_switchback = False + if options['--disable-switchback']: + disable_switchback = True + try: stream_server = pulseaudio_dlna.streamserver.ThreadedStreamServer( host, port, bridges, message_queue, fake_http10_content_length=fake_http10_content_length, + disable_switchback=disable_switchback, ) except socket.error: logger.error( @@ -153,8 +158,8 @@ 'Perhaps this is already in use? Application terminates.') sys.exit(1) - self.run_process(target=pulse.run) self.run_process(target=stream_server.run) + self.run_process(target=pulse.run) self.run_process(target=ssdp_listener.run) setproctitle.setproctitle('pulseaudio-dlna')
View file
pulseaudio-dlna-0.4.1.tar.gz/pulseaudio_dlna/encoders.py -> pulseaudio-dlna-0.4.3.tar.gz/pulseaudio_dlna/encoders.py
Changed
@@ -136,7 +136,7 @@ self._mime_types = ['audio/wav', 'audio/x-wav'] self._bit_rate = None self._bit_rates = [] - self._priority = 18 + self._priority = 15 self._enabled = True @property @@ -159,7 +159,7 @@ self._bit_rate = 192 self._bit_rates = [32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320] - self._priority = 15 + self._priority = 18 self._enabled = True @property
View file
pulseaudio-dlna-0.4.1.tar.gz/pulseaudio_dlna/listener.py -> pulseaudio-dlna-0.4.3.tar.gz/pulseaudio_dlna/listener.py
Changed
@@ -55,15 +55,15 @@ self.renderers_holder = RendererHolder( stream_server_address, message_queue, plugins, device_filter) self.renderer_urls = renderer_urls - - def run(self): - setproctitle.setproctitle('ssdp_listener') if self.renderer_urls is not None: self.renderers_holder.add_renderers_by_url(self.renderer_urls) else: discover = RendererDiscover(self.renderers_holder) discover.search() logger.info('Discovery complete.') + + def run(self): + setproctitle.setproctitle('ssdp_listener') SocketServer.UDPServer.serve_forever(self)
View file
pulseaudio-dlna-0.4.1.tar.gz/pulseaudio_dlna/notification.py -> pulseaudio-dlna-0.4.3.tar.gz/pulseaudio_dlna/notification.py
Changed
@@ -35,5 +35,8 @@ title=title, message=message)) - -notify2.init('pulseaudio_dlna') +try: + notify2.init('pulseaudio_dlna') +except: + logger.error('notify2 could not be initialized! Notifications will ' + 'most likely not work.')
View file
pulseaudio-dlna-0.4.1.tar.gz/pulseaudio_dlna/plugins/upnp/renderer.py -> pulseaudio-dlna-0.4.3.tar.gz/pulseaudio_dlna/plugins/upnp/renderer.py
Changed
@@ -202,6 +202,9 @@ UpnpContentFlags.CONNECTION_STALLING_SUPPORTED, UpnpContentFlags.DLNA_VERSION_15_SUPPORTED ]) + mime_type = self.encoder.mime_type + if isinstance(self.encoder, pulseaudio_dlna.encoders.WavEncoder): + mime_type = 'audio/mpeg' metadata = self.xml['register_metadata'].format( stream_url=stream_url, title='Live Audio', @@ -209,7 +212,7 @@ creator='PulseAudio', album='Stream', encoding=self.ENCODING, - mime_type=self.encoder.mime_type, + mime_type=mime_type, content_features=str(content_features), ) data = self.xml['register'].format(
View file
pulseaudio-dlna-0.4.1.tar.gz/pulseaudio_dlna/pulseaudio.py -> pulseaudio-dlna-0.4.3.tar.gz/pulseaudio_dlna/pulseaudio.py
Changed
@@ -121,16 +121,22 @@ self.streams.append(stream) def update_sinks(self): - sink_paths = self.core.Get( - 'org.PulseAudio.Core1', 'Sinks', - dbus_interface='org.freedesktop.DBus.Properties') + try: + sink_paths = self.core.Get( + 'org.PulseAudio.Core1', 'Sinks', + dbus_interface='org.freedesktop.DBus.Properties') - self.sinks = [] - for sink_path in sink_paths: - sink = PulseSinkFactory.new(self.bus, sink_path) - if sink: - sink.fallback_sink = self.fallback_sink - self.sinks.append(sink) + self.sinks = [] + for sink_path in sink_paths: + sink = PulseSinkFactory.new(self.bus, sink_path) + if sink: + sink.fallback_sink = self.fallback_sink + self.sinks.append(sink) + except dbus.exceptions.DBusException: + logger.error( + 'Could not update sinks. This normally indicates a problem ' + 'with pulseaudio\'s dbus module. Try restarting pulseaudio ' + 'if the problem persists.') def create_null_sink(self, sink_name, sink_description): cmd = [
View file
pulseaudio-dlna-0.4.1.tar.gz/pulseaudio_dlna/streamserver.py -> pulseaudio-dlna-0.4.3.tar.gz/pulseaudio_dlna/streamserver.py
Changed
@@ -29,6 +29,8 @@ import functools import atexit import json +import os +import signal import BaseHTTPServer import SocketServer @@ -68,14 +70,15 @@ raise NotImplementedError +@functools.total_ordering class ProcessStream(object): - def __init__(self, path, recorder, encoder, server): + def __init__(self, path, recorder, encoder, manager): self.path = path self.recorder = recorder self.encoder = encoder self.recorder_process = None self.encoder_process = None - self.server = server + self.manager = manager self.sockets = {} self.timeouts = {} @@ -86,22 +89,32 @@ atexit.register(self.shutdown) - gobject.timeout_add(10000, self._on_regenerate_reinitialize_count) + gobject.timeout_add( + 10000, self._on_regenerate_reinitialize_count) class UpdateThread(threading.Thread): def __init__(self, stream): threading.Thread.__init__(self) self.stream = stream self.is_running = False + self.do_stop = False self.lock = threading.Lock() self.lock.acquire() def run(self): while True: - if self.is_running is False: + if self.do_stop: + break + elif self.is_running is False: self.lock.acquire() else: self.stream.communicate() + logger.info('Thread stopped for "{}".'.format( + self.stream.path)) + + def stop(self): + self.do_stop = True + self.resume() def pause(self): self.is_running = False @@ -173,12 +186,9 @@ logger.info('Stream closed. ' 'Cleaning up remaining processes ...') self.update_thread.pause() - self.cleanup() + self.terminate_processes() - if device not in self.sockets.values(): - self.server.message_queue.put( - {'type': 'on_bridge_disconnected', - 'stopped_bridge': device.bridge}) + self.manager._on_device_disconnect(device, self) return False def communicate(self): @@ -191,7 +201,7 @@ 'Processes of {path} initialized ...'.format( path=self.path)) if not self.do_processes_respond(): - self.cleanup() + self.terminate_processes() self.create_processes() logger.info( 'Processes of {path} reinitialized ...'.format( @@ -241,15 +251,21 @@ return (self.recorder_process.poll() is None and self.encoder_process.poll() is None) - def cleanup(self): - self._kill_process(self.encoder_process) - self._kill_process(self.recorder_process) + def terminate_processes(self): - def _kill_process(self, process): - try: - process.kill() - except: - pass + def _kill_process(process): + pid = process.pid + try: + os.kill(pid, signal.SIGTERM) + _pid, return_code = os.waitpid(pid, 0) + except: + try: + os.kill(pid, signal.SIGKILL) + except: + pass + + _kill_process(self.encoder_process) + _kill_process(self.recorder_process) def create_processes(self): if self.reinitialize_count < 3: @@ -272,30 +288,70 @@ self.reinitialize_count)) def shutdown(self, *args): - logger.info('Streaming server is shutting down.') + self.update_thread.stop() for sock in self.sockets.keys(): sock.close() + def __eq__(self, other): + if isinstance(other, ProcessStream): + return self.path == other.path + raise NotImplementedError + + def __gt__(self, other): + if isinstance(other, ProcessStream): + return self.path > other.path + raise NotImplementedError + class StreamManager(object): def __init__(self, server): - self.streams = {} + self.single_streams = [] + self.shared_streams = {} self.server = server + def _on_device_disconnect(self, device, stream): + + def _send_bridge_disconnected(bridge): + logger.info('Device "{}" disconnected.'.format(bridge.device.name)) + self.server.message_queue.put({ + 'type': 'on_bridge_disconnected', + 'stopped_bridge': bridge, + }) + + if isinstance(stream.encoder, pulseaudio_dlna.encoders.WavEncoder): + self.single_streams.remove(stream) + if not self.server.disable_switchback: + if stream not in self.single_streams: + _send_bridge_disconnected(device.bridge) + stream.shutdown() + else: + if not self.server.disable_switchback: + if device not in stream.sockets.values(): + _send_bridge_disconnected(device.bridge) + + def _create_stream(self, path, bridge, encoder): + recorder = pulseaudio_dlna.recorders.PulseaudioRecorder( + bridge.sink.monitor) + stream = ProcessStream(path, recorder, encoder, self) + return stream + def get_stream(self, path, bridge, encoder): - if path not in self.streams: - recorder = pulseaudio_dlna.recorders.PulseaudioRecorder( - bridge.sink.monitor) - stream = ProcessStream( - path, - recorder, - encoder, - self.server, - ) - self.streams[path] = stream + if isinstance(encoder, pulseaudio_dlna.encoders.WavEncoder): + # always create a seperate process stream for wav encoders + # since the client devices require the wav header which is + # just send at the beginning of each encoding process + stream = self._create_stream(path, bridge, encoder) + self.single_streams.append(stream) return stream else: - return self.streams[path] + # all other encoders can share a process stream depending + # on their path + if path not in self.shared_streams: + stream = self._create_stream(path, bridge, encoder) + self.shared_streams[path] = stream + return stream + else: + return self.shared_streams[path] class StreamRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.