Skip to content

Commit

Permalink
fixed stream padding to avoid timeline spoilers (#64)
Browse files Browse the repository at this point in the history
Co-authored-by: tonywagner <you@example.com>
  • Loading branch information
tonywagner and tonywagner authored Mar 22, 2024
1 parent 0772368 commit fbf1bfa
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 21 deletions.
4 changes: 2 additions & 2 deletions addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.mlbtv" name="MLB.TV®" version="2023.10.11+matrix.1" provider-name="eracknaphobia">
<addon id="plugin.video.mlbtv" name="MLB.TV®" version="2024.3.1+matrix.1" provider-name="eracknaphobia">
<requires>
<import addon="xbmc.python" version="3.0.0"/>
<import addon="script.module.pytz" />
Expand All @@ -22,7 +22,7 @@
</description>
<disclaimer lang="en_GB">Requires an MLB.tv account</disclaimer>
<news>
- improve settings type
- fixed stream padding to avoid timeline spoilers
</news>
<language>en</language>
<platform>all</platform>
Expand Down
15 changes: 8 additions & 7 deletions resources/lib/mlb.py
Original file line number Diff line number Diff line change
Expand Up @@ -961,17 +961,18 @@ def stream_select(game_pk, spoiler='True', suspended='False', start_inning='Fals
# if not live and no spoilers and not audio, generate a random number of segments to pad at end of proxy stream url
elif DISABLE_VIDEO_PADDING == 'false' and is_live is False and spoiler == 'False' and stream_type != 'audio':
pad = random.randint((3600 / SECONDS_PER_SEGMENT), (7200 / SECONDS_PER_SEGMENT))
headers += '&pad=' + str(pad)
stream_url = 'http://127.0.0.1:43670/' + stream_url
# pass padding as URL querystring parameter
stream_url = 'http://127.0.0.1:43670/' + stream_url + '?pad=' + str(pad)

# add alternate audio tracks, if necessary
# add extra alternate audio tracks, if necessary
if DISABLE_VIDEO_PADDING == 'false' and (alternate_english is not None or alternate_spanish is not None):
# pass any extra alternate audio tracks as URL querystring parameters
if not stream_url.startswith('http://127.0.0.1:43670/'):
stream_url = 'http://127.0.0.1:43670/' + stream_url + '?'
if alternate_english is not None:
headers += '&alternate_english=' + urllib.quote_plus(alternate_english)
stream_url += '&alternate_english=' + urllib.quote_plus(alternate_english)
if alternate_spanish is not None:
headers += '&alternate_spanish=' + urllib.quote_plus(alternate_spanish)
if not stream_url.startswith('http://127.0.0.1:43670/'):
stream_url = 'http://127.0.0.1:43670/' + stream_url
stream_url += '&alternate_spanish=' + urllib.quote_plus(alternate_spanish)

# valid stream url
if '.m3u8' in stream_url:
Expand Down
35 changes: 23 additions & 12 deletions service.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@
from http.server import BaseHTTPRequestHandler, HTTPServer
from socketserver import ThreadingMixIn
from urllib.parse import urljoin
from urllib.parse import urlparse
from urllib.parse import parse_qs
except:
# Python2
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn
from urlparse import urljoin
from urlparse import urlparse
from urlparse import parse_qs

HOST = '127.0.0.1'
PORT = 43670
Expand All @@ -31,7 +35,7 @@
URI_END_DELIMETER = '"'
KEY_TEXT = '-KEY:METHOD=AES-128'
ENDLIST_TEXT = '#EXT-X-ENDLIST'
REMOVE_IN_HEADERS = ['upgrade', 'host', 'pad', 'alternate_english', 'alternate_spanish']
REMOVE_IN_HEADERS = ['upgrade', 'host']
REMOVE_OUT_HEADERS = ['date', 'server', 'transfer-encoding', 'keep-alive', 'connection', 'content-length', 'content-range', 'content-md5', 'access-control-allow-credentials', 'content-encoding']

class RequestHandler(BaseHTTPRequestHandler):
Expand All @@ -45,23 +49,30 @@ def do_HEAD(self):
self.send_error(404)

def do_GET(self):
url = self.path.lstrip('/').strip('\\')
# parse path of the incoming request into components
parsed_url = urlparse(self.path.lstrip('/').strip('\\'))
# build our outgoing request URL without the querystring parameters
url = parsed_url.scheme + '://' + parsed_url.netloc + parsed_url.path
if not url.endswith(STREAM_EXTENSION):
self.send_error(404)

headers = {}
pad = 0
alternate_english = None
alternate_spanish = None

# parse the querystring parameters component
parsed_qs = parse_qs(parsed_url.query)
if 'pad' in parsed_qs:
pad = int(parsed_qs['pad'][0])
if 'alternate_english' in parsed_qs:
alternate_english = urllib.unquote_plus(parsed_qs['alternate_english'][0])
if 'alternate_spanish' in parsed_qs:
alternate_spanish = urllib.unquote_plus(parsed_qs['alternate_spanish'][0])

for key in self.headers:
if key.lower() not in REMOVE_IN_HEADERS:
headers[key] = self.headers[key]
elif key.lower() == 'pad':
pad = int(self.headers[key])
elif key.lower() == 'alternate_english':
alternate_english = urllib.unquote_plus(self.headers[key])
elif key.lower() == 'alternate_spanish':
alternate_spanish = urllib.unquote_plus(self.headers[key])

response = requests.get(url, headers=headers)

Expand All @@ -88,20 +99,20 @@ def do_GET(self):
url_split = line_split[1].split(URI_END_DELIMETER, 1)
absolute_url = urljoin(url, url_split[0])
if absolute_url.endswith(STREAM_EXTENSION) and not absolute_url.startswith(PROXY_URL):
absolute_url = PROXY_URL + absolute_url
absolute_url = PROXY_URL + absolute_url + '?' + parsed_url.query
new_line = line_split[0] + URI_START_DELIMETER + absolute_url + URI_END_DELIMETER + url_split[1]
new_line_array.append(new_line)
else:
new_line_array.append(line)
if line == '#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",LANGUAGE="en",NAME="English",AUTOSELECT=YES,DEFAULT=YES':
if alternate_english is not None:
new_line_array.append('#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",NAME="Alternate English",LANGUAGE="en",AUTOSELECT=YES,DEFAULT=NO,URI="' + PROXY_URL + alternate_english + '"')
new_line_array.append('#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",NAME="Alternate English",LANGUAGE="en",AUTOSELECT=YES,DEFAULT=NO,URI="' + PROXY_URL + alternate_english + '?' + parsed_url.query + '"')
if alternate_spanish is not None:
new_line_array.append('#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",NAME="Alternate Spanish",LANGUAGE="es",AUTOSELECT=YES,DEFAULT=NO,URI="' + PROXY_URL + alternate_spanish + '"')
new_line_array.append('#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="aac",NAME="Alternate Spanish",LANGUAGE="es",AUTOSELECT=YES,DEFAULT=NO,URI="' + PROXY_URL + alternate_spanish + '?' + parsed_url.query + '"')
elif line != '':
absolute_url = urljoin(url, line)
if absolute_url.endswith(STREAM_EXTENSION) and not absolute_url.startswith(PROXY_URL):
absolute_url = PROXY_URL + absolute_url
absolute_url = PROXY_URL + absolute_url + '?' + parsed_url.query
new_line_array.append(absolute_url)

# pad the end of the stream by the requested number of segments
Expand Down

0 comments on commit fbf1bfa

Please sign in to comment.