Only show direct sound outputs on windows.

This commit is contained in:
Matthew Stratford 2021-04-14 13:43:58 +01:00
parent 0dcd0b4ae6
commit 2a24e6400b
2 changed files with 38 additions and 12 deletions

View file

@ -1,14 +1,21 @@
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional, Tuple
import sounddevice as sd import sounddevice as sd
from helpers.os_environment import isLinux, isMacOS, isWindows from helpers.os_environment import isLinux, isMacOS, isWindows
import glob import glob
# TODO: https://wiki.libsdl.org/FAQUsingSDL maybe try setting some of these env variables for choosing different host APIs?
WINDOWS_APIS = ["Windows DirectSound"]
class DeviceManager: class DeviceManager:
@classmethod @classmethod
def _isOutput(cls, device: Dict[str, Any]) -> bool: def _isOutput(cls, device: Dict[str, Any]) -> bool:
return device["max_output_channels"] > 0 return device["max_output_channels"] > 0
@classmethod
def _isHostAPI(cls, host_api) -> bool:
return host_api
@classmethod @classmethod
def _getAudioDevices(cls) -> sd.DeviceList: def _getAudioDevices(cls) -> sd.DeviceList:
# To update the list of devices # To update the list of devices
@ -20,10 +27,24 @@ class DeviceManager:
return devices return devices
@classmethod @classmethod
def getAudioOutputs(cls) -> List[Dict]: def getAudioOutputs(cls) -> Tuple[List[Dict]]:
outputs: List[Dict] = list(filter(cls._isOutput, cls._getAudioDevices())) host_apis = sd.query_hostapis()
outputs = sorted(outputs, key=lambda k: k["name"]) devices: sd.DeviceList = cls._getAudioDevices()
return [{"name": None}] + outputs
valid_host_apis = []
for host_api_id in range(len(host_apis)):
if isWindows() and host_apis[host_api_id]["name"] not in WINDOWS_APIS:
continue
host_api_devices = (device for device in devices if device["hostapi"] == host_api_id)
outputs: List[Dict] = list(filter(cls._isOutput, host_api_devices))
outputs = sorted(outputs, key=lambda k: k["name"])
valid_host_apis.append(host_apis[host_api_id])
valid_host_apis[-1]["output_devices"] = outputs
return host_apis
@classmethod @classmethod
def getSerialPorts(cls) -> List[Optional[str]]: def getSerialPorts(cls) -> List[Optional[str]]:

View file

@ -1,15 +1,20 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% block content_inner %} {% block content_inner %}
<h3 class="h5">Audio Outputs</h3> <h3 class="h5">Audio Outputs</h3>
<code> <p><strong>Please note: Currently BAPSicle does not support choosing which Host API is used. This list is for reference.</strong></p>
{% for output in data.outputs %}
{% for host_api in data.outputs %}
<hr>
{{host_api.name}}
<br>
<code>
{% for output in host_api.output_devices %}
Set for: Set for:
{% for channel in data.channels %} {% for channel in data.channels %}
<a href="/player/{{channel.channel}}/output/{{output.name}}">Channel {{channel.channel}}</a> <a href="/player/{{channel.channel}}/output/{{output.name}}">Channel {{channel.channel}}</a>
{% endfor %} {% endfor %}
- {% if output.name %}{{output.name}}{% else %}System Default Output{% endif %}<br> - {% if output.name %}{{output.name}}{% else %}System Default Output{% endif %}<br>
{% endfor %} {% endfor %}
</code> </code>
{% endfor %}
{% endblock %} {% endblock %}