mirror of
https://github.com/dmunozv04/iSponsorBlockTV.git
synced 2026-03-14 06:22:56 +03:00
@@ -17,3 +17,5 @@ skip_categories = (
|
||||
('Preview', 'preview'),
|
||||
('Filler', 'filler'),
|
||||
)
|
||||
|
||||
youtube_client_blacklist = ["TVHTML5_FOR_KIDS"]
|
||||
|
||||
@@ -3,6 +3,7 @@ import aiohttp
|
||||
import time
|
||||
import logging
|
||||
from . import api_helpers, ytlounge
|
||||
from .constants import youtube_client_blacklist
|
||||
import traceback
|
||||
|
||||
|
||||
@@ -40,7 +41,6 @@ class DeviceListener:
|
||||
except:
|
||||
# traceback.print_exc()
|
||||
await asyncio.sleep(10)
|
||||
|
||||
while not self.cancelled:
|
||||
while not (await self.is_available()) and not self.cancelled:
|
||||
await asyncio.sleep(10)
|
||||
@@ -49,17 +49,17 @@ class DeviceListener:
|
||||
except:
|
||||
pass
|
||||
while not lounge_controller.connected() and not self.cancelled:
|
||||
# Doesn't connect to the device if it's a kids profile (it's broken)
|
||||
await asyncio.sleep(10)
|
||||
try:
|
||||
await lounge_controller.connect()
|
||||
except:
|
||||
pass
|
||||
print(f"Connected to device {lounge_controller.screen_name}")
|
||||
try:
|
||||
#print("Subscribing to lounge")
|
||||
# print("Subscribing to lounge")
|
||||
sub = await lounge_controller.subscribe_monitored(self)
|
||||
await sub
|
||||
#print("Subscription ended")
|
||||
await asyncio.sleep(10)
|
||||
except:
|
||||
pass
|
||||
|
||||
@@ -110,7 +110,6 @@ class DeviceListener:
|
||||
self.api_helper.mark_viewed_segments(UUID)
|
||||
) # Don't wait for this to finish
|
||||
|
||||
|
||||
# Stops the connection to the device
|
||||
async def cancel(self):
|
||||
self.cancelled = True
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import asyncio
|
||||
import json
|
||||
import aiohttp
|
||||
import pyytlounge
|
||||
from .constants import youtube_client_blacklist
|
||||
|
||||
|
||||
# Temporary imports
|
||||
from pyytlounge.api import api_base
|
||||
from pyytlounge.wrapper import NotLinkedException, desync
|
||||
create_task = asyncio.create_task
|
||||
|
||||
|
||||
@@ -40,7 +46,7 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
||||
|
||||
# Process a lounge subscription event
|
||||
def _process_event(self, event_id: int, event_type: str, args):
|
||||
# print(f"YtLoungeApi.__process_event({event_id}, {event_type}, {args})")
|
||||
print(f"YtLoungeApi.__process_event({event_id}, {event_type}, {args})")
|
||||
# (Re)start the watchdog
|
||||
try:
|
||||
self.subscribe_task_watchdog.cancel()
|
||||
@@ -51,8 +57,6 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
||||
# A bunch of events useful to detect ads playing, and the next video before it starts playing (that way we can get the segments)
|
||||
if event_type == "onStateChange":
|
||||
data = args[0]
|
||||
self.state.apply_state(data)
|
||||
self._update_state()
|
||||
# print(data)
|
||||
# Unmute when the video starts playing
|
||||
if self.mute_ads and data["state"] == "1":
|
||||
@@ -63,12 +67,12 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
||||
self._update_state()
|
||||
# Unmute when the video starts playing
|
||||
if self.mute_ads and data.get("state", "0") == "1":
|
||||
#print("Ad has ended, unmuting")
|
||||
# print("Ad has ended, unmuting")
|
||||
create_task(self.mute(False, override=True))
|
||||
elif self.mute_ads and event_type == "onAdStateChange":
|
||||
data = args[0]
|
||||
if data["adState"] == '0': # Ad is not playing
|
||||
#print("Ad has ended, unmuting")
|
||||
# print("Ad has ended, unmuting")
|
||||
create_task(self.mute(False, override=True))
|
||||
else: # Seen multiple other adStates, assuming they are all ads
|
||||
print("Ad has started, muting")
|
||||
@@ -98,11 +102,20 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
||||
create_task(self.mute(False, override=True))
|
||||
elif self.mute_ads:
|
||||
create_task(self.mute(True, override=True))
|
||||
elif event_type == "onAutoplayModeChanged":
|
||||
|
||||
elif event_type == "loungeStatus":
|
||||
data = args[0]
|
||||
create_task(self.set_auto_play_mode(data["autoplayMode"] == "ENABLED"))
|
||||
else:
|
||||
super()._process_event(event_id, event_type, args)
|
||||
devices = json.loads(data["devices"])
|
||||
for device in devices:
|
||||
if device["type"] == "LOUNGE_SCREEN":
|
||||
device_info = json.loads(device.get("deviceInfo", ""))
|
||||
if device_info.get("clientName", "") in youtube_client_blacklist:
|
||||
self._sid = None
|
||||
self._gsession = None # Force disconnect
|
||||
# elif event_type == "onAutoplayModeChanged":
|
||||
# data = args[0]
|
||||
# create_task(self.set_auto_play_mode(data["autoplayMode"] == "ENABLED"))
|
||||
super()._process_event(event_id, event_type, args)
|
||||
|
||||
# Set the volume to a specific value (0-100)
|
||||
async def set_volume(self, volume: int) -> None:
|
||||
@@ -123,4 +136,49 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
|
||||
await super()._command("setVolume", {"volume": self.volume_state.get("volume", 100), "muted": mute_str})
|
||||
|
||||
async def set_auto_play_mode(self, enabled: bool):
|
||||
await super()._command("setAutoplayMode", {"autoplayMode": "ENABLED" if enabled else "DISABLED"})
|
||||
await super()._command("setAutoplayMode", {"autoplayMode": "ENABLED" if enabled else "DISABLED"})
|
||||
|
||||
# Here just temporarily, will be removed once the PR is merged on YTlounge
|
||||
async def connect(self) -> bool:
|
||||
"""Attempt to connect using the previously set tokens"""
|
||||
if not self.linked():
|
||||
raise NotLinkedException("Not linked")
|
||||
|
||||
connect_body = {
|
||||
"app": "web",
|
||||
"mdx-version": "3",
|
||||
"name": self.device_name,
|
||||
"id": self.auth.screen_id,
|
||||
"device": "REMOTE_CONTROL",
|
||||
"capabilities": "que,dsdtr,atp",
|
||||
"method": "setPlaylist",
|
||||
"magnaKey": "cloudPairedDevice",
|
||||
"ui": "false",
|
||||
"deviceContext": "user_agent=dunno&window_width_points=&window_height_points=&os_name=android&ms=",
|
||||
"theme": "cl",
|
||||
"loungeIdToken": self.auth.lounge_id_token,
|
||||
}
|
||||
connect_url = (
|
||||
f"{api_base}/bc/bind?RID=1&VER=8&CVER=1&auth_failure_option=send_error"
|
||||
)
|
||||
async with aiohttp.ClientSession() as session:
|
||||
async with session.post(url=connect_url, data=connect_body) as resp:
|
||||
try:
|
||||
text = await resp.text()
|
||||
if resp.status == 401:
|
||||
self.auth.lounge_id_token = None
|
||||
return False
|
||||
|
||||
if resp.status != 200:
|
||||
self._logger.warning(
|
||||
"Unknown reply to connect %i %s", resp.status, resp.reason
|
||||
)
|
||||
return False
|
||||
lines = text.splitlines()
|
||||
async for events in self._parse_event_chunks(desync(lines)):
|
||||
self._process_events(events)
|
||||
self._command_offset = 1
|
||||
return self.connected()
|
||||
except Exception as ex:
|
||||
self._logger.exception(ex, resp.status, resp.reason)
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user