From: Marcel van der Veldt Date: Sat, 7 May 2022 19:20:06 +0000 (+0200) Subject: auto select stream port (#285) X-Git-Url: https://git.kitaultman.com/?a=commitdiff_plain;h=a602ecf6f477be1355c8d3fff648590afa46642c;p=music-assistant-server.git auto select stream port (#285) --- diff --git a/music_assistant/controllers/stream.py b/music_assistant/controllers/stream.py index b4ba59de..32cce3a2 100644 --- a/music_assistant/controllers/stream.py +++ b/music_assistant/controllers/stream.py @@ -20,7 +20,7 @@ from music_assistant.helpers.audio import ( ) from music_assistant.helpers.process import AsyncProcess from music_assistant.helpers.typing import MusicAssistant -from music_assistant.helpers.util import get_ip +from music_assistant.helpers.util import get_ip, select_stream_port from music_assistant.models.errors import MediaNotFoundError, MusicAssistantError from music_assistant.models.media_items import ContentType, MediaType from music_assistant.models.player_queue import CrossFadeMode, PlayerQueue, QueueItem @@ -29,11 +29,11 @@ from music_assistant.models.player_queue import CrossFadeMode, PlayerQueue, Queu class StreamController: """Controller to stream audio to players.""" - def __init__(self, mass: MusicAssistant, port: int = 8095): + def __init__(self, mass: MusicAssistant, port: Optional[int] = None): """Initialize instance.""" self.mass = mass self.logger = mass.logger.getChild("stream") - self._port = port + self._port = port or select_stream_port() self._ip: str = get_ip() self._subscribers: Dict[str, Set[str]] = {} self._client_queues: Dict[str, Dict[str, asyncio.Queue]] = {} diff --git a/music_assistant/helpers/util.py b/music_assistant/helpers/util.py index 44c6f39f..e121d40e 100755 --- a/music_assistant/helpers/util.py +++ b/music_assistant/helpers/util.py @@ -5,6 +5,7 @@ import asyncio import os import platform import socket +import socketserver import tempfile from typing import Any, Callable, Dict, List, Optional, Set, Tuple, TypeVar @@ -174,6 +175,20 @@ def get_ip(): return _ip +def is_port_in_use(port: int) -> bool: + """Check if port is in use.""" + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as _sock: + return _sock.connect_ex(("localhost", port)) == 0 + + +def select_stream_port() -> int: + """Automaticlaly find available stream port, prefer the default 8095.""" + if not is_port_in_use(8095): + return 8095 + with socketserver.TCPServer(("localhost", 0), None) as _sock: + return _sock.server_address[1] + + def get_folder_size(folderpath): """Return folder size in gb.""" total_size = 0 diff --git a/music_assistant/mass.py b/music_assistant/mass.py index b5dc5311..7dfe1673 100644 --- a/music_assistant/mass.py +++ b/music_assistant/mass.py @@ -37,7 +37,6 @@ class MusicAssistant: def __init__( self, db_url: DatabaseURL, - stream_port: int = 8095, session: Optional[aiohttp.ClientSession] = None, ) -> None: """ @@ -63,7 +62,7 @@ class MusicAssistant: self.metadata = MetaDataController(self) self.music = MusicController(self) self.players = PlayerController(self) - self.streams = StreamController(self, stream_port) + self.streams = StreamController(self) self._tracked_tasks: List[asyncio.Task] = [] self.closed = False