Hi everyone.
Recently I bought a Tablet and i put on it Fedora with KDE, I came from Galaxy Tab so one of the functions that i miss is the ability to cast the screen from the tablet to a Chromecast device, the problem is that there is not and easy way to cast my screen using wayland on KDE, i found a workaround to cast videos or images using a Brave or VLC, but sometimes i want to cast an application so i need to cast my screen or at least the application window.
I’m a Software Engineer but mostly focused on web development and backend, however I decided to work on this feature with my few knowledge about wayand and kde development, my idea is first, create a service to interact with chromecast protocol(find, devices, stream media, etc…) and second, create a KDE plasmoid for interacting with this service with he ability to cast my screen or a window .
I’m using python right now because it’s the easier way to interact with chromecast that i found but i’m open to alternatives.
here’s my progress:
I wrote a simple script with Python, my idea was use ffmpeg for creating a stream of my screen and cast to an specific chromecast device, it’s not working because the ffmpeg show errors when i try to cast the screen on wayland but the chromecast functions are working: find devices and cast media to those devices.
Here’s my script, it’s only depends on pychromecast pip package:
import pychromecast
import time
import subprocess
import os
from pychromecast.controllers.media import MediaController
def find_chromecasts():
print("Searching Chromecast devices...")
chromecasts, browser = pychromecast.get_chromecasts()
if not chromecasts:
print("Not found.")
return None
print("Chromecast devices availble:")
for i, cc in enumerate(chromecasts):
print(f"{i}: {cc.cast_info.friendly_name}")
selection = int(input("Select Chromecast device: "))
cast = chromecasts[selection]
print(f"Connected to {cast.cast_info.friendly_name}")
cast.wait()
return cast
def get_displays():
displays = []
xrandr_output = subprocess.check_output(["xrandr", "--listmonitors"]).decode()
for line in xrandr_output.split('\n')[1:]: # Skip the first line
if line.strip():
displays.append(line.split()[-1])
return displays
def select_display():
displays = get_displays()
print("Displays disponibles:")
for i, display in enumerate(displays):
print(f"{i}: {display}")
selection = int(input("Select display: "))
return displays[selection]
def get_display_resolution(display):
xrandr_output = subprocess.check_output(["xrandr", "--query"]).decode()
for line in xrandr_output.split('\n'):
if display in line and "connected" in line:
resolution = line.split()[2].split('+')[0]
return resolution
return "1920x1080" # Default resolution if not found
def start_ffmpeg_stream(cast, display):
ip = cast.cast_info.host
port = cast.cast_info.port
resolution = get_display_resolution(display)
print("Casting to: ", ip)
ffmpeg_command = [
"ffmpeg",
"-f", "x11grab",
"-r", "60",
"-s", resolution,
"-i", f"{os.environ['DISPLAY']}.0+{display}",
"-vcodec", "libx264",
"-preset", "ultrafast",
"-tune", "zerolatency",
"-maxrate", "5000k",
"-bufsize", "10000k",
"-f", "matroska",
f"tcp://{ip}:{port}"
]
print("starting transmission with ffmpeg...")
return subprocess.Popen(ffmpeg_command)
def stream_to_chromecast(cast, display):
mc = cast.media_controller
print(f"Setting transmission to {cast.cast_info.friendly_name}")
stream_url = f"tcp://{cast.cast_info.host}:8009"
ffmpeg_process = start_ffmpeg_stream(cast, display)
print("Starting Chromecast transmission...")
mc.play_media(stream_url, 'video/mp4')
mc.block_until_active()
print("Play started. Press Ctrl+C To stop.")
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
print("Stoping transmission...")
mc.stop()
cast.quit_app()
ffmpeg_process.terminate()
ffmpeg_process.wait()
if __name__ == "__main__":
cast = find_chromecasts()
if cast:
display = select_display()
stream_to_chromecast(cast, display)
Currently I’m looking for a better way to cast the screen on wayland, so any help is welcome, also i have no idea how to develop the cast widget, I’m focused right now on the functionality so any advice is welcome to.
Also here’s mockup of the plasmoid:
Any help or advice is welcome, thanks for reading.