├── LICENSE ├── README.md ├── build ├── arch │ └── PKGBUILD ├── build-deb.sh ├── debian │ ├── control │ ├── copyright │ └── postinst ├── mac │ ├── TVDemon.spec │ └── tvdemon.icns └── win │ ├── BUILD.md │ ├── TVDemon.spec │ ├── tvdemon.ico │ └── tvdemon.py ├── po ├── tvdemon-be.po ├── tvdemon-de.po └── tvdemon-ru.po ├── tvdemon.desktop ├── tvdemon.py └── usr ├── bin └── tvdemon ├── lib └── tvdemon │ ├── __init__.py │ ├── app │ ├── __init__.py │ ├── common.py │ ├── epg.py │ ├── madia.py │ ├── main.py │ ├── settings.py │ ├── ui.py │ └── xtream.py │ └── tvdemon.py └── share ├── applications └── tvdemon.desktop ├── icons └── hicolor │ └── scalable │ └── apps │ └── tvdemon.svg ├── locale ├── be │ └── LC_MESSAGES │ │ └── tvdemon.mo ├── de │ └── LC_MESSAGES │ │ └── tvdemon.mo └── ru │ └── LC_MESSAGES │ └── tvdemon.mo └── tvdemon ├── app.ui ├── channel_widget.ui ├── epg.ui ├── favorites.ui ├── favorites_group_widget.ui ├── flow_channel_widget.ui ├── group_widget.ui ├── media_bar.ui ├── pictures ├── badges │ ├── README │ ├── afghanistan.svg │ ├── albania.svg │ ├── algeria.svg │ ├── andorra.svg │ ├── angola.svg │ ├── argentina.svg │ ├── armenia.svg │ ├── australia.svg │ ├── austria.svg │ ├── bahrain.svg │ ├── bangladesh.svg │ ├── barbados.svg │ ├── belarus.svg │ ├── belgium.svg │ ├── botswana.svg │ ├── brazil.svg │ ├── bulgaria.svg │ ├── cameroon.svg │ ├── canada.svg │ ├── chile.svg │ ├── china.svg │ ├── colombia.svg │ ├── costarica.svg │ ├── croatia.svg │ ├── cuba.svg │ ├── cyprus.svg │ ├── czech.svg │ ├── de.svg │ ├── denmark.svg │ ├── ecuador.svg │ ├── egypt.svg │ ├── en.svg │ ├── es.svg │ ├── esperanto.svg │ ├── estonia.svg │ ├── ethiopia.svg │ ├── europe.svg │ ├── finland.svg │ ├── fr.svg │ ├── france.svg │ ├── georgia.svg │ ├── germany.svg │ ├── ghana.svg │ ├── greece.svg │ ├── honduras.svg │ ├── hongkong.svg │ ├── hungary.svg │ ├── iceland.svg │ ├── india.svg │ ├── indonesia.svg │ ├── irak.svg │ ├── iran.svg │ ├── iraq.svg │ ├── ireland.svg │ ├── israel.svg │ ├── it.svg │ ├── italy.svg │ ├── ivory.svg │ ├── jamaica.svg │ ├── japan.svg │ ├── kenya.svg │ ├── korea.svg │ ├── kuweit.svg │ ├── laos.svg │ ├── latvia.svg │ ├── lebanon.svg │ ├── liechtenstein.svg │ ├── lithuania.svg │ ├── luxembourg.svg │ ├── lybia.svg │ ├── malaysia.svg │ ├── malta.svg │ ├── marino.svg │ ├── mexico.svg │ ├── monaco.svg │ ├── morocco.svg │ ├── movies.svg │ ├── mozambique.svg │ ├── music.svg │ ├── namibia.svg │ ├── nepal.svg │ ├── netherlands.svg │ ├── news.svg │ ├── newzealand.svg │ ├── nicaragua.svg │ ├── nigeria.svg │ ├── norway.svg │ ├── pakistan.svg │ ├── panama.svg │ ├── paraguay.svg │ ├── peru.svg │ ├── philippines.svg │ ├── poland.svg │ ├── portugal.svg │ ├── romania.svg │ ├── russia.svg │ ├── rw.svg │ ├── saudi.svg │ ├── scotland.svg │ ├── senegal.svg │ ├── serbia.svg │ ├── singapore.svg │ ├── slovakia.svg │ ├── slovenia.svg │ ├── south-africa.svg │ ├── spain.svg │ ├── sweden.svg │ ├── switzerland.svg │ ├── syria.svg │ ├── taiwan.svg │ ├── tanzania.svg │ ├── thailand.svg │ ├── togo.svg │ ├── tunisia.svg │ ├── turkey.svg │ ├── uganda.svg │ ├── uk.svg │ ├── ukraine.svg │ ├── uruguay.svg │ ├── usa.svg │ ├── uzbekistan.svg │ ├── venezuela.svg │ ├── vietnam.svg │ ├── wales.svg │ ├── yemen.svg │ ├── zambia.svg │ └── zimbabwe.svg ├── movies.svg ├── series.svg └── tv.svg ├── preferences.ui ├── provider_properties_widget.ui ├── provider_widget.ui ├── question_dialog.ui ├── shortcuts.ui └── style.css /README.md: -------------------------------------------------------------------------------- 1 | ## Project switched to **Gtk4** and [Libadwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/index.html). 2 | ### *Under development...* 3 | 4 | # TVDemon 5 | ### TVDemon based on [Hypnotix](https://github.com/linuxmint/hypnotix). 6 | This is an IPTV streaming application with support for live TV, movies and series. 7 | ![TVDemon](https://raw.githubusercontent.com/DYefremov/TVDemon/gh-pages/assets/TVDemon.png) 8 | It can support multiple IPTV providers of the following types: 9 | 10 | - M3U URL 11 | - Xtream API 12 | - Local M3U playlist 13 | 14 | ## Differences from [Hypnotix](https://github.com/linuxmint/hypnotix) 15 | * GUI redesign. Developed using Gtk4 and [Libadwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/). 16 | * [GStreamer](https://gstreamer.freedesktop.org/) as default media library. 17 | * Can be run without installation. 18 | * Ability to run on *macOS* and *MS Windows* (via [MSYS2](https://www.msys2.org/) platform). 19 | 20 | ## Requirements 21 | - Gtk4 >= 4.12 22 | - [Libadwaita](https://gnome.pages.gitlab.gnome.org/libadwaita/) >= 1.4 23 | - Python >= 3.11 24 | - PyGObject (pygobject3) 25 | - Requests (python3-request) 26 | - [GStreamer](https://gstreamer.freedesktop.org/) with Gtk4 plugin (gst-plugin-gtk4). 27 | 28 | ## Installation and Launch 29 | * ### Linux 30 | To start the program, in most cases it is enough to download the [archive](https://github.com/DYefremov/TVDemon/archive/refs/heads/main.zip), 31 | unpack and run it by double-clicking on the *.desktop file in the root directory, 32 | or launch from the console with the command:```./tvdemon.py``` 33 | Depending on your distro, you may need to install additional packages and libraries. 34 | 35 | To create a Debian package, you can use the *build-deb.sh* file from the *build* directory. 36 | 37 | * ### macOS (experimental) 38 | To run the program on macOS, you need to install [Homebrew](https://brew.sh/). 39 | Then install the required components via terminal: 40 | `brew install python3 gtk+4 libadwaita pygobject3 adwaita-icon-theme python-requests gstreamer` 41 | 42 | Launch is similar to Linux. 43 | 44 | 45 | * ### MS Windows (experimental) 46 | Windows users can also run (build) this program. 47 | One way is the [MSYS2](https://www.msys2.org/) platform. You can use [this](https://github.com/DYefremov/TVDemon/blob/main/build/win/BUILD.md) quick guide. 48 | 49 | ## TV Channels and media content 50 | 51 | TVDemon does not provide content or TV channels, it is a player application which streams from IPTV providers. 52 | 53 | By default, TVDemon is configured with one IPTV provider called Free-TV: https://github.com/Free-TV/IPTV. 54 | 55 | ### Issues relating to TV channels and media content should be addressed directly to the relevant provider. 56 | 57 | Note: Feel free to remove Free-TV from TVDemon if you don't use it, or add any other provider you may have access to or local M3U playlists. 58 | 59 | ## License 60 | 61 | - Code: GPLv3 62 | - Flags: https://github.com/linuxmint/flags 63 | - Icons on the landing page: CC BY-ND 2.0 -------------------------------------------------------------------------------- /build/arch/PKGBUILD: -------------------------------------------------------------------------------- 1 | # Maintainer: Dmitriy Yefremov 2 | 3 | pkgname=TVDemon-git 4 | pkgver=2.0.0 5 | pkgrel=1 6 | pkgdesc="An IPTV streaming application with support for live TV, movies and series." 7 | arch=('any') 8 | url="https://github.com/DYefremov/TVDemon" 9 | license=('GPL3') 10 | source=("git+$url.git") 11 | sha256sums=('SKIP') 12 | 13 | depends=( 14 | 'gtk4>=4.12' 15 | 'libadwaita>=1.15' 16 | 'python>=3.11' 17 | 'hicolor-icon-theme' 18 | 'python-gobject' 19 | 'python-requests' 20 | 'gstreamer' 21 | 'gst-plugins-base' 22 | 'gst-plugins-good' 23 | 'gst-plugins-bad' 24 | 'gst-plugin-gtk4' 25 | 'gst-libav' 26 | ) 27 | 28 | package() { 29 | cd ${pkgname/-git} 30 | cp -r usr/ "$pkgdir/" 31 | } 32 | -------------------------------------------------------------------------------- /build/build-deb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | VER="2.0.0-Alpha2" 3 | B_PATH="dist/TVDemon" 4 | 5 | mkdir -p $B_PATH 6 | cp -TRv debian "$B_PATH/DEBIAN" 7 | rsync --exclude=__pycache__ -arv ../usr "$B_PATH" 8 | 9 | cd dist 10 | dpkg-deb --build TVDemon 11 | mv TVDemon.deb TVDemon-$VER.deb 12 | 13 | rm -R TVDemon 14 | -------------------------------------------------------------------------------- /build/debian/control: -------------------------------------------------------------------------------- 1 | Package: tvdemon 2 | Version: 2.0.0-Alpha2 3 | Section: video 4 | Priority: optional 5 | Maintainer: Dmitriy Yefremov 6 | Build-Depends: debhelper (>= 10) 7 | Rules-Requires-Root: no 8 | Architecture: all 9 | Standards-Version: 4.1.2 10 | Depends: python3 (>= 3.11), 11 | python3-requests, 12 | python3-chardet, 13 | libgtk-4-1 (>= 4.12), 14 | libadwaita-1-0 (>= 1.4), 15 | gir1.2-gtk-4.0, 16 | gir1.2-adw-1, 17 | gir1.2-gst-plugins-bad-1.0, 18 | gstreamer1.0-plugins-bad, 19 | gstreamer1.0-gtk4 20 | Description: IPTV Player 21 | Watch TV by streaming from M3U sources. 22 | -------------------------------------------------------------------------------- /build/debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Source: https://github.com/DYefremov/TVDemon 3 | 4 | Files: * 5 | Copyright: 2020 Linux Mint 6 | 2022-2025 Dmitriy Yefremov 7 | 8 | License: GPL-3+ 9 | This program is free software; you can redistribute it and/or modify 10 | it under the terms of the GNU General Public License as published by 11 | the Free Software Foundation; either version 3 of the License, or 12 | (at your option) any later version. 13 | . 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | . 19 | On Debian systems, the complete text of the GNU General 20 | Public License can be found in `/usr/share/common-licenses/GPL' 21 | -------------------------------------------------------------------------------- /build/debian/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | case "$1" in 5 | configure) 6 | if which glib-compile-schemas >/dev/null 2>&1 7 | then 8 | glib-compile-schemas /usr/share/glib-2.0/schemas 9 | fi 10 | ;; 11 | 12 | abort-upgrade|abort-remove|abort-deconfigure) 13 | 14 | ;; 15 | 16 | *) 17 | echo "postinst called with unknown argument \`$1'" >&2 18 | exit 1 19 | ;; 20 | esac 21 | -------------------------------------------------------------------------------- /build/mac/TVDemon.spec: -------------------------------------------------------------------------------- 1 | import os 2 | import datetime 3 | import distutils.util 4 | 5 | EXE_NAME = 'tvdemon.py' 6 | DIR_PATH = os.getcwd() 7 | COMPILING_PLATFORM = distutils.util.get_platform() 8 | PATH_EXE = [os.path.join(DIR_PATH, EXE_NAME)] 9 | STRIP = True 10 | BUILD_DATE = datetime.datetime.now().strftime("%y%m%d") 11 | 12 | block_cipher = None 13 | 14 | excludes = [] 15 | 16 | ui_files = [('usr/share/tvdemon', 'share/tvdemon'), 17 | ('usr/share/icons/hicolor/scalable/apps/tvdemon.svg', 18 | 'share/icons/hicolor/scalable/apps')] 19 | 20 | a = Analysis([EXE_NAME], 21 | pathex=PATH_EXE, 22 | binaries=None, 23 | datas=ui_files, 24 | hiddenimports=[], 25 | hookspath=[], 26 | runtime_hooks=[], 27 | hooksconfig={ 28 | "gi": { 29 | "languages": ["en", "be", "de", "ru"], 30 | "module-versions": { 31 | "Gtk": "4.0" 32 | }, 33 | "gstreamer": { 34 | "exclude_plugins": ["opencv"], 35 | }, 36 | }, 37 | }, 38 | excludes=excludes, 39 | win_no_prefer_redirects=False, 40 | win_private_assemblies=False, 41 | cipher=block_cipher) 42 | 43 | pyz = PYZ(a.pure, 44 | a.zipped_data, 45 | cipher=block_cipher) 46 | 47 | exe = EXE(pyz, 48 | a.scripts, 49 | exclude_binaries=True, 50 | name='TVDemon', 51 | debug=False, 52 | strip=STRIP, 53 | upx=False, 54 | console=False) 55 | 56 | coll = COLLECT(exe, 57 | a.binaries, 58 | a.zipfiles, 59 | a.datas, 60 | strip=STRIP, 61 | upx=False, 62 | name='TVDemon') 63 | 64 | app = BUNDLE(coll, 65 | name='TVDemon.app', 66 | icon='tvdemon.icns', 67 | bundle_identifier=None, 68 | info_plist={ 69 | 'NSPrincipalClass': 'NSApplication', 70 | 'CFBundleName': 'TVDemon', 71 | 'CFBundleDisplayName': 'TVDemon', 72 | 'CFBundleGetInfoString': "IPTV Player", 73 | 'LSApplicationCategoryType': 'public.app-category.video', 74 | 'LSMinimumSystemVersion': '14.3.1', 75 | 'CFBundleShortVersionString': f"2.0.0.{BUILD_DATE} Alpha2", 76 | 'NSHumanReadableCopyright': u"Copyright © 2024, Dmitriy Yefremov", 77 | 'NSRequiresAquaSystemAppearance': 'False', 78 | 'NSHighResolutionCapable': 'True' 79 | }) 80 | -------------------------------------------------------------------------------- /build/mac/tvdemon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DYefremov/TVDemon/098d418348f1d23665f1ffcde973c8b39833c436/build/mac/tvdemon.icns -------------------------------------------------------------------------------- /build/win/BUILD.md: -------------------------------------------------------------------------------- 1 | ## Launch 2 | 1. Download and install the [MSYS2](https://www.msys2.org/) platform as described [here](https://www.msys2.org/) up to point 4. 3 | 2. Start **mingw64** shell. 4 | ![mingw64](https://user-images.githubusercontent.com/7511379/161400639-898ceb10-7de8-4557-bde1-25fe32bdfb03.png) 5 | 3. Run command `pacman -Suy` After that, you may need to restart the terminal and re-run the update command. 6 | 4. Install minimal required packages: 7 | `pacman -S mingw-w64-x86_64-gtk4 mingw-w64-x86_64-libadwaita mingw-w64-x86_64-python3 mingw-w64-x86_64-python3-gobject mingw-w64-x86_64-python-requests` 8 | 5. Install GStreamer and plugins: 9 | `pacman -S mingw-w64-x86_64-gstreamer mingw-w64-x86_64-gst-plugins-base mingw-w64-x86_64-gst-plugins-good mingw-w64-x86_64-gst-plugins-bad mingw-w64-x86_64-gtk4-media-gstreamer mingw-w64-x86_64-gst-plugins-rs` 10 | 6. Download and unzip the archive with sources from preferred branch (e.g. [main](https://github.com/DYefremov/TVDemon/archive/refs/heads/main.zip)) in to folder where MSYS2 is installed. E.g: `c:\msys64\home\username\` 11 | 7. Run mingw64 shell. Go to the folder where the program was unpacked. E.g: `cd TVDemon` 12 | And run: `./tvdemon.py` 13 | 14 | ## Building a package 15 | To build a standalone package, we can use [PyInstaller](https://pyinstaller.readthedocs.io/en/stable/). 16 | 1. Launch *mingw64* shell. 17 | 2. Install [UPX](https://upx.github.io/) (**optional**) via command: `pacman -S upx`. 18 | 3. Install *[PyInstaller](https://pyinstaller.org)* : `pacman -S mingw-w64-x86_64-pyinstaller` 19 | 4. Go to the folder where the program was unpacked. E.g: `c:\msys64\home\username\TVDemon` 20 | 5. Сopy and replace the files from the */build/win/* folder to the root . 21 | 6. Go to the folder with the program in the running terminal: `cd TVDemon` 22 | 7. Give the following command: `pyinstaller.exe TVDemon.spec` 23 | 8. Wait until the operation end. In the *dist* folder you will find a ready-made build. 24 | -------------------------------------------------------------------------------- /build/win/TVDemon.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python ; coding: utf-8 -*- 2 | 3 | EXE_NAME = 'tvdemon.py' 4 | DIR_PATH = os.getcwd() 5 | PATH_EXE = [os.path.join(DIR_PATH, EXE_NAME)] 6 | 7 | block_cipher = None 8 | 9 | 10 | excludes = ['youtube_dl', 11 | 'tkinter'] 12 | 13 | ui_files = [('usr\\share\\tvdemon', 'share\\tvdemon'), 14 | ('usr\\share\\icons\\hicolor\\scalable\\apps\\tvdemon.svg', 15 | 'share\\icons\\hicolor\\scalable\\apps')] 16 | 17 | 18 | a = Analysis([EXE_NAME], 19 | pathex=PATH_EXE, 20 | binaries=[('C:\\msys64\\mingw64\\lib\\gio\\modules\\*', 'lib\\gio\\modules')], 21 | datas=ui_files, 22 | hiddenimports=[], 23 | hookspath=[], 24 | runtime_hooks=[], 25 | hooksconfig={ 26 | "gi": { 27 | "module-versions": { 28 | "Gtk": "4.0" 29 | }, 30 | }, 31 | }, 32 | excludes=excludes, 33 | win_no_prefer_redirects=False, 34 | win_private_assemblies=False, 35 | cipher=block_cipher, 36 | noarchive=False) 37 | pyz = PYZ(a.pure, a.zipped_data, 38 | cipher=block_cipher) 39 | exe = EXE(pyz, 40 | a.scripts, 41 | [], 42 | exclude_binaries=True, 43 | name='TVDemon', 44 | debug=False, 45 | bootloader_ignore_signals=False, 46 | contents_directory='.', 47 | strip=False, 48 | upx=True, 49 | console=False, 50 | icon='tvdemon.ico') 51 | coll = COLLECT(exe, 52 | a.binaries, 53 | a.zipfiles, 54 | a.datas, 55 | strip=False, 56 | upx=True, 57 | upx_exclude=[], 58 | name='TVDemon') 59 | -------------------------------------------------------------------------------- /build/win/tvdemon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DYefremov/TVDemon/098d418348f1d23665f1ffcde973c8b39833c436/build/win/tvdemon.ico -------------------------------------------------------------------------------- /build/win/tvdemon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"): 7 | from multiprocessing import freeze_support 8 | 9 | os.environ["GIO_EXTRA_MODULES"] = os.path.join(sys._MEIPASS, "lib", "gio", "modules") 10 | freeze_support() 11 | 12 | from usr.lib.tvdemon.app.main import run_app 13 | 14 | run_app() 15 | -------------------------------------------------------------------------------- /po/tvdemon-de.po: -------------------------------------------------------------------------------- 1 | # German translation for linuxmint 2 | # Copyright (c) 2020 Rosetta Contributors and Canonical Ltd 2020 3 | # This file is distributed under the same license as the linuxmint package. 4 | # FIRST AUTHOR , 2020. 5 | # 6 | msgid "" 7 | msgstr "" 8 | "Project-Id-Version: linuxmint\n" 9 | "Report-Msgid-Bugs-To: FULL NAME \n" 10 | "POT-Creation-Date: 2021-11-23 12:21+0000\n" 11 | "PO-Revision-Date: 2021-11-23 15:01+0000\n" 12 | "Last-Translator: Tobias Bannert \n" 13 | "Language-Team: German \n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Plural-Forms: nplurals=2; plural=n != 1;\n" 18 | "X-Launchpad-Export-Date: 2022-07-24 09:43+0000\n" 19 | "X-Generator: Launchpad (build 025a39fd866a641b6ae33074cda0d02a2c712d38)\n" 20 | 21 | #: usr/lib/tvdemon/app.py:119 usr/lib/tvdemon/app.py:696 22 | #: usr/lib/tvdemon/app.py:1214 generate_desktop_files:25 23 | #: usr/share/tvdemon/app.ui.h:1 24 | msgid "TVDemon" 25 | msgstr "TVDemon" 26 | 27 | #: usr/lib/tvdemon/app.py:238 usr/share/tvdemon/shortcuts.ui.h:6 28 | msgid "Keyboard Shortcuts" 29 | msgstr "Tastenkombinationen" 30 | 31 | #: usr/lib/tvdemon/app.py:245 usr/share/tvdemon/app.ui.h:35 32 | #: usr/share/tvdemon/shortcuts.ui.h:3 33 | msgid "Stream Information" 34 | msgstr "Stream-Informationen" 35 | 36 | #: usr/lib/tvdemon/app.py:253 usr/lib/tvdemon/app.py:1213 37 | #: usr/share/tvdemon/shortcuts.ui.h:2 38 | msgid "About" 39 | msgstr "Info" 40 | 41 | #: usr/lib/tvdemon/app.py:258 usr/share/tvdemon/shortcuts.ui.h:8 42 | msgid "Quit" 43 | msgstr "Beenden" 44 | 45 | #: usr/lib/tvdemon/app.py:271 46 | msgid "M3U URL" 47 | msgstr "M3U-Adresse" 48 | 49 | #: usr/lib/tvdemon/app.py:272 50 | msgid "Local M3U File" 51 | msgstr "Lokale M3U-Datei" 52 | 53 | #: usr/lib/tvdemon/app.py:273 54 | msgid "Xtream API" 55 | msgstr "Xtream-API" 56 | 57 | #: usr/lib/tvdemon/app.py:451 58 | #, python-format 59 | msgid "Season %s" 60 | msgstr "Staffel %s" 61 | 62 | #: usr/lib/tvdemon/app.py:461 63 | #, python-format 64 | msgid "Episode %s" 65 | msgstr "Episode %s" 66 | 67 | #: usr/lib/tvdemon/app.py:601 68 | msgid "No provider selected" 69 | msgstr "Kein Anbieter ausgewählt" 70 | 71 | #: usr/lib/tvdemon/app.py:623 usr/lib/tvdemon/app.py:636 72 | msgid "TV Channels" 73 | msgstr "Fernsehkanäle" 74 | 75 | #: usr/lib/tvdemon/app.py:626 usr/lib/tvdemon/app.py:651 76 | msgid "Movies" 77 | msgstr "Filme" 78 | 79 | #: usr/lib/tvdemon/app.py:628 usr/lib/tvdemon/app.py:658 80 | msgid "Series" 81 | msgstr "Serien" 82 | 83 | #: usr/lib/tvdemon/app.py:639 84 | #, python-format 85 | msgid "TV Channels > %s" 86 | msgstr "Fernsehkanäle > %s" 87 | 88 | #: usr/lib/tvdemon/app.py:654 89 | #, python-format 90 | msgid "Movies > %s" 91 | msgstr "Filme > %s" 92 | 93 | #: usr/lib/tvdemon/app.py:661 94 | #, python-format 95 | msgid "Series > %s" 96 | msgstr "Serien > %s" 97 | 98 | #: usr/lib/tvdemon/app.py:669 usr/share/tvdemon/app.ui.h:6 99 | msgid "Preferences" 100 | msgstr "Einstellungen" 101 | 102 | #: usr/lib/tvdemon/app.py:673 usr/share/tvdemon/app.ui.h:5 103 | msgid "Providers" 104 | msgstr "Anbieter" 105 | 106 | #: usr/lib/tvdemon/app.py:678 107 | #, python-format 108 | msgid "Edit %s" 109 | msgstr "%s bearbeiten" 110 | 111 | #: usr/lib/tvdemon/app.py:680 112 | msgid "Add a new provider" 113 | msgstr "Neuen Anbieter hinzufügen" 114 | 115 | #: usr/lib/tvdemon/app.py:684 116 | #, python-format 117 | msgid "Delete %s" 118 | msgstr "%s löschen" 119 | 120 | #: usr/lib/tvdemon/app.py:688 121 | msgid "Reset providers" 122 | msgstr "Anbieter zurücksetzen" 123 | 124 | #: usr/lib/tvdemon/app.py:726 usr/lib/tvdemon/app.py:730 125 | #: usr/lib/tvdemon/app.py:782 usr/lib/tvdemon/app.py:784 126 | #: usr/lib/tvdemon/app.py:791 usr/lib/tvdemon/app.py:794 127 | #: usr/lib/tvdemon/app.py:806 usr/lib/tvdemon/app.py:819 128 | #: usr/lib/tvdemon/app.py:824 usr/lib/tvdemon/app.py:832 129 | #: usr/lib/tvdemon/app.py:1166 usr/lib/tvdemon/app.py:1168 130 | #: usr/lib/tvdemon/app.py:1193 usr/lib/tvdemon/app.py:1197 131 | #: usr/share/tvdemon/app.ui.h:36 132 | msgid "General" 133 | msgstr "Allgemein" 134 | 135 | #: usr/lib/tvdemon/app.py:727 usr/lib/tvdemon/app.py:796 136 | #: usr/lib/tvdemon/app.py:798 usr/lib/tvdemon/app.py:800 137 | #: usr/lib/tvdemon/app.py:1167 usr/share/tvdemon/app.ui.h:38 138 | msgid "Color" 139 | msgstr "Farbe" 140 | 141 | #: usr/lib/tvdemon/app.py:731 usr/lib/tvdemon/app.py:816 142 | #: usr/lib/tvdemon/app.py:826 usr/lib/tvdemon/app.py:1169 143 | #: usr/share/tvdemon/app.ui.h:40 144 | msgid "Layout" 145 | msgstr "Ansicht" 146 | 147 | #: usr/lib/tvdemon/app.py:767 usr/lib/tvdemon/app.py:768 148 | #: usr/lib/tvdemon/app.py:782 usr/lib/tvdemon/app.py:784 149 | #: usr/lib/tvdemon/app.py:1189 usr/lib/tvdemon/app.py:1190 150 | #: usr/lib/tvdemon/app.py:1193 usr/lib/tvdemon/app.py:1197 151 | #: usr/share/tvdemon/app.ui.h:37 152 | msgid "Average Bitrate" 153 | msgstr "Durchschnittliche Bitrate" 154 | 155 | #: usr/lib/tvdemon/app.py:791 156 | msgid "Dimensions" 157 | msgstr "Abmessungen" 158 | 159 | #: usr/lib/tvdemon/app.py:794 160 | msgid "Aspect" 161 | msgstr "Seitenverhältnis" 162 | 163 | #: usr/lib/tvdemon/app.py:796 164 | msgid "Pixel Format" 165 | msgstr "Pixelformat" 166 | 167 | #: usr/lib/tvdemon/app.py:798 168 | msgid "Gamma" 169 | msgstr "Gamma" 170 | 171 | #: usr/lib/tvdemon/app.py:800 172 | msgid "Bits Per Pixel" 173 | msgstr "Bits pro Pixel" 174 | 175 | #: usr/lib/tvdemon/app.py:806 usr/lib/tvdemon/app.py:832 176 | msgid "Codec" 177 | msgstr "Kodierer" 178 | 179 | #: usr/lib/tvdemon/app.py:815 180 | msgid "surround sound" 181 | msgstr "Surround-Sound" 182 | 183 | #: usr/lib/tvdemon/app.py:816 184 | msgid "Channels" 185 | msgstr "Kanäle" 186 | 187 | #: usr/lib/tvdemon/app.py:819 188 | msgid "Sample Rate" 189 | msgstr "Abtastrate" 190 | 191 | #: usr/lib/tvdemon/app.py:824 192 | msgid "Format" 193 | msgstr "Format" 194 | 195 | #: usr/lib/tvdemon/app.py:826 196 | msgid "Channel Count" 197 | msgstr "Kanalanzahl" 198 | 199 | #: usr/lib/tvdemon/app.py:920 200 | #, python-format 201 | msgid "%d TV channel" 202 | msgid_plural "%d TV channels" 203 | msgstr[0] "%d Fernsehkanal" 204 | msgstr[1] "%d Fernsehkanäle" 205 | 206 | #: usr/lib/tvdemon/app.py:925 207 | #, python-format 208 | msgid "%d movie" 209 | msgid_plural "%d movies" 210 | msgstr[0] "%d Film" 211 | msgstr[1] "%d Filme" 212 | 213 | #: usr/lib/tvdemon/app.py:930 214 | #, python-format 215 | msgid "%d series" 216 | msgid_plural "%d series" 217 | msgstr[0] "%d Serie" 218 | msgstr[1] "%d Serien" 219 | 220 | #: usr/lib/tvdemon/app.py:950 221 | msgid "Edit" 222 | msgstr "Bearbeiten" 223 | 224 | #: usr/lib/tvdemon/app.py:960 225 | msgid "Remove" 226 | msgstr "Entfernen" 227 | 228 | #: usr/lib/tvdemon/app.py:1053 229 | msgid "M3U Playlists" 230 | msgstr "M3U-Wiedergabelisten" 231 | 232 | #: usr/lib/tvdemon/app.py:1215 generate_desktop_files:25 233 | #: usr/share/tvdemon/app.ui.h:2 234 | msgid "Watch TV" 235 | msgstr "Fernsehen" 236 | 237 | #: usr/share/tvdemon/app.ui.h:3 usr/share/tvdemon/shortcuts.ui.h:5 238 | msgid "Search" 239 | msgstr "Suchen" 240 | 241 | #: usr/share/tvdemon/app.ui.h:4 242 | msgid "Fullscreen" 243 | msgstr "Vollbild" 244 | 245 | #: usr/share/tvdemon/app.ui.h:7 246 | msgid "MPV Options" 247 | msgstr "MPV-Optionen" 248 | 249 | #: usr/share/tvdemon/app.ui.h:8 250 | msgid "List of MPV options" 251 | msgstr "Liste der MPV-Optionen" 252 | 253 | #: usr/share/tvdemon/app.ui.h:9 254 | msgid "Playback" 255 | msgstr "Wiedergabe" 256 | 257 | #: usr/share/tvdemon/app.ui.h:10 258 | msgid "User Agent" 259 | msgstr "Benutzerkennung" 260 | 261 | #: usr/share/tvdemon/app.ui.h:11 262 | msgid "Referrer" 263 | msgstr "Referrer" 264 | 265 | #: usr/share/tvdemon/app.ui.h:12 266 | msgid "Network" 267 | msgstr "Netzwerk" 268 | 269 | #: usr/share/tvdemon/app.ui.h:13 270 | msgid "" 271 | "This option only works when used with light desktop themes which support " 272 | "dark mode." 273 | msgstr "" 274 | "Diese Option funktioniert nur in Verbindung mit hellen Schreibtischthemen, " 275 | "die den dunklen Modus unterstützen." 276 | 277 | #: usr/share/tvdemon/app.ui.h:14 278 | msgid "Prefer dark mode" 279 | msgstr "Dunklen Modus bevorzugen" 280 | 281 | #: usr/share/tvdemon/app.ui.h:15 282 | msgid "Add a new provider..." 283 | msgstr "Neuen Anbieter hinzufügen …" 284 | 285 | #: usr/share/tvdemon/app.ui.h:16 286 | msgid "Reset to defaults..." 287 | msgstr "Auf Vorgaben zurücksetzen …" 288 | 289 | #: usr/share/tvdemon/app.ui.h:17 290 | msgid "Name:" 291 | msgstr "Name:" 292 | 293 | #: usr/share/tvdemon/app.ui.h:18 294 | msgid "URL:" 295 | msgstr "Adresse:" 296 | 297 | #: usr/share/tvdemon/app.ui.h:19 298 | msgid "Path:" 299 | msgstr "Pfad:" 300 | 301 | #: usr/share/tvdemon/app.ui.h:20 302 | msgid "Cancel" 303 | msgstr "Abbrechen" 304 | 305 | #: usr/share/tvdemon/app.ui.h:21 306 | msgid "OK" 307 | msgstr "OK" 308 | 309 | #: usr/share/tvdemon/app.ui.h:22 310 | msgid "Username:" 311 | msgstr "Benutzername:" 312 | 313 | #: usr/share/tvdemon/app.ui.h:23 314 | msgid "Password:" 315 | msgstr "Passwort:" 316 | 317 | #: usr/share/tvdemon/app.ui.h:24 318 | msgid "Browse..." 319 | msgstr "Durchsuchen …" 320 | 321 | #: usr/share/tvdemon/app.ui.h:25 322 | msgid "EPG:" 323 | msgstr "Programm:" 324 | 325 | #: usr/share/tvdemon/app.ui.h:26 326 | msgid "Type:" 327 | msgstr "Typ:" 328 | 329 | #: usr/share/tvdemon/app.ui.h:27 330 | msgid "Are you sure you want to delete this provider?" 331 | msgstr "Sind Sie sicher, dass Sie diesen Anbieter löschen wollen?" 332 | 333 | #: usr/share/tvdemon/app.ui.h:28 334 | msgid "No" 335 | msgstr "Nein" 336 | 337 | #: usr/share/tvdemon/app.ui.h:29 338 | msgid "Yes" 339 | msgstr "Ja" 340 | 341 | #: usr/share/tvdemon/app.ui.h:30 342 | msgid "Are you sure you want to reset to the default providers?" 343 | msgstr "" 344 | "Sind Sie sicher, dass Sie auf die vorgegebenen Anbieter zurücksetzen wollen?" 345 | 346 | #: usr/share/tvdemon/app.ui.h:31 347 | msgid "Currently playing:" 348 | msgstr "Wird derzeit wiedergegeben:" 349 | 350 | #: usr/share/tvdemon/app.ui.h:32 351 | msgid "Show" 352 | msgstr "Anzeigen" 353 | 354 | #: usr/share/tvdemon/app.ui.h:33 355 | msgid "Pause" 356 | msgstr "Unterbrechen" 357 | 358 | #: usr/share/tvdemon/app.ui.h:34 359 | msgid "Stop" 360 | msgstr "Anhalten" 361 | 362 | #: usr/share/tvdemon/app.ui.h:39 363 | msgid "Video" 364 | msgstr "Film" 365 | 366 | #: usr/share/tvdemon/app.ui.h:41 367 | msgid "Audio" 368 | msgstr "Ton" 369 | 370 | #: usr/share/tvdemon/shortcuts.ui.h:1 371 | msgid "Main shortcuts" 372 | msgstr "Haupttastenkombinationen" 373 | 374 | #: usr/share/tvdemon/shortcuts.ui.h:4 375 | msgid "Toggle Fullscreen" 376 | msgstr "Vollbild ein/aus" 377 | 378 | #: usr/share/tvdemon/shortcuts.ui.h:7 379 | msgid "Reload all providers" 380 | msgstr "Alle Anbieter neu laden." 381 | -------------------------------------------------------------------------------- /tvdemon.desktop: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env xdg-open 2 | [Desktop Entry] 3 | Version=1.0 4 | Name=TVDemon 5 | GenericName=IPTV Player 6 | GenericName[ru]=IPTV-плеер 7 | Comment=An M3U IPTV Player 8 | Icon=tvdemon 9 | Exec=bash -c 'cd $(dirname %k) && ./tvdemon.py' 10 | Terminal=false 11 | Type=Application 12 | Categories=AudioVideo;Video;Player;TV; 13 | Keywords=Television;Stream; 14 | StartupNotify=false 15 | -------------------------------------------------------------------------------- /tvdemon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (C) 2024 Dmitriy Yefremov 4 | # 5 | # 6 | # This file is part of TVDemon. 7 | # 8 | # TVDemon is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # TVDemon is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with TVDemon If not, see . 20 | # 21 | 22 | import os 23 | import sys 24 | 25 | 26 | def update_icon(): 27 | need_update = False 28 | icon_name = "tvdemon.desktop" 29 | logo_path = "/usr/share/icons/hicolor/scalable/apps/tvdemon.svg" 30 | 31 | with open(icon_name, "r", encoding="utf-8") as f: 32 | lines = f.readlines() 33 | for i, line in enumerate(lines): 34 | if line.startswith("Icon="): 35 | icon_path = line.lstrip("Icon=") 36 | current_path = f"{os.getcwd()}{logo_path}" 37 | if icon_path != current_path: 38 | need_update = True 39 | lines[i] = f"Icon={current_path}\n" 40 | break 41 | 42 | if need_update: 43 | with open(icon_name, "w", encoding="utf-8") as f: 44 | f.writelines(lines) 45 | 46 | 47 | if __name__ == "__main__": 48 | from usr.lib.tvdemon.app.main import run_app 49 | 50 | if sys.platform == "linux": 51 | update_icon() 52 | 53 | run_app() 54 | -------------------------------------------------------------------------------- /usr/bin/tvdemon: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | /usr/lib/tvdemon/tvdemon.py & 3 | -------------------------------------------------------------------------------- /usr/lib/tvdemon/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DYefremov/TVDemon/098d418348f1d23665f1ffcde973c8b39833c436/usr/lib/tvdemon/__init__.py -------------------------------------------------------------------------------- /usr/lib/tvdemon/app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DYefremov/TVDemon/098d418348f1d23665f1ffcde973c8b39833c436/usr/lib/tvdemon/app/__init__.py -------------------------------------------------------------------------------- /usr/lib/tvdemon/app/madia.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Copyright © 2023-2025 Dmitriy Yefremov 4 | # 5 | # 6 | # This file is part of TVDemon. 7 | # 8 | # TVDemon is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # TVDemon is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with TVDemon If not, see . 20 | # 21 | 22 | """ Basic playback module. """ 23 | import sys 24 | 25 | from .common import GObject, Gdk, log 26 | 27 | 28 | class Player(GObject.GObject): 29 | """ Wrapper class for the media library. """ 30 | 31 | def __init__(self, widget: Gdk.Paintable, **kwargs): 32 | super().__init__(**kwargs) 33 | self.widget = widget 34 | self._player = None 35 | 36 | GObject.signal_new("error", self, GObject.SignalFlags.RUN_FIRST, GObject.TYPE_PYOBJECT, 37 | (GObject.TYPE_PYOBJECT,)) 38 | GObject.signal_new("played", self, GObject.SignalFlags.RUN_FIRST, GObject.TYPE_PYOBJECT, 39 | (GObject.TYPE_PYOBJECT,)) 40 | GObject.signal_new("recorded", self, GObject.SignalFlags.RUN_FIRST, GObject.TYPE_PYOBJECT, 41 | (GObject.TYPE_PYOBJECT,)) 42 | 43 | self._video_properties = {} 44 | self._audio_properties = {} 45 | 46 | @property 47 | def current_lib(self): 48 | return self._lib 49 | 50 | @property 51 | def video_properties(self): 52 | return self._video_properties 53 | 54 | @property 55 | def audio_properties(self): 56 | return self._audio_properties 57 | 58 | def play(self, url): 59 | pass 60 | 61 | def pause(self): 62 | pass 63 | 64 | def stop(self): 65 | pass 66 | 67 | def set_volume(self, value): 68 | pass 69 | 70 | def get_volume(self): 71 | pass 72 | 73 | def volume_up(self): 74 | pass 75 | 76 | def volume_down(self): 77 | pass 78 | 79 | def is_playing(self): 80 | pass 81 | 82 | def start_record(self, path): 83 | pass 84 | 85 | def record_stop(self): 86 | pass 87 | 88 | def is_record(self): 89 | pass 90 | 91 | def get_stream_info(self) -> dict: 92 | pass 93 | 94 | @staticmethod 95 | def get_instance(lib: str, widget: Gdk.Paintable): 96 | if lib == "gst": 97 | return GstPlayer.get_instance(widget) 98 | raise NameError(f"There is no such [{lib}] implementation.") 99 | 100 | 101 | class GstPlayer(Player): 102 | """ Simple wrapper for GStreamer playbin. """ 103 | 104 | __INSTANCE = None 105 | 106 | def __init__(self, widget): 107 | super().__init__(widget) 108 | try: 109 | import gi 110 | 111 | gi.require_version("Gst", "1.0") 112 | gi.require_version("GstVideo", "1.0") 113 | gi.require_version("GstPlayer", "1.0") 114 | from gi.repository import Gst, GstVideo, GstPlayer 115 | # Initialization of GStreamer. 116 | # For Arch linux -> gst-plugin-gtk4 117 | Gst.init(sys.argv) 118 | except (OSError, ValueError) as e: 119 | log(f"{__class__.__name__}: Load library error: {e}") 120 | raise ImportError("No GStreamer is found. Check that it is installed!") 121 | else: 122 | self.STATE = Gst.State 123 | self.STAT_RETURN = Gst.StateChangeReturn 124 | self.EVENT = Gst.Event 125 | self.P_TYPE = Gst.PadProbeType 126 | # -> gst-plugin-gtk4 127 | if Gst.ElementFactory.make("gtk4paintablesink"): 128 | self._player = Gst.ElementFactory.make("playbin", "player") 129 | v_sink = Gst.parse_bin_from_description("tee name=v_tee ! queue ! gtk4paintablesink name=v_sink", True) 130 | self._v_tee = v_sink.get_by_name("v_tee") 131 | self._player.set_property("video-sink", v_sink) 132 | self.widget.set_paintable(v_sink.get_by_name("v_sink").props.paintable) 133 | # Record 134 | self._is_record = False 135 | rec_str = " ! ".join(("queue name=filequeue", 136 | "jpegenc", 137 | "avimux name=mux", 138 | "filesink name=rec_sink")) 139 | self._rec_pipe = Gst.parse_bin_from_description(rec_str, True) 140 | self._rec_sink = self._rec_pipe.get_by_name("rec_sink") 141 | else: 142 | msg = f"Error: The Gtk4 plugin for GStreamer is not initialized. Check that it is installed!" 143 | log(msg) 144 | raise ImportError(msg) 145 | 146 | bus = self._player.get_bus() 147 | bus.add_signal_watch() 148 | bus.connect("message::error", self.on_error) 149 | bus.connect("message::state-changed", self.on_state_changed) 150 | bus.connect("message::eos", self.on_eos) 151 | 152 | @classmethod 153 | def get_instance(cls, widget): 154 | if not cls.__INSTANCE: 155 | cls.__INSTANCE = GstPlayer(widget) 156 | return cls.__INSTANCE 157 | 158 | def get_play_mode(self): 159 | return self._mode 160 | 161 | def play(self, mrl=None): 162 | self._player.set_state(self.STATE.READY) 163 | if not mrl: 164 | return 165 | 166 | self._player.set_property("uri", mrl) 167 | 168 | log(f"Setting the URL for playback: {mrl}") 169 | ret = self._player.set_state(self.STATE.PLAYING) 170 | 171 | if ret == self.STAT_RETURN.FAILURE: 172 | msg = f"ERROR: Unable to set the 'PLAYING' state for '{mrl}'." 173 | log(msg) 174 | self.emit("error", msg) 175 | 176 | def stop(self): 177 | log("Stop playback...") 178 | self._player.set_state(self.STATE.READY) 179 | 180 | def pause(self): 181 | state = self._player.get_state(self.STATE.NULL).state 182 | if state == self.STATE.PLAYING: 183 | self._player.set_state(self.STATE.PAUSED) 184 | elif state == self.STATE.PAUSED: 185 | self._player.set_state(self.STATE.PLAYING) 186 | 187 | def set_volume(self, value: float): 188 | self._player.set_property("volume", value) 189 | 190 | def get_volume(self): 191 | return self._player.get_property("volume") 192 | 193 | def volume_up(self): 194 | volume = self._player.get_property("volume") + 0.1 195 | self.set_volume(1.0 if volume >= 1 else volume) 196 | 197 | def volume_down(self): 198 | volume = self._player.get_property("volume") - 0.1 199 | self.set_volume(0.0 if volume <= 0 else volume) 200 | 201 | def is_playing(self): 202 | return self._player.get_state(self.STATE.NULL).state is self.STATE.PLAYING 203 | 204 | def start_record(self, path): 205 | if not self.is_playing(): 206 | self.emit("error", "Recording error. No active stream!") 207 | 208 | self._player.add(self._rec_pipe) 209 | self._v_tee.link(self._rec_pipe) 210 | self._rec_sink.set_property("location", path) 211 | self._rec_pipe.set_state(self.STATE.PLAYING) 212 | self._is_record = True 213 | self.emit("recorded", 0) 214 | 215 | def record_stop(self): 216 | src = self._rec_sink.get_static_pad("src") 217 | if src: 218 | src.add_probe(self.P_TYPE.BLOCK_DOWNSTREAM, lambda pad, buf: True) 219 | self._player.remove(self._rec_pipe) 220 | self._v_tee.unlink(self._rec_pipe) 221 | self._rec_sink.get_static_pad("sink").send_event(self.EVENT.new_eos()) 222 | log("Stopped recording") 223 | self._is_record = False 224 | 225 | def is_record(self): 226 | return self._is_record 227 | 228 | def release(self): 229 | if self._player: 230 | self._player.set_state(self.STATE.NULL) 231 | self.__INSTANCE = None 232 | 233 | def on_error(self, bus, msg): 234 | err, dbg = msg.parse_error() 235 | log(err) 236 | if msg.src == self._player: 237 | self.emit("error", f"Can't Playback!") 238 | elif msg.src == self._rec_sink: 239 | self.record_stop() 240 | 241 | def on_state_changed(self, bus, msg): 242 | if not msg.src == self._player: 243 | # Not from the player. 244 | return 245 | 246 | old_state, new_state, pending = msg.parse_state_changed() 247 | if new_state is self.STATE.PLAYING: 248 | log("Starting playback...") 249 | self.emit("played", 0) 250 | self.get_stream_info() 251 | 252 | def on_eos(self, bus, msg): 253 | """ Called when an end-of-stream message appears. """ 254 | self._player.set_state(self.STATE.READY) 255 | 256 | def get_stream_info(self) -> dict: 257 | log("Getting stream info...") 258 | video_codec = "unknown" 259 | audio_codec = "unknown" 260 | nr_video = self._player.get_property("n-video") 261 | for i in range(nr_video): 262 | # Retrieve the stream's video tags. 263 | tags = self._player.emit("get-video-tags", i) 264 | if tags: 265 | _, cod = tags.get_string("video-codec") 266 | video_codec = cod or video_codec 267 | log(f"Video codec: {video_codec}") 268 | 269 | nr_audio = self._player.get_property("n-audio") 270 | for i in range(nr_audio): 271 | # Retrieve the stream's video tags. 272 | tags = self._player.emit("get-audio-tags", i) 273 | if tags: 274 | _, cod = tags.get_string("audio-codec") 275 | audio_codec = cod or audio_codec 276 | log(f"Audio codec: {audio_codec}") 277 | 278 | return {"Codec": video_codec, "Audio": audio_codec} 279 | 280 | 281 | if __name__ == "__main__": 282 | pass 283 | -------------------------------------------------------------------------------- /usr/lib/tvdemon/app/settings.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import json 3 | import os 4 | from pathlib import Path 5 | from typing import Any 6 | 7 | 8 | # Copyright (C) 2022-2024 Dmitriy Yefremov 9 | # 10 | # 11 | # This file is part of TVDemon. 12 | # 13 | # TVDemon is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU General Public License as published by 15 | # the Free Software Foundation, either version 3 of the License, or 16 | # (at your option) any later version. 17 | # 18 | # TVDemon is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU General Public License 24 | # along with TVDemon If not, see . 25 | # 26 | 27 | 28 | class Defaults(dict): 29 | def __init__(self, **kwargs): 30 | super().__init__(**kwargs) 31 | self["playback-library"] = 0 # GStreamer 32 | self["mpv-options"] = "hwdec=auto-safe" 33 | self["recordings-path"] = str(Path.home()) 34 | self["user-agent"] = "Mozilla/5.0" 35 | self["http-referer"] = "" 36 | self["active-provider"] = "Free-TV" 37 | self["providers"] = [ 38 | "Free-TV:::url:::https://raw.githubusercontent.com/Free-TV/IPTV/master/playlist.m3u8:::::::::"] 39 | self["main-window-size"] = (700, 500) 40 | self["reload-interval"] = 3600 # 1 Hour 41 | self["dark-mode"] = False # 1 Hour 42 | 43 | 44 | class Settings(dict): 45 | CONFIG_PATH = f"{Path.home()}{os.sep}.config{os.sep}tvdemon{os.sep}" 46 | CONFIG_FILE = f"{CONFIG_PATH}config" 47 | 48 | def __init__(self, **kwargs): 49 | super().__init__(**kwargs) 50 | 51 | self._defaults = Defaults() 52 | Path(self.CONFIG_PATH).mkdir(parents=True, exist_ok=True) 53 | Path(self.CONFIG_FILE).touch(exist_ok=True) 54 | 55 | if os.path.isfile(self.CONFIG_FILE) and os.stat(self.CONFIG_FILE).st_size > 0: 56 | with open(self.CONFIG_FILE, "r") as config_file: 57 | self.update(json.load(config_file)) 58 | 59 | def save(self): 60 | with open(self.CONFIG_FILE, "w") as config_file: 61 | json.dump(self, config_file) 62 | 63 | def reset(self, key): 64 | if key in self._defaults: 65 | self[key] = self._defaults.get(key) 66 | 67 | def get_value(self, key) -> Any: 68 | return self.get(key, self._defaults.get(key, None)) 69 | 70 | def set_value(self, key: str, value: object) -> None: 71 | self[key] = value 72 | 73 | def set_string(self, key, value) -> None: 74 | self[key] = value 75 | 76 | def get_string(self, key) -> str: 77 | return self.get(key, self._defaults.get(key, "")) 78 | 79 | def set_strv(self, key: str, value: list = None) -> None: 80 | self[key] = value 81 | 82 | def get_strv(self, key: str) -> list: 83 | return self.get(key, self._defaults.get(key, [])) 84 | 85 | 86 | if __name__ == '__main__': 87 | pass 88 | -------------------------------------------------------------------------------- /usr/lib/tvdemon/tvdemon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | # Copyright (C) 2023-2024 Dmitriy Yefremov 4 | # 5 | # 6 | # This file is part of TVDemon. 7 | # 8 | # TVDemon is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # TVDemon is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with TVDemon If not, see . 20 | # 21 | 22 | if __name__ == "__main__": 23 | from app.main import run_app 24 | 25 | run_app() 26 | -------------------------------------------------------------------------------- /usr/share/applications/tvdemon.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=TVDemon 3 | Comment=Watch TV 4 | Exec=tvdemon 5 | Icon=tvdemon 6 | Terminal=false 7 | Type=Application 8 | Encoding=UTF-8 9 | Categories=AudioVideo;Video;Player;TV; 10 | Keywords=Television;Stream; 11 | StartupNotify=false 12 | -------------------------------------------------------------------------------- /usr/share/locale/be/LC_MESSAGES/tvdemon.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DYefremov/TVDemon/098d418348f1d23665f1ffcde973c8b39833c436/usr/share/locale/be/LC_MESSAGES/tvdemon.mo -------------------------------------------------------------------------------- /usr/share/locale/de/LC_MESSAGES/tvdemon.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DYefremov/TVDemon/098d418348f1d23665f1ffcde973c8b39833c436/usr/share/locale/de/LC_MESSAGES/tvdemon.mo -------------------------------------------------------------------------------- /usr/share/locale/ru/LC_MESSAGES/tvdemon.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DYefremov/TVDemon/098d418348f1d23665f1ffcde973c8b39833c436/usr/share/locale/ru/LC_MESSAGES/tvdemon.mo -------------------------------------------------------------------------------- /usr/share/tvdemon/channel_widget.ui: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 99 | 100 | -------------------------------------------------------------------------------- /usr/share/tvdemon/epg.ui: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | 72 | 73 | -------------------------------------------------------------------------------- /usr/share/tvdemon/favorites_group_widget.ui: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | 54 | -------------------------------------------------------------------------------- /usr/share/tvdemon/flow_channel_widget.ui: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 79 | 80 | -------------------------------------------------------------------------------- /usr/share/tvdemon/group_widget.ui: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 53 | 54 | -------------------------------------------------------------------------------- /usr/share/tvdemon/media_bar.ui: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 170 | 171 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/README: -------------------------------------------------------------------------------- 1 | Source of country emblems: 2 | 3 | https://github.com/HatScripts/circle-flags 4 | 5 | MIT License 6 | 7 | Copyright (c) 2021 HatScripts 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/afghanistan.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/albania.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/algeria.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/andorra.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/angola.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/argentina.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/armenia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/australia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/austria.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/bahrain.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/bangladesh.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/barbados.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/belarus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/belgium.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/botswana.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/brazil.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/bulgaria.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/cameroon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/canada.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/chile.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/china.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/colombia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/costarica.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/croatia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/cuba.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/cyprus.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/czech.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/de.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 24 | 28 | 32 | 33 | 43 | 44 | 64 | 66 | 67 | 69 | image/svg+xml 70 | 72 | 73 | 74 | 75 | 76 | 81 | DE 92 | 93 | 94 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/denmark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/ecuador.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/egypt.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/en.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 24 | 28 | 32 | 33 | 43 | 44 | 64 | 66 | 67 | 69 | image/svg+xml 70 | 72 | 73 | 74 | 75 | 76 | 81 | EN 92 | 93 | 94 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/es.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 24 | 28 | 32 | 33 | 43 | 44 | 64 | 66 | 67 | 69 | image/svg+xml 70 | 72 | 73 | 74 | 75 | 76 | 81 | ES 92 | 93 | 94 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/esperanto.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/estonia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/ethiopia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/europe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/finland.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/fr.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 24 | 28 | 32 | 33 | 43 | 44 | 64 | 66 | 67 | 69 | image/svg+xml 70 | 72 | 73 | 74 | 75 | 76 | 81 | FR 92 | 93 | 94 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/france.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/georgia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/germany.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/ghana.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/greece.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/honduras.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/hongkong.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/hungary.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/iceland.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/india.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/indonesia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/irak.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/iran.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/iraq.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/ireland.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/israel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/it.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 24 | 28 | 32 | 33 | 43 | 44 | 64 | 66 | 67 | 69 | image/svg+xml 70 | 72 | 73 | 74 | 75 | 76 | 81 | IT 92 | 93 | 94 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/italy.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/ivory.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/jamaica.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/japan.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/kenya.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/korea.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/kuweit.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/laos.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/latvia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/lebanon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/liechtenstein.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/lithuania.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/luxembourg.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/lybia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/malaysia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/malta.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/marino.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/mexico.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/monaco.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/morocco.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/movies.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 24 | 28 | 32 | 33 | 43 | 44 | 64 | 66 | 67 | 69 | image/svg+xml 70 | 72 | 73 | 74 | 75 | 76 | 81 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/mozambique.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/music.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 32 | 34 | 38 | 42 | 43 | 44 | 64 | 66 | 67 | 69 | image/svg+xml 70 | 72 | 73 | 74 | 75 | 76 | 81 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/namibia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/nepal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/netherlands.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/newzealand.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/nicaragua.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/nigeria.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/norway.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/pakistan.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/panama.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/paraguay.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/peru.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/philippines.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/poland.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/portugal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/romania.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/russia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/rw.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/saudi.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/scotland.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/senegal.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/serbia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/singapore.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/slovakia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/slovenia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/south-africa.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/spain.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/sweden.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/switzerland.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/syria.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/taiwan.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/tanzania.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/thailand.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/togo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/tunisia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/turkey.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/uganda.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/uk.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/ukraine.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/uruguay.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/usa.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/uzbekistan.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/venezuela.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/vietnam.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/wales.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/yemen.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/zambia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/badges/zimbabwe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/movies.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 25 | 29 | 33 | 34 | 43 | 44 | 63 | 65 | 66 | 68 | image/svg+xml 69 | 71 | 72 | 73 | 74 | 75 | 80 | 85 | 89 | 94 | 99 | 104 | 109 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/series.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 25 | 29 | 33 | 34 | 43 | 44 | 63 | 65 | 66 | 68 | image/svg+xml 69 | 71 | 72 | 73 | 74 | 75 | 80 | 85 | 88 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /usr/share/tvdemon/pictures/tv.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 20 | 22 | 25 | 29 | 33 | 34 | 43 | 44 | 63 | 65 | 66 | 68 | image/svg+xml 69 | 71 | 72 | 73 | 74 | 75 | 80 | 85 | 88 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /usr/share/tvdemon/preferences.ui: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | 117 | 118 | -------------------------------------------------------------------------------- /usr/share/tvdemon/provider_properties_widget.ui: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | 138 | 139 | -------------------------------------------------------------------------------- /usr/share/tvdemon/provider_widget.ui: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | 53 | -------------------------------------------------------------------------------- /usr/share/tvdemon/question_dialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 23 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /usr/share/tvdemon/shortcuts.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 68 | 69 | -------------------------------------------------------------------------------- /usr/share/tvdemon/style.css: -------------------------------------------------------------------------------- 1 | #playback { 2 | background: rgba(0,0,0,1); 3 | } --------------------------------------------------------------------------------