From 45626df8f248f07e194a9723460f0ffc5d1102ac Mon Sep 17 00:00:00 2001 From: AbdullahGheith <64132433+AbdullahGheith@users.noreply.github.com> Date: Thu, 2 Oct 2025 09:17:37 +0200 Subject: [PATCH 1/6] Update cli.py fixed json scan --- catt/cli.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/catt/cli.py b/catt/cli.py index 2299dde..8c99589 100755 --- a/catt/cli.py +++ b/catt/cli.py @@ -564,7 +564,14 @@ def scan(json_output): devices = get_cast_infos() if json_output: - echo_json({d.friendly_name: d._asdict() for d in devices}) + echo_json({d.friendly_name: { + 'host': d.host, + 'port': d.port, + 'uuid': d.uuid, + 'model_name': d.model_name, + 'friendly_name': d.friendly_name, + 'manufacturer': d.manufacturer + } for d in devices}) else: if not devices: raise CastError("No devices found") From 4f7e19ad7438bf8426efac294e101aab724ad056 Mon Sep 17 00:00:00 2001 From: Abdullah Gheith Date: Tue, 10 Mar 2026 01:19:27 +0100 Subject: [PATCH 2/6] possiblity to define title in the cli when casting --- catt/cli.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/catt/cli.py b/catt/cli.py index 8c99589..1351c7b 100755 --- a/catt/cli.py +++ b/catt/cli.py @@ -214,6 +214,12 @@ def cli(ctx, device): metavar="TIME", help="Start playback at specific timestamp.", ) +@click.option( + "-l", + "--title", + metavar="TITLE", + help="Specify a title for the media file.", +) @click.option( "-b", "--block", @@ -238,6 +244,7 @@ def cast( no_playlist: bool, ytdl_option, seek_to: str, + title: str, stream_type: str, block: bool = False, ): @@ -300,14 +307,14 @@ def cast( click.echo( '{} "{}" on "{}"...'.format( "Showing" if media_is_image else "Playing", - stream.video_title, + title or stream.video_title, cst.cc_name, ) ) if cst.info_type == "url": cst.play_media_url( stream.video_url, - title=stream.video_title, + title=title or stream.video_title, content_type=stream.guessed_content_type, subtitles=subs.url if subs else None, thumb=stream.video_thumbnail, From 495fbbbf078fd05eb90b963040c1d0563163edd9 Mon Sep 17 00:00:00 2001 From: Abdullah Gheith Date: Tue, 10 Mar 2026 01:36:19 +0100 Subject: [PATCH 3/6] possiblity to define volume in the cli when casting --- catt/cli.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/catt/cli.py b/catt/cli.py index 1351c7b..0cbc8ce 100755 --- a/catt/cli.py +++ b/catt/cli.py @@ -220,6 +220,13 @@ def cli(ctx, device): metavar="TITLE", help="Specify a title for the media file.", ) +@click.option( + "-v", + "--volume", + type=click.IntRange(0, 100), + metavar="LVL", + help="Set volume (0-100).", +) @click.option( "-b", "--block", @@ -245,6 +252,7 @@ def cast( ytdl_option, seek_to: str, title: str, + volume: int, stream_type: str, block: bool = False, ): @@ -311,6 +319,9 @@ def cast( cst.cc_name, ) ) + if volume is not None: + cst.volume(volume / 100.0) + if cst.info_type == "url": cst.play_media_url( stream.video_url, @@ -319,8 +330,8 @@ def cast( subtitles=subs.url if subs else None, thumb=stream.video_thumbnail, current_time=seek_to, - stream_type=stream.stream_type, - media_info=stream.media_info, + stream_type=getattr(stream, "stream_type", None), + media_info=getattr(stream, "media_info", None), ) elif cst.info_type == "id": cst.play_media_id(stream.video_id, current_time=seek_to) From 06386a066e6ed5217f734094f49f876d4d5a5847 Mon Sep 17 00:00:00 2001 From: Abdullah Gheith Date: Tue, 10 Mar 2026 01:55:53 +0100 Subject: [PATCH 4/6] remote mp3 fix --- catt/stream_info.py | 3 +++ tests/test_catt.py | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/catt/stream_info.py b/catt/stream_info.py index 2d2426e..3399cc5 100644 --- a/catt/stream_info.py +++ b/catt/stream_info.py @@ -257,6 +257,9 @@ def _get_stream_info(self, preinfo): raise ExtractionError("yt-dlp extractor failed") def _get_stream_url(self, info): + if info.get("direct"): + return info["url"] + try: format_selector = self._ydl.build_format_selector(self._best_format) except ValueError: diff --git a/tests/test_catt.py b/tests/test_catt.py index 8abbb00..42f08cc 100644 --- a/tests/test_catt.py +++ b/tests/test_catt.py @@ -58,6 +58,13 @@ def test_stream_info_other_video(self): self.assertTrue(stream.is_remote_file) self.assertEqual(stream.extractor, "twitch") + def test_stream_info_direct_link(self): + url = "https://file-examples.com/storage/fede0b421769af5709b2497/2017/11/file_example_MP3_700KB.mp3" + stream = StreamInfo(url) + self.assertEqual(stream.video_url, url) + self.assertTrue(stream.is_remote_file) + self.assertTrue(stream._is_direct_link) + if __name__ == "__main__": import sys From 56dab61e7c03294245bbe53a0c5744700779c5d9 Mon Sep 17 00:00:00 2001 From: AbdullahGheith <64132433+AbdullahGheith@users.noreply.github.com> Date: Thu, 12 Mar 2026 06:50:49 +0100 Subject: [PATCH 5/6] Update test_catt.py Replaced url with selfhosted url --- tests/test_catt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_catt.py b/tests/test_catt.py index 42f08cc..da77008 100644 --- a/tests/test_catt.py +++ b/tests/test_catt.py @@ -59,7 +59,7 @@ def test_stream_info_other_video(self): self.assertEqual(stream.extractor, "twitch") def test_stream_info_direct_link(self): - url = "https://file-examples.com/storage/fede0b421769af5709b2497/2017/11/file_example_MP3_700KB.mp3" + url = "https://homeazan.com/file_example_MP3_700KB.mp3" stream = StreamInfo(url) self.assertEqual(stream.video_url, url) self.assertTrue(stream.is_remote_file) From f75bee398dccbff57d3971b6651349d0f789b577 Mon Sep 17 00:00:00 2001 From: Abdullah Gheith Date: Sat, 14 Mar 2026 14:55:03 +0100 Subject: [PATCH 6/6] formatting --- catt/cli.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/catt/cli.py b/catt/cli.py index 0cbc8ce..f39284a 100755 --- a/catt/cli.py +++ b/catt/cli.py @@ -582,14 +582,19 @@ def scan(json_output): devices = get_cast_infos() if json_output: - echo_json({d.friendly_name: { - 'host': d.host, - 'port': d.port, - 'uuid': d.uuid, - 'model_name': d.model_name, - 'friendly_name': d.friendly_name, - 'manufacturer': d.manufacturer - } for d in devices}) + echo_json( + { + d.friendly_name: { + "host": d.host, + "port": d.port, + "uuid": d.uuid, + "model_name": d.model_name, + "friendly_name": d.friendly_name, + "manufacturer": d.manufacturer, + } + for d in devices + } + ) else: if not devices: raise CastError("No devices found")