Skip to content

Instantly share code, notes, and snippets.

@alexrecuenco
Last active December 16, 2023 23:19
Show Gist options
  • Save alexrecuenco/1f8e3d0edbe5e3a754e11b3ea38f127b to your computer and use it in GitHub Desktop.
Save alexrecuenco/1f8e3d0edbe5e3a754e11b3ea38f127b to your computer and use it in GitHub Desktop.
Using PyChromecast to change the volume of a chrome cast device (Useful since VLC doesn't provide volume controls)
#!/usr/bin/env python3
# requirement: PyChromecast==12.1.4
# version 0.1
import pychromecast
import argparse
from typing import List, Union
import dataclasses
UP = "up"
DOWN = "down"
UP_OPTIONS = set([UP, "up", "u", "raise", "r"])
DOWN_OPTIONS = set([DOWN, "d", "lower", "l"])
class Daemon:
cast: pychromecast.Chromecast
amount: float
def start(self):
self.cast.start()
self.cast.wait()
def __init__(self, cast: pychromecast.Chromecast, amount: float):
self.cast = cast
self.amount = amount
self.start()
def run(self, cmd: str, amount: float = 0.1):
if cmd in UP_OPTIONS:
self.cast.volume_up(self.amount)
elif cmd in DOWN_OPTIONS:
self.cast.volume_down(self.amount)
else:
try:
volume = int(cmd)
self.cast.set_volume(volume / 100)
except:
raise TypeError("Incorrect command")
@dataclasses.dataclass
class Options:
cmds: List[str]
amount: float
name: str
daemon: bool
def parse_args() -> Options:
parser = argparse.ArgumentParser("Chromecast remote control")
parser.add_argument(
"--cmds",
nargs="*",
choices=[UP, DOWN],
help="Commands to execute on chromecast",
default=[],
)
parser.add_argument(
"-a",
"--amount",
type=float,
default=0.1,
help="Amount of volumen to increase/decrease",
)
parser.add_argument(
"-n",
"--name",
default="living",
help="Name that identifies the specific chromecast (Will choose only the first one it finds)",
)
parser.add_argument(
"--daemon", dest="daemon", action="store_true", help="Activate daemon"
)
parser.add_argument(
"--no-daemon", dest="daemon", action="store_false", help="De-activate daemon"
)
parser.set_defaults(daemon=True)
parsed = parser.parse_args()
return Options(
cmds=parsed.cmds,
amount=parsed.amount,
name=parsed.name.lower(),
daemon=parsed.daemon,
)
def main():
options = parse_args()
chromecasts = pychromecast.get_chromecasts()
cc_list = [cc for ccs in chromecasts if isinstance(ccs, list) for cc in ccs]
if len(cc_list) > 1:
print("All devices available ", [cc.name for cc in cc_list])
name = options.name
cast: Union[pychromecast.Chromecast, None] = next(
(cc for cc in cc_list if name in cc.name.lower()),
None,
)
if cast is None:
print("No device found with name", name)
exit(1)
print("Connected to", cast.name)
amount = options.amount
daemon = Daemon(cast, amount)
msg = "Input one of " + ", ".join([UP, DOWN]) + ", or a number\n"
for cmd in options.cmds:
daemon.run(cmd, amount)
if options.daemon:
while True:
cmd = input(msg)
try:
daemon.run(cmd, amount)
except TypeError:
print("WARN: Incorrect command")
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment