Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ check-translations:
check-addon: build
@printf ">>> Running addon checks\n"
$(eval TMPDIR := $(shell mktemp -d))
@unzip dist/plugin.video.goplay-*.zip -d ${TMPDIR}
@unzip dist/plugin.video.play-*.zip -d ${TMPDIR}
cd ${TMPDIR} && kodi-addon-checker --branch=matrix
@rm -rf ${TMPDIR}

Expand Down
24 changes: 10 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
[![GitHub release](https://img.shields.io/github/v/release/add-ons/plugin.video.goplay?display_name=tag)](https://github.com/add-ons/plugin.video.goplay/releases)
[![Build Status](https://img.shields.io/github/actions/workflow/status/add-ons/plugin.video.goplay/ci.yml?branch=master)](https://github.com/add-ons/plugin.video.goplay/actions?query=branch%3Amaster)
[![Codecov status](https://img.shields.io/codecov/c/github/add-ons/plugin.video.goplay/master)](https://codecov.io/gh/add-ons/plugin.video.goplay/branch/master)
[![GitHub release](https://img.shields.io/github/v/release/add-ons/plugin.video.play?display_name=tag)](https://github.com/add-ons/plugin.video.play/releases)
[![Build Status](https://img.shields.io/github/actions/workflow/status/add-ons/plugin.video.play/ci.yml?branch=master)](https://github.com/add-ons/plugin.video.play/actions?query=branch%3Amaster)
[![Codecov status](https://img.shields.io/codecov/c/github/add-ons/plugin.video.play/master)](https://codecov.io/gh/add-ons/plugin.video.play/branch/master)
[![License: GPLv3](https://img.shields.io/badge/License-GPLv3-yellow.svg)](https://opensource.org/licenses/GPL-3.0)
[![Contributors](https://img.shields.io/github/contributors/add-ons/plugin.video.goplay.svg)](https://github.com/add-ons/plugin.video.goplay/graphs/contributors)
[![Contributors](https://img.shields.io/github/contributors/add-ons/plugin.video.play.svg)](https://github.com/add-ons/plugin.video.play/graphs/contributors)

# GoPlay Kodi add-on
# Play Kodi add-on

*plugin.video.goplay* is een Kodi add-on om de video-on-demand content van [GoPlay](https://www.goplay.be/) te bekijken. Hiervoor dien je eerst een
account op [goplay.be](https://www.goplay.be/) aan te maken.
*plugin.video.play* is een Kodi add-on om de video-on-demand content van [Play](https://www.play.tv/) te bekijken. Hiervoor dien je eerst een
account op [play.tv](https://www.play.tv/) aan te maken.

## Features

De volgende features worden ondersteund:
* Bekijk on-demand content van Play4, Play5, Play6, Play7 en Play Crime
* Bekijk on-demand content van Play, Play Fictie, Play Actie, Play Reality en Play Crime
* Doorzoeken van alle programma's

## Screenshots
Expand All @@ -26,9 +26,5 @@ De volgende features worden ondersteund:
</table>

## Changelog
## [v0.5.1](https://github.com/add-ons/plugin.video.goplay/tree/v0.5.1) (2024-10-21)
- Fix caching (@mediaminister)
- Add support for external Widevine device (@mediaminister)

## [v0.5.0](https://github.com/add-ons/plugin.video.goplay/tree/v0.5.0) (2024-09-11)
- Update to new GoPlay API (@mediaminister)
## [v0.6.0](https://github.com/add-ons/plugin.video.play/tree/v0.6.0) (2025-10-15)
- Play rebranding (@mediaminister)
19 changes: 8 additions & 11 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.goplay" name="GoPlay" version="0.5.1" provider-name="mediaminister">
<addon id="plugin.video.play" name="Play" version="0.6.0" provider-name="mediaminister">
<requires>
<import addon="xbmc.python" version="3.0.0"/>
<import addon="script.module.dateutil" version="2.8.1"/>
Expand All @@ -13,23 +13,20 @@
</extension>
<extension point="xbmc.service" library="service_entry.py"/>
<extension point="xbmc.addon.metadata">
<summary lang="nl_NL">Bekijk programma's van GoPlay.</summary>
<description lang="nl_NL">Deze add-on geeft toegang tot de programma's die aangeboden worden op Goplay.</description>
<summary lang="nl_NL">Bekijk programma's van Play.</summary>
<description lang="nl_NL">Deze add-on geeft toegang tot de programma's die aangeboden worden op Play.</description>
<disclaimer lang="nl_NL">Deze add-on wordt niet ondersteund door Play Media, en wordt aangeboden 'as is', zonder enige garantie. De logo's zijn eigendom van Play Media.</disclaimer>
<summary lang="en_GB">Watch content from GoPlay.</summary>
<description lang="en_GB">This add-on gives access to video-on-demand content available on GoPlay.</description>
<summary lang="en_GB">Watch content from Play.</summary>
<description lang="en_GB">This add-on gives access to video-on-demand content available on Play.</description>
<disclaimer lang="en_GB">This add-on is not officially commissioned/supported by Play Media and is provided 'as is' without any warranty of any kind. The logos are property of Play Media.</disclaimer>
<platform>all</platform>
<license>GPL-3.0-only</license>
<news>
v0.5.1 (2024-10-21)
- Fix caching
- Add support for external Widevine device
v0.6.0 (2025-10-15)
- Play rebranding

v0.5.0 (2024-09-11)
- Update to new GoPlay API
</news>
<source>https://github.com/add-ons/plugin.video.goplay</source>
<source>https://github.com/add-ons/plugin.video.play</source>
<assets>
<icon>resources/icon.png</icon>
<fanart>resources/fanart.png</fanart>
Expand Down
Binary file modified resources/fanart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified resources/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 0 additions & 7 deletions resources/lib/addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,6 @@ def show_search(query=None):
Search().show_search(query)


@routing.route('/play/live/<channel>')
def play_live(channel):
""" Play the requested item """
from resources.lib.modules.player import Player
Player().live(channel)


@routing.route('/play/catalog')
@routing.route('/play/catalog/<uuid>')
@routing.route('/play/catalog/<uuid>/<content_type>')
Expand Down
94 changes: 0 additions & 94 deletions resources/lib/goplay/__init__.py

This file was deleted.

4 changes: 2 additions & 2 deletions resources/lib/modules/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from urllib.parse import unquote_plus

from resources.lib import kodiutils
from resources.lib.goplay.auth import AuthApi
from resources.lib.goplay.content import CACHE_PREVENT, ContentApi, UnavailableException
from resources.lib.play.auth import AuthApi
from resources.lib.play.content import CACHE_PREVENT, ContentApi, UnavailableException
from resources.lib.modules.menu import Menu

_LOGGER = logging.getLogger(__name__)
Expand Down
10 changes: 5 additions & 5 deletions resources/lib/modules/channels.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import logging

from resources.lib import kodiutils
from resources.lib.goplay import STREAM_DICT
from resources.lib.goplay.auth import AuthApi
from resources.lib.goplay.content import ContentApi
from resources.lib.play import STREAM_DICT
from resources.lib.play.auth import AuthApi
from resources.lib.play.content import ContentApi

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -86,7 +86,7 @@ def show_channel_menu(self, uuid):
listing.append(
kodiutils.TitleItem(
title=kodiutils.localize(30055, channel=channel.title), # Catalog for {channel}
path=kodiutils.url_for('show_channel_catalog', channel=channel.title),
path=kodiutils.url_for('show_channel_catalog', channel=channel.brand.lower()),
art_dict={
'icon': 'DefaultMovieTitle.png',
'fanart': channel.fanart,
Expand All @@ -100,7 +100,7 @@ def show_channel_menu(self, uuid):
listing.append(
kodiutils.TitleItem(
title=kodiutils.localize(30052, channel=channel.title), # Watch live {channel}
path=kodiutils.url_for('play_live', channel=channel.uuid) + '?.pvr',
path=kodiutils.url_for('play_catalog', uuid=channel.uuid, content_type='live_channel') + '?.pvr',
art_dict={
'icon': channel.logo,
'fanart': channel.fanart,
Expand Down
43 changes: 23 additions & 20 deletions resources/lib/modules/iptvmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
from datetime import datetime, timedelta

from resources.lib import kodiutils
from resources.lib.goplay import CHANNELS
from resources.lib.goplay.epg import EpgApi
from resources.lib.play.auth import AuthApi
from resources.lib.play.content import ContentApi
from resources.lib.play.epg import EpgApi

_LOGGER = logging.getLogger(__name__)

Expand All @@ -17,6 +18,8 @@ class IPTVManager:
def __init__(self, port):
"""Initialize IPTV Manager object"""
self.port = port
auth = AuthApi(kodiutils.get_setting('username'), kodiutils.get_setting('password'), kodiutils.get_tokens_path())
self._api = ContentApi(auth, cache_path=kodiutils.get_cache_path())

def via_socket(func): # pylint: disable=no-self-argument
"""Send the output of the wrapped function to socket"""
Expand All @@ -28,49 +31,49 @@ def send(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('127.0.0.1', self.port))
try:
sock.sendall(json.dumps(func()).encode()) # pylint: disable=not-callable
sock.sendall(json.dumps(func(self)).encode()) # pylint: disable=not-callable
finally:
sock.close()

return send

@via_socket
def send_channels(): # pylint: disable=no-method-argument
def send_channels(self): # pylint: disable=no-method-argument
"""Return JSON-STREAMS formatted information to IPTV Manager"""
streams = []
for key, channel in CHANNELS.items():
if channel.get('iptv_id'):
channels = self._api.get_live_channels()
for channel in channels:
if channel.uuid:
streams.append({
'id': channel.get('iptv_id'),
'name': channel.get('name'),
'logo': 'special://home/addons/{addon}/resources/logos/{logo}'.format(addon=kodiutils.addon_id(),
logo=channel.get('logo')),
'preset': channel.get('iptv_preset'),
'stream': 'plugin://plugin.video.goplay/play/live/{channel}'.format(channel=key),
'vod': 'plugin://plugin.video.goplay/play/epg/{channel}/{{date}}'.format(channel=key)
'id': channel.uuid,
'name': channel.title,
'logo': channel.logo,
'stream': 'plugin://plugin.video.play/play/catalog/{uuid}/live_channel'.format(uuid=channel.uuid),
'vod': 'plugin://plugin.video.play/play/epg/{channel}/{{date}}'.format(channel=channel.uuid)
})

return {'version': 1, 'streams': streams}

@via_socket
def send_epg(): # pylint: disable=no-method-argument
def send_epg(self): # pylint: disable=no-method-argument
"""Return JSON-EPG formatted information to IPTV Manager"""
epg_api = EpgApi()

today = datetime.today()

results = {}
for key, channel in CHANNELS.items():
iptv_id = channel.get('iptv_id')
channels = self._api.get_live_channels()
for channel in channels:
uuid = channel.uuid

if channel.get('iptv_id'):
results[iptv_id] = []
if channel.uuid:
results[uuid] = []

for i in range(-3, 7):
date = today + timedelta(days=i)
epg = epg_api.get_epg(key, date.strftime('%Y-%m-%d'))
epg = epg_api.get_epg(channel.title.lower().split()[-1], date.strftime('%Y-%m-%d'))

results[iptv_id].extend([
results[uuid].extend([
{
'start': program.start.isoformat(),
'stop': (program.start + timedelta(seconds=program.duration)).isoformat(),
Expand Down
4 changes: 2 additions & 2 deletions resources/lib/modules/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
from urllib.parse import quote, quote_plus

from resources.lib import kodiutils
from resources.lib.goplay import STREAM_DICT
from resources.lib.goplay.content import Episode, Program
from resources.lib.play import STREAM_DICT
from resources.lib.play.content import Episode, Program
from resources.lib.kodiutils import TitleItem

_LOGGER = logging.getLogger(__name__)
Expand Down
28 changes: 3 additions & 25 deletions resources/lib/modules/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import logging

from resources.lib import kodiutils
from resources.lib.goplay.auth import AuthApi
from resources.lib.goplay.aws.cognito_idp import AuthenticationException, InvalidLoginException
from resources.lib.goplay.content import ApiException, ContentApi, GeoblockedException, MissingModuleException, UnavailableException
from resources.lib.play.auth import AuthApi
from resources.lib.play.aws.cognito_idp import AuthenticationException, InvalidLoginException
from resources.lib.play.content import ApiException, ContentApi, GeoblockedException, MissingModuleException, UnavailableException

_LOGGER = logging.getLogger(__name__)

Expand All @@ -22,28 +22,6 @@ def __init__(self):
# Workaround for Raspberry Pi 3 and older
kodiutils.set_global_setting('videoplayer.useomxplayer', True)

def live(self, uuid):
""" Play the live channel.
:type uuid: str
"""
# TODO: this doesn't work correctly, playing a live program from the PVR won't play something from the beginning
# Lookup current program
# broadcast = self._epg.get_broadcast(channel, datetime.datetime.now().isoformat())
# if broadcast and broadcast.video_url:
# self.play_from_page(broadcast.video_url)
# return
if "lay" in uuid: #Channel name from IPTV_manager => get uuid
try:
items = self._api.get_live_channels()
except Exception as ex:
kodiutils.notification(message=str(ex))
raise
channel = next(channel for channel in items if channel.title == uuid)
print(f"uuid entry is {uuid}")
uuid=channel.uuid

self.play(uuid, 'live_channel')

def play(self, uuid, content_type):
""" Play the requested item.
:type uuid: str
Expand Down
4 changes: 2 additions & 2 deletions resources/lib/modules/search.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
import logging

from resources.lib import kodiutils
from resources.lib.goplay.auth import AuthApi
from resources.lib.goplay.content import ContentApi
from resources.lib.play.auth import AuthApi
from resources.lib.play.content import ContentApi
from resources.lib.modules.menu import Menu

_LOGGER = logging.getLogger(__name__)
Expand Down
Loading