Skip to content

Commit d3badb5

Browse files
authored
Merge pull request #79 from anxdpanic/pr_isengard
fix playback
2 parents 454e7d5 + 5e80909 commit d3badb5

File tree

4 files changed

+53
-20
lines changed

4 files changed

+53
-20
lines changed

addon.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<addon id="script.module.python.twitch" name="python-twitch for Kodi" version="2.0.16~beta1" provider-name="anxdpanic, A Talented Community">
2+
<addon id="script.module.python.twitch" name="python-twitch for Kodi" version="2.0.16~beta2" provider-name="anxdpanic, A Talented Community">
33
<requires>
44
<import addon="xbmc.python" version="2.20.0"/>
55
<import addon="script.module.six" version="1.11.0"/>
@@ -9,6 +9,7 @@
99
<extension point="xbmc.addon.metadata">
1010
<platform>all</platform>
1111
<news>
12+
[fix] playback, change access token to use gql endpoints
1213
[chg] change followed, following, and unfollowing games to use gql endpoints
1314
</news>
1415
<assets>

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
2.0.16
2+
[fix] playback, change access token to use gql endpoints
23
[chg] change followed, following, and unfollowing games to use gql endpoints
34

45
2.0.15

resources/lib/twitch/api/usher.py

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from .. import keys
1717
from ..api.parameters import Boolean
1818
from ..parser import m3u8, clip_embed
19-
from ..queries import ClipsQuery, HiddenApiQuery, UsherQuery
19+
from ..queries import ClipsQuery, HiddenApiQuery, UsherQuery, GQLQuery
2020
from ..queries import query
2121
from ..log import log
2222

@@ -33,21 +33,35 @@ def valid_video_id(video_id):
3333

3434
@query
3535
def channel_token(channel, platform=keys.WEB, headers={}):
36-
q = HiddenApiQuery('channels/{channel}/access_token', headers=headers)
37-
q.add_urlkw(keys.CHANNEL, channel)
38-
q.add_param(keys.NEED_HTTPS, Boolean.TRUE)
39-
q.add_param(keys.PLATFORM, platform)
40-
q.add_param(keys.PLAYER_BACKEND, keys.MEDIAPLAYER)
36+
data = [{
37+
"operationName": "PlaybackAccessToken_Template",
38+
"query": "query PlaybackAccessToken_Template($login: String!, $isLive: Boolean!, $vodID: ID!, $isVod: Boolean!, $playerType: String!) { streamPlaybackAccessToken(channelName: $login, params: {platform: \"web\", playerBackend: \"mediaplayer\", playerType: $playerType}) @include(if: $isLive) { value signature __typename } videoPlaybackAccessToken(id: $vodID, params: {platform: \"web\", playerBackend: \"mediaplayer\", playerType: $playerType}) @include(if: $isVod) { value signature __typename }}",
39+
"variables": {
40+
"isLive": True,
41+
"login": channel,
42+
"isVod": False,
43+
"vodID": "",
44+
"playerType": "site"
45+
}
46+
}]
47+
q = GQLQuery('', headers=headers, data=data, use_token=True)
4148
return q
4249

4350

4451
@query
4552
def vod_token(video_id, platform=keys.WEB, headers={}):
46-
q = HiddenApiQuery('vods/{vod}/access_token', headers=headers)
47-
q.add_urlkw(keys.VOD, video_id)
48-
q.add_param(keys.NEED_HTTPS, Boolean.TRUE)
49-
q.add_param(keys.PLATFORM, platform)
50-
q.add_param(keys.PLAYER_BACKEND, keys.MEDIAPLAYER)
53+
data = [{
54+
"operationName": "PlaybackAccessToken_Template",
55+
"query": "query PlaybackAccessToken_Template($login: String!, $isLive: Boolean!, $vodID: ID!, $isVod: Boolean!, $playerType: String!) { streamPlaybackAccessToken(channelName: $login, params: {platform: \"web\", playerBackend: \"mediaplayer\", playerType: $playerType}) @include(if: $isLive) { value signature __typename } videoPlaybackAccessToken(id: $vodID, params: {platform: \"web\", playerBackend: \"mediaplayer\", playerType: $playerType}) @include(if: $isVod) { value signature __typename }}",
56+
"variables": {
57+
"isLive": False,
58+
"login": "",
59+
"isVod": True,
60+
"vodID": video_id,
61+
"playerType": "site"
62+
}
63+
}]
64+
q = GQLQuery('', headers=headers, data=data, use_token=True)
5165
return q
5266

5367

@@ -63,10 +77,13 @@ def live_request(channel, platform=keys.WEB, headers={}):
6377
if keys.ERROR in token:
6478
return token
6579
else:
80+
token = token[0][keys.DATA][keys.STREAM_PLAYBACK_ACCESS_TOKEN]
81+
signature = token[keys.SIGNATURE]
82+
access_token = token[keys.VALUE]
6683
q = UsherQuery('api/channel/hls/{channel}.m3u8', headers=headers)
6784
q.add_urlkw(keys.CHANNEL, channel)
68-
q.add_param(keys.SIG, token[keys.SIG].encode('utf-8'))
69-
q.add_param(keys.TOKEN, token[keys.TOKEN].encode('utf-8'))
85+
q.add_param(keys.SIG, signature.encode('utf-8'))
86+
q.add_param(keys.TOKEN, access_token.encode('utf-8'))
7087
q.add_param(keys.ALLOW_SOURCE, Boolean.TRUE)
7188
q.add_param(keys.ALLOW_SPECTRE, Boolean.TRUE)
7289
q.add_param(keys.ALLOW_AUDIO_ONLY, Boolean.TRUE)
@@ -84,10 +101,13 @@ def live_request(channel, platform=keys.WEB, headers={}):
84101

85102
@query
86103
def _live(channel, token, headers={}):
104+
token = token[0][keys.DATA][keys.STREAM_PLAYBACK_ACCESS_TOKEN]
105+
signature = token[keys.SIGNATURE]
106+
access_token = token[keys.VALUE]
87107
q = UsherQuery('api/channel/hls/{channel}.m3u8', headers=headers)
88108
q.add_urlkw(keys.CHANNEL, channel)
89-
q.add_param(keys.SIG, token[keys.SIG].encode('utf-8'))
90-
q.add_param(keys.TOKEN, token[keys.TOKEN].encode('utf-8'))
109+
q.add_param(keys.SIG, signature.encode('utf-8'))
110+
q.add_param(keys.TOKEN, access_token.encode('utf-8'))
91111
q.add_param(keys.ALLOW_SOURCE, Boolean.TRUE)
92112
q.add_param(keys.ALLOW_SPECTRE, Boolean.TRUE)
93113
q.add_param(keys.ALLOW_AUDIO_ONLY, Boolean.TRUE)
@@ -116,10 +136,13 @@ def video_request(video_id, platform=keys.WEB, headers={}):
116136
if keys.ERROR in token:
117137
return token
118138
else:
139+
token = token[0][keys.DATA][keys.VIDEO_PLAYBACK_ACCESS_TOKEN]
140+
signature = token[keys.SIGNATURE]
141+
access_token = token[keys.VALUE]
119142
q = UsherQuery('vod/{id}', headers=headers)
120143
q.add_urlkw(keys.ID, video_id)
121-
q.add_param(keys.NAUTHSIG, token[keys.SIG].encode('utf-8'))
122-
q.add_param(keys.NAUTH, token[keys.TOKEN].encode('utf-8'))
144+
q.add_param(keys.NAUTHSIG, signature.encode('utf-8'))
145+
q.add_param(keys.NAUTH, access_token.encode('utf-8'))
123146
q.add_param(keys.ALLOW_SOURCE, Boolean.TRUE)
124147
q.add_param(keys.ALLOW_AUDIO_ONLY, Boolean.TRUE)
125148
q.add_param(keys.CDM, keys.WV)
@@ -140,10 +163,13 @@ def video_request(video_id, platform=keys.WEB, headers={}):
140163

141164
@query
142165
def _vod(video_id, token, headers={}):
166+
token = token[0][keys.DATA][keys.VIDEO_PLAYBACK_ACCESS_TOKEN]
167+
signature = token[keys.SIGNATURE]
168+
access_token = token[keys.VALUE]
143169
q = UsherQuery('vod/{id}', headers=headers)
144170
q.add_urlkw(keys.ID, video_id)
145-
q.add_param(keys.NAUTHSIG, token[keys.SIG].encode('utf-8'))
146-
q.add_param(keys.NAUTH, token[keys.TOKEN].encode('utf-8'))
171+
q.add_param(keys.NAUTHSIG, signature.encode('utf-8'))
172+
q.add_param(keys.NAUTH, access_token.encode('utf-8'))
147173
q.add_param(keys.ALLOW_SOURCE, Boolean.TRUE)
148174
q.add_param(keys.ALLOW_AUDIO_ONLY, Boolean.TRUE)
149175
q.add_param(keys.CDM, keys.WV)

resources/lib/twitch/keys.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
COVER_IMAGE = 'cover_image'
4444
CURSOR = 'cursor'
4545
CLIENT_ID = 'client_id'
46+
DATA = 'data'
4647
DELAY = 'delay'
4748
DESCRIPTION = 'description'
4849
DIRECTION = 'direction'
@@ -94,11 +95,13 @@
9495
SCE_PLATFORM = 'sce_platform'
9596
SHARE = 'share'
9697
SIG = 'sig'
98+
SIGNATURE = 'signature'
9799
SLUG = 'slug'
98100
SORT = 'sort'
99101
SORT_BY = 'sortby'
100102
STARTED_AT = 'started_at'
101103
STATUS = 'status'
104+
STREAM_PLAYBACK_ACCESS_TOKEN = 'streamPlaybackAccessToken'
102105
STREAM_TYPE = 'stream_type'
103106
SUMMARY = 'summary'
104107
TAG_ID = 'tag_id'
@@ -119,7 +122,9 @@
119122
USER_ID = 'user_id'
120123
USER_LOGIN = 'user_login'
121124
UPLOAD_TOKEN = 'upload_token'
125+
VALUE = 'value'
122126
VIDEO_ID = 'video_id'
127+
VIDEO_PLAYBACK_ACCESS_TOKEN = 'videoPlaybackAccessToken'
123128
VOD = 'vod'
124129
WEB = 'web'
125130
WV = 'wv'

0 commit comments

Comments
 (0)