maxgalbu / xbmc.plugin.video.nba

Kodi plugin to watch NBA games with nba league pass

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Can't browse or play games

nre-ableton opened this issue · comments

With the 2020/21 season about to start, I've dusted off the NBA Kodi plugin only to sadly discover that I can't browse or stream any games from the 19/20 season. I am skeptical that the plugin will work for games in the upcoming season, but obviously we'll have to wait for pre-season to find out.

Here's the kodi.log output that I see when trying to browse an arbitrary game (in this case, game 5 of the bubble finals, which is pretty recent):

2020-12-05 11:37:12.594 T:2422203248   ERROR: Previous line repeats 451 times.
2020-12-05 11:37:12.595 T:2422203248   ERROR: EXCEPTION Thrown (PythonToCppException) : -->Python callback/script returned the following error<--
                                             - NOTE: IGNORING THIS CAN LEAD TO MEMORY LEAKS!
                                            Error Type: <type 'exceptions.KeyError'>
                                            Error Contents: 'gameState'
                                            Traceback (most recent call last):
                                              File "/storage/.kodi/addons/plugin.video.nba/main.py", line 12, in <module>
                                                from leaguepass import *
                                              File "/storage/.kodi/addons/plugin.video.nba/src/leaguepass.py", line 81, in <module>
                                                chooseGameVideoMenu()
                                              File "/storage/.kodi/addons/plugin.video.nba/src/games.py", line 320, in chooseGameVideoMenu
                                                game_state = game_data_json['gameState']
                                            KeyError: 'gameState'
                                            -->End of Python script error report<--
2020-12-05 11:37:12.697 T:2402284400   ERROR: GetDirectory - Error getting plugin://plugin.video.nba/?duration=10193000&end_time=1602301644000&has_away_feed=0&has_condensed_game=1&home_team=Lakers&mode=gamechoosevideo&name=2020-10-09%20Heat%20vs%20Lakers%20(game%205)&seo_name=20201009%2fMIALAL&start_time=1602291451000&url&video_id=0041900405&video_type=archive&visitor_team=Heat
2020-12-05 11:37:12.712 T:3011665936   ERROR: CGUIMediaWindow::GetDirectory(plugin://plugin.video.nba/?duration=10193000&end_time=1602301644000&has_away_feed=0&has_condensed_game=1&home_team=Lakers&mode=gamechoosevideo&name=2020-10-09%20Heat%20vs%20Lakers%20(game%205)&seo_name=20201009%2fMIALAL&start_time=1602291451000&url&video_id=0041900405&video_type=archive&visitor_team=Heat) failed
2020-12-05 11:37:13.354 T:2847540080   ERROR: EXCEPTION: XBMC is not playing any file

I'm guessing something has changed on the NBA's API that must be adapted in the plugin. I haven't really dug into the plugin sources though, so this is just speculation.

Also ping @ivankokan, who I guess is the de-facto maintainer these days.

I haven't used the plugin recently, so I don't know why browsing games doesn't work, but I know that the NBA has changed authentication method. Here is the snippet which I used to log in and get a game URL. Maybe it will help.

if __name__ == '__main__':
    # login
    username = '...'
    password = '...'
    headers = {'Content-Type': 'application/json', 'X-Client-Platform': 'web'}
    body = json.dumps({
        'email': username,
        'password': password,
        'rememberMe': False
    })
    body = body.encode('ascii')

    request = urllib.request.Request('https://identity.nba.com/api/v1/auth', body, headers)
    response = urllib.request.urlopen(request)
    content = response.read()
    json_content = json.loads(content)
    cookies = response.info()['Set-Cookie'].partition(';')[0]

    headers = {
        'Cookie': cookies,
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
    }

    esCustomerId = json_content['data']['user']['alternateIds']['endeavorCustomerId']
    body = {
        'format': 'json',
        'skus': 'true',
        'accesstoken': 'true',
        'esCustomerId': esCustomerId,
        'ciamlogin': 'true'
    }

    body = urlencode(body)
    body = body.encode('ascii')

    request = urllib.request.Request('https://watch.nba.com/secure/authenticate', body, headers)
    response = urllib.request.urlopen(request)
    content = response.read()
    json_content = json.loads(content)
    token = json_content['data']['accessToken']

    video_id = '0041900406'
    video_type = 'archive'
    gt = 1

    body = {
        'type': 'game',
        'extid': str(video_id),
        'drmtoken': True,
        'deviceid': 'blah',  # TODO
        'token': token,
        'gt': gt,
        'gs': 3,
        'cam': 16,
        'pcid': 'blah',
        'format': 'xml'
    }

    body = urlencode(body)
    body = body.encode('ascii')

    request = urllib.request.Request('https://nbaapi.neulion.com/api_nba/v1/publishpoint', body, headers)
    response = urllib.request.urlopen(request)
    content = response.read()

    xml = parseString(content)
    url = xml.getElementsByTagName("path")[0].childNodes[0].nodeValue
    drm = xml.getElementsByTagName("drmToken")[0].childNodes[0].nodeValue
    print (url)
    print (drm)

Yes getting a login error also

Hi. Please have patience, the fix is almost ready for the new season!

Awesome. Thanks in advance ivankokan

@ivankokan Sounds good! Please let us know if you need any help testing/hacking/etc. Thanks for all of your work as well.

@panpawel88 where i have to put this code to get url of the game , please can you help me

@ivankokan Awesome. Thank you.

@panpawel88 Thanks, I have been on the same track!

The fix is available within the master branch on my fork, enjoy the season!

Do not forget to update the e-mail address and the password in the Settings.

Thanks @ivankokan.... Will test this out. Appreciate you taking care of us year after year

@ivankokan unfortunately live games are not working - tested with the Nets game thats on right now
I get an HTTP error for archive games when browsing for them (choosing the season) but the games work when i play....so no issue on archives

Updated user/pass
Kodi 18.8 on the Nvidia Sheild

https://pastebin.com/3jMHyC83

Great work. Archive and TV work fine. Thank you so much!

Got caught with the new season record display, though! It is almost as if scrores are displayed, at least at the start of the season. I would prefer no season record or a way to switch that off.

Great work. Archive and TV work fine. Thank you so much!

Got caught with the new season record display, though! It is almost as if scrores are displayed, at least at the start of the season. I would prefer no season record or a way to switch that off.

At first: thanks to @ivankokan for this timely release :)

But I am really alarmed by anything that's looking like spoilers and immediately left the menu when I saw any numbers after the team names. I checked my apprehension and looked into older archived games and was confirmed. I would prefer to have this feature configurable.

For me I switched it off by applying this simple patch:

diff --git a/src/games.py b/src/games.py
index c3f1e19..14a9182 100644
--- a/src/games.py
+++ b/src/games.py
@@ -236,7 +236,7 @@ def addGamesLinks(date='', video_type="archive"):
                     if video_type == "live":
                         name = utils.toLocalTimezone(game_start_datetime_est).strftime("%Y-%m-%d (at %I:%M %p)")
 
-                    name += " %s (%s) vs %s (%s)" % (visitor_name, vr, host_name, hr)
+                    name += " %s vs %s" % (visitor_name, host_name)
 
                     if playoff_game_number != 0:
                         name += ' (game %d)' % (playoff_game_number)

@ivankokan unfortunately live games are not working - tested with the Nets game thats on right now
I get an HTTP error for archive games when browsing for them (choosing the season) but the games work when i play....so no issue on archives

Updated user/pass
Kodi 18.8 on the Nvidia Sheild

https://pastebin.com/3jMHyC83

@cablegoon True, live games were not OK last night. The log you provided does not help - you must enable debug logging. However, I have my own debug log to investigate today.

Great work. Archive and TV work fine. Thank you so much!

Got caught with the new season record display, though! It is almost as if scrores are displayed, at least at the start of the season. I would prefer no season record or a way to switch that off.

@Judge33 @sprotznock Will be resolved.

@ivankokan, any update about live games?

I made my own investigation and it seems that HLS is used as the adaptive streaming protocol for live games.

I made some adjustments to src/common.py and DAL-LAC game was started successfully. It's hard to say whether it will work for other cases.

PROTOCOLS = [
    {'protocol': 'mpd', 'extension': 'mpd', 'mimetype': 'application/dash+xml'},
    {'protocol': 'hls', 'extension': 'm3u8', 'mimetype': 'vnd.apple.mpegURL'}
]

DRM = 'com.widevine.alpha'  # TODO Handle other DRM_SCHEMES
LICENSE_URL = 'https://shield-twoproxy.imggaming.com/proxy'


def play(video):
    item = None
    if 'url' in video:
        item = xbmcgui.ListItem(path=video['url'])
        for protocol_info in PROTOCOLS:
            if '.%s' % protocol_info['extension'] in video['url']:
                from inputstreamhelper import Helper
                is_helper = Helper(protocol_info['protocol'], drm=DRM)
                if is_helper.check_inputstream():
                    item.setMimeType(protocol_info['mimetype'])
                    item.setContentLookup(False)
                    item.setProperty('inputstreamaddon', is_helper.inputstream_addon)  # TODO Kodi version dep
                    item.setProperty('inputstream.adaptive.manifest_type', protocol_info['protocol'])
                    item.setProperty('inputstream.adaptive.license_type', DRM)
                    item.setProperty('inputstream.adaptive.manifest_update_parameter', 'full')
                    license_key = '%s|authorization=bearer %s|R{SSM}|' % (LICENSE_URL, video['drm'])
                    item.setProperty('inputstream.adaptive.license_key', license_key)

    if item is not None:
        xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=item)

@panpawel88 Thanks for the investigation! I have made a PR with your patch here: ivankokan#11

@nre-ableton, thanks for the PR.

Yesterday, I tested my patch on other live games (BKN-CHA, SAS-NOP) and I was able to see a video, but there are still some things to fix:

  • I selected "Go LIVE" option for a single live game a few times, but it always started from the same position/segment. After a few seconds from the beginning, the playback has been stopped. I was able to resume video by seeking to a different position, but an audio was lost.
  • "Start from beginning" option doesn't work.

The fix is available within the master branch on my fork, enjoy the Live Games!

Do not forget to update the unified Show records and scores setting.

Start from Beginning / Go LIVE will be addressed accordingly very soon.

Thanks @panpawel88 @nre-ableton!

I'm closing this issue, since it has been effectively resolved.