aboutsummaryrefslogtreecommitdiffstats
path: root/hypervideo_dl/postprocessor/sponsorblock.py
diff options
context:
space:
mode:
Diffstat (limited to 'hypervideo_dl/postprocessor/sponsorblock.py')
-rw-r--r--hypervideo_dl/postprocessor/sponsorblock.py29
1 files changed, 18 insertions, 11 deletions
diff --git a/hypervideo_dl/postprocessor/sponsorblock.py b/hypervideo_dl/postprocessor/sponsorblock.py
index 7943014..6ba87cd 100644
--- a/hypervideo_dl/postprocessor/sponsorblock.py
+++ b/hypervideo_dl/postprocessor/sponsorblock.py
@@ -1,9 +1,9 @@
-from hashlib import sha256
+import hashlib
import json
import re
+import urllib.parse
from .ffmpeg import FFmpegPostProcessor
-from ..compat import compat_urllib_parse_urlencode
class SponsorBlockPP(FFmpegPostProcessor):
@@ -14,6 +14,10 @@ class SponsorBlockPP(FFmpegPostProcessor):
POI_CATEGORIES = {
'poi_highlight': 'Highlight',
}
+ NON_SKIPPABLE_CATEGORIES = {
+ **POI_CATEGORIES,
+ 'chapter': 'Chapter',
+ }
CATEGORIES = {
'sponsor': 'Sponsor',
'intro': 'Intermission/Intro Animation',
@@ -23,7 +27,7 @@ class SponsorBlockPP(FFmpegPostProcessor):
'filler': 'Filler Tangent',
'interaction': 'Interaction Reminder',
'music_offtopic': 'Non-Music Section',
- **POI_CATEGORIES,
+ **NON_SKIPPABLE_CATEGORIES
}
def __init__(self, downloader, categories=None, api='https://sponsor.ajay.app'):
@@ -38,7 +42,7 @@ class SponsorBlockPP(FFmpegPostProcessor):
return [], info
self.to_screen('Fetching SponsorBlock segments')
- info['sponsorblock_chapters'] = self._get_sponsor_chapters(info, info['duration'])
+ info['sponsorblock_chapters'] = self._get_sponsor_chapters(info, info.get('duration'))
return [], info
def _get_sponsor_chapters(self, info, duration):
@@ -60,7 +64,8 @@ class SponsorBlockPP(FFmpegPostProcessor):
if duration and duration - start_end[1] <= 1:
start_end[1] = duration
# SponsorBlock duration may be absent or it may deviate from the real one.
- return s['videoDuration'] == 0 or not duration or abs(duration - s['videoDuration']) <= 1
+ diff = abs(duration - s['videoDuration']) if s['videoDuration'] else 0
+ return diff < 1 or (diff < 5 and diff / (start_end[1] - start_end[0]) < 0.05)
duration_match = [s for s in segments if duration_filter(s)]
if len(duration_match) != len(segments):
@@ -68,28 +73,30 @@ class SponsorBlockPP(FFmpegPostProcessor):
def to_chapter(s):
(start, end), cat = s['segment'], s['category']
+ title = s['description'] if cat == 'chapter' else self.CATEGORIES[cat]
return {
'start_time': start,
'end_time': end,
'category': cat,
- 'title': self.CATEGORIES[cat],
- '_categories': [(cat, start, end)]
+ 'title': title,
+ 'type': s['actionType'],
+ '_categories': [(cat, start, end, title)],
}
sponsor_chapters = [to_chapter(s) for s in duration_match]
if not sponsor_chapters:
- self.to_screen('No segments were found in the SponsorBlock database')
+ self.to_screen('No matching segments were found in the SponsorBlock database')
else:
self.to_screen(f'Found {len(sponsor_chapters)} segments in the SponsorBlock database')
return sponsor_chapters
def _get_sponsor_segments(self, video_id, service):
- hash = sha256(video_id.encode('ascii')).hexdigest()
+ hash = hashlib.sha256(video_id.encode('ascii')).hexdigest()
# SponsorBlock API recommends using first 4 hash characters.
- url = f'{self._API_URL}/api/skipSegments/{hash[:4]}?' + compat_urllib_parse_urlencode({
+ url = f'{self._API_URL}/api/skipSegments/{hash[:4]}?' + urllib.parse.urlencode({
'service': service,
'categories': json.dumps(self._categories),
- 'actionTypes': json.dumps(['skip', 'poi'])
+ 'actionTypes': json.dumps(['skip', 'poi', 'chapter'])
})
for d in self._download_json(url) or []:
if d['videoID'] == video_id: