Final v2 commit before launch?

Adds better logging and modifies README.md
This commit is contained in:
dmunozv04
2023-10-13 17:46:25 +02:00
parent aad6eea686
commit 143e5e4eff
6 changed files with 51 additions and 29 deletions

View File

@@ -31,9 +31,9 @@ jobs:
uses: docker/metadata-action@v4
with:
images: ghcr.io/dmunozv04/isponsorblocktv, dmunozv04/isponsorblocktv
# tags: |
# type=raw,value=latest,priority=900,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
# type=ref,enable=true,priority=600,prefix=pr-,suffix=,event=pr
tags: |
type=raw,value=develop,priority=900,enable=${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
type=ref,enable=true,priority=600,prefix=pr-,suffix=,event=pr
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU

2
.gitignore vendored
View File

@@ -155,7 +155,7 @@ cython_debug/
#config folder
data/
config.json
data/config.json
.DS_Store

View File

@@ -1,33 +1,49 @@
# iSponsorBlockTV
Skip sponsor segments in YouTube videos playing on a YouTube TV device (see below for compatibility details).
Skip sponsor segments in YouTube videos playing on an Apple TV. Sponsor Block in YouTube for apple TV
This project is written in asynchronous python and should be pretty quick.
This project is written in asycronous python and should be pretty quick.
# Installation
## Installation
Check the [wiki](https://github.com/dmunozv04/iSponsorBlockTV/wiki/Installation)
Warning: armv7 builds have been deprecated.
Warning: docker armv7 builds have been deprecated. Amd64 and arm64 builds are still available.
# Usage
## Compatibility
Leyend: ✅ = Working, ❌ = Not working, ❔ = Not tested
Run iSponsorBLockTV on the same network as the Apple TV.
Open an issue/pull request if you have tested a device that isn't listed here.
It connects to the Apple TV, watches its activity and skips any sponsor segment using the [SponsorBlock](https://sponsor.ajay.app/) API.
| Device | Status |
|:-------------------|:------:|
| Apple TV | ✅ |
| Samsung TV (Tizen) | ✅ |
| LG TV (WebOS) | ✅ |
| Android TV | ❔ |
| Chromecast | ❔ |
| Roku | ❔ |
| Fire TV | ❔ |
| Nintendo Switch | ✅ |
| Xbox One/Series | ❔ |
| Playstation 4/5 | ❔ |
The last 5 videos' segments are cached to limit the number on queries on SponsorBlock and YouTube.
## Usage
Run iSponsorBlockTV on a computer that has network access.
Auto discovery will require the computer to be on the same network as the device during setup.
It connects to the device, watches its activity and skips any sponsor segment using the [SponsorBlock](https://sponsor.ajay.app/) API.
It can also skip/mute YouTube ads.
# Libraries used
- [pyatv](https://github.com/postlund/pyatv) Used to connect to the Apple TV
## Libraries used
- [pyytlounge](https://github.com/FabioGNR/pyytlounge) Used to interact with the device
- asyncio and [aiohttp](https://github.com/aio-libs/aiohttp)
- [async-cache](https://github.com/iamsinghrajat/async-cache)
- [Textual](https://github.com/textualize/textual/) Used for the amazing new graphical configurator
- [ssdp](https://github.com/codingjoe/ssdp) Used for auto discovery
# Projects using this proect
## Projects using this project
- [Home Assistant Addon](https://github.com/bertybuttface/addons/tree/main/isponsorblocktv)
# Contributing
## Contributing
1. Fork it (<https://github.com/dmunozv04/iSponsorBlockTV/fork>)
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
@@ -35,9 +51,8 @@ The last 5 videos' segments are cached to limit the number on queries on Sponsor
5. Create a new Pull Request
## Contributors
- [dmunozv04](https://github.com/dmunozv04) - creator and maintainer
- [HaltCatchFire](https://github.com/HaltCatchFire) - updated dependencies and improved skip logic
- [Oxixes](https://github.com/oxixes) - added support for channel whitelist and minor improvements
# License
## License
[![GNU GPLv3](https://www.gnu.org/graphics/gplv3-127x51.png)](https://www.gnu.org/licenses/gpl-3.0.en.html)

View File

@@ -8,6 +8,7 @@ import traceback
class DeviceListener:
def __init__(self, api_helper, config, screen_id, offset):
self.task: asyncio.Task = None
self.api_helper = api_helper
self.lounge_controller = ytlounge.YtLoungeApi(screen_id, config, api_helper)
self.offset = offset
@@ -53,12 +54,12 @@ class DeviceListener:
await lounge_controller.connect()
except:
pass
# print(f"Connected to device {lounge_controller.screen_name}")
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")
#print("Subscription ended")
except:
pass
@@ -77,9 +78,10 @@ class DeviceListener:
segments = []
if state.videoId:
segments = await self.api_helper.get_segments(state.videoId)
print(segments)
if state.state.value == 1 and segments: # Playing and has segments to skip
await self.time_to_segment(segments, state.currentTime, time_start)
if state.state.value == 1: # Playing
print(f"Playing {state.videoId} with {len(segments)} segments")
if segments: # If there are segments
await self.time_to_segment(segments, state.currentTime, time_start)
# Finds the next segment to skip to and skips to it
async def time_to_segment(self, segments, position, time_start):
@@ -108,13 +110,14 @@ 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
try:
self.task.cancel()
except Exception as e:
traceback.print_exc()
pass
async def finish(devices):
@@ -141,7 +144,6 @@ def main(config, debug):
loop.run_forever()
except KeyboardInterrupt as e:
print("Keyboard interrupt detected, cancelling tasks and exiting...")
traceback.print_exc()
loop.run_until_complete(finish(devices))
finally:
loop.run_until_complete(web_session.close())

View File

@@ -63,12 +63,15 @@ 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")
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")
create_task(self.mute(False, override=True))
else: # Seen multiple other adStates, assuming they are all ads
print("Ad has started, muting")
create_task(self.mute(True, override=True))
# Manages volume, useful since YouTube wants to know the volume when unmuting (even if they already have it)
elif event_type == "onVolumeChanged":
@@ -77,6 +80,7 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
# Gets segments for the next video before it starts playing
elif event_type == "autoplayUpNext":
if len(args) > 0 and (vid_id := args[0]["videoId"]): # if video id is not empty
print(f"Getting segments for next video: {vid_id}")
create_task(self.api_helper.get_segments(vid_id))
# #Used to know if an ad is skippable or not
@@ -84,6 +88,7 @@ class YtLoungeApi(pyytlounge.YtLoungeApi):
data = args[0]
# Gets segments for the next video (after the ad) before it starts playing
if vid_id := data["contentVideoId"]:
print(f"Getting segments for next video: {vid_id}")
create_task(self.api_helper.get_segments(vid_id))
if data["isSkippable"] == "true": # YouTube uses strings for booleans

View File

@@ -1,5 +1,5 @@
from iSponsorBlockTV import setup_wizard
from iSponsorBlockTV.helpers import Config
config = Config("config.json")
config = Config("data/config.json")
setup_wizard.main(config)