Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
ecbb542437
|
|||
|
256248f635
|
|||
|
0df4578e09
|
3
.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
||||
*.md
|
||||
*.example
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
IPTV_ENV=dev
|
||||
REDIS_PORT=6379
|
||||
# IPTV_ENV=prod
|
||||
IPTV_NGNIX_PORT=9990
|
||||
IPTV_KEYDB_PORT=9991
|
||||
|
||||
14
.gitignore
vendored
@@ -1,17 +1,13 @@
|
||||
/.idea
|
||||
/.vscode
|
||||
.idea/
|
||||
.vscode/
|
||||
downloaded/
|
||||
/src/commit
|
||||
/src/cache/*
|
||||
/src/vendor
|
||||
/src/config/playlists.ini
|
||||
/src/views/custom.twig
|
||||
/tmp
|
||||
|
||||
commit
|
||||
*.log
|
||||
.env
|
||||
*.m3u
|
||||
*.m3u.*
|
||||
*.m3u8
|
||||
*.m3u8.*
|
||||
*.rdb
|
||||
|
||||
!/**/.gitkeep
|
||||
|
||||
@@ -4,61 +4,58 @@ networks:
|
||||
|
||||
services:
|
||||
|
||||
keydb:
|
||||
container_name: iptv-keydb
|
||||
image: eqalpha/keydb:latest
|
||||
nginx:
|
||||
container_name: iptv-nginx
|
||||
build:
|
||||
context: ./docker/nginx/
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ./docker/keydb/keydb.conf:/etc/keydb/keydb.conf
|
||||
- ./docker/keydb/data/:/data:rw
|
||||
- ./log/keydb:/var/log/keydb/:rw
|
||||
env_file:
|
||||
- .env
|
||||
- ./docker/nginx/vhost.conf:/etc/nginx/conf.d/default.conf
|
||||
- ./log/nginx:/var/log/nginx:rw
|
||||
- ./src/svc-main:/var/www:ro
|
||||
ports:
|
||||
- "${REDIS_PORT:-6379}:6379"
|
||||
- ${IPTV_NGNIX_PORT}:80
|
||||
links:
|
||||
- svc-main
|
||||
depends_on:
|
||||
- svc-main
|
||||
networks:
|
||||
- iptv
|
||||
|
||||
php:
|
||||
container_name: iptv-php
|
||||
keydb:
|
||||
container_name: iptv-keydb
|
||||
build:
|
||||
context: ./docker/keydb/
|
||||
dockerfile: Dockerfile
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ./docker/keydb/redis.conf:/etc/redis/redis.conf
|
||||
- ./docker/keydb/data/:/data:rw
|
||||
ports:
|
||||
- ${IPTV_KEYDB_PORT}:6379
|
||||
networks:
|
||||
- iptv
|
||||
|
||||
svc-main:
|
||||
container_name: iptv-svc-main
|
||||
build:
|
||||
context: ./docker/php/
|
||||
dockerfile: ${IPTV_ENV}.dockerfile
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
environment:
|
||||
- PHP_IDE_CONFIG=serverName=iptv.local
|
||||
build:
|
||||
dockerfile: docker/php/${IPTV_ENV}.dockerfile
|
||||
restart: unless-stopped
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
networks:
|
||||
- iptv
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ./docker/php/www.conf:/usr/local/etc/php-fpm.d/www.conf:ro
|
||||
- ./docker/php/${IPTV_ENV}.php.ini:/usr/local/etc/php/conf.d/php.ini:ro
|
||||
- ./log/php:/var/log/php:rw
|
||||
- ./src:/var/www:rw
|
||||
- ./playlists.ini:/var/www/config/playlists.ini:ro
|
||||
depends_on:
|
||||
- keydb
|
||||
|
||||
nginx:
|
||||
container_name: iptv-nginx
|
||||
image: nginx:latest
|
||||
restart: unless-stopped
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
- ./src/svc-main:/var/www:rw
|
||||
- ./commit:/var/www/commit:ro
|
||||
- ./playlists.ini:/var/www/playlists.ini:ro
|
||||
networks:
|
||||
- iptv
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ./docker/nginx/vhost.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
- ./log/nginx:/var/log/nginx:rw
|
||||
- ./src:/var/www:ro
|
||||
ports:
|
||||
- '8080:80'
|
||||
links:
|
||||
- php
|
||||
depends_on:
|
||||
- php
|
||||
1
docker/keydb/Dockerfile
Normal file
@@ -0,0 +1 @@
|
||||
FROM eqalpha/keydb
|
||||
BIN
docker/keydb/data/dump.rdb
Normal file
@@ -270,7 +270,7 @@ loglevel notice
|
||||
# Set the number of databases. The default database is DB 0, you can select
|
||||
# a different one on a per-connection basis using SELECT <dbid> where
|
||||
# dbid is a number between 0 and 'databases'-1
|
||||
databases 2
|
||||
databases 16
|
||||
|
||||
# By default Redis shows an ASCII art logo only when started to log to the
|
||||
# standard output and if the standard output is a TTY. Basically this means
|
||||
@@ -855,7 +855,6 @@ acllog-max-len 128
|
||||
# output buffers (but this is not needed if the policy is 'noeviction').
|
||||
#
|
||||
# maxmemory <bytes>
|
||||
#maxmemory 1 Gb
|
||||
maxmemory 1073741824
|
||||
|
||||
# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
|
||||
1
docker/nginx/Dockerfile
Normal file
@@ -0,0 +1 @@
|
||||
FROM nginx:latest
|
||||
@@ -20,7 +20,7 @@ server {
|
||||
}
|
||||
location ~ \.php$ {
|
||||
try_files $uri /index.php =404;
|
||||
fastcgi_pass php:9000;
|
||||
fastcgi_pass svc-main:9000;
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
FROM php:8.3-fpm
|
||||
FROM php:8.4-fpm
|
||||
|
||||
RUN apt update && \
|
||||
apt upgrade -y && \
|
||||
apt install -y git unzip 7zip
|
||||
RUN apt update \
|
||||
&& apt upgrade -y \
|
||||
&& apt install -y --no-install-recommends \
|
||||
git \
|
||||
unzip \
|
||||
7zip \
|
||||
&& apt-get clean autoclean \
|
||||
&& apt-get autoremove --yes \
|
||||
&& rm -rf /var/lib/{apt,dpkg,cache,log}/
|
||||
|
||||
# https://pecl.php.net/package/xdebug
|
||||
# https://pecl.php.net/package/redis
|
||||
RUN pecl channel-update pecl.php.net && \
|
||||
pecl install xdebug-3.4.1 redis && \
|
||||
docker-php-ext-enable redis && \
|
||||
mkdir -p /var/run/php && \
|
||||
mkdir -p /var/log/php && \
|
||||
chmod -R 777 /var/log/php
|
||||
RUN pecl channel-update pecl.php.net \
|
||||
&& pecl install \
|
||||
xdebug-3.4.0 \
|
||||
unzip \
|
||||
redis \
|
||||
&& mkdir -p /var/log/php
|
||||
|
||||
COPY --from=composer /usr/bin/composer /usr/local/bin/composer
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
error_reporting = E_ALL
|
||||
expose_php = Off
|
||||
file_uploads = Off
|
||||
memory_limit=-1
|
||||
max_execution_time=-1
|
||||
; upload_max_filesize=10M
|
||||
; post_max_size=10M
|
||||
|
||||
[opcache]
|
||||
opcache.enable = 1
|
||||
@@ -19,7 +22,10 @@ zend_extension = xdebug.so
|
||||
xdebug.mode = debug
|
||||
xdebug.start_with_request = yes
|
||||
xdebug.trigger_value = go
|
||||
xdebug.client_host = host.docker.internal
|
||||
xdebug.client_host = 172.17.0.1
|
||||
xdebug.REQUEST = *
|
||||
xdebug.SESSION = *
|
||||
xdebug.SERVER = *
|
||||
|
||||
[redis]
|
||||
extension=redis
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
FROM php:8.3-fpm
|
||||
FROM php:8.4-fpm
|
||||
|
||||
RUN apt update && \
|
||||
apt upgrade -y && \
|
||||
apt install -y git
|
||||
|
||||
# https://pecl.php.net/package/redis
|
||||
RUN pecl channel-update pecl.php.net && \
|
||||
pecl install redis && \
|
||||
docker-php-ext-enable redis && \
|
||||
mkdir -p /var/log/php && \
|
||||
chmod -R 777 /var/log/php
|
||||
apt install -y --no-install-recommends git && \
|
||||
apt-get clean autoclean && \
|
||||
apt-get autoremove --yes && \
|
||||
rm -rf /var/lib/{apt,dpkg,cache,log}/
|
||||
|
||||
COPY --from=composer /usr/bin/composer /usr/local/bin/composer
|
||||
|
||||
USER www-data
|
||||
EXPOSE 9000
|
||||
WORKDIR /var/www
|
||||
CMD composer install
|
||||
|
||||
@@ -13,3 +13,6 @@ opcache.max_accelerated_files = 30000
|
||||
opcache.revalidate_freq = 0
|
||||
opcache.jit_buffer_size = 64M
|
||||
opcache.jit = tracing
|
||||
|
||||
[redis]
|
||||
extension=redis
|
||||
|
||||
@@ -16,6 +16,6 @@ access.log = /var/log/php/$pool.access.log
|
||||
; chroot = /var/www
|
||||
; chdir = /var/www
|
||||
php_flag[display_errors] = on
|
||||
php_admin_value[error_log] = /var/log/php/$pool.error.log
|
||||
php_admin_value[error_log] = /var/log/php/www.error.log
|
||||
php_admin_flag[log_errors] = on
|
||||
php_admin_value[memory_limit] = 512M
|
||||
php_admin_value[memory_limit] = 32M
|
||||
|
||||
4
hooks/post-commit
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
# хук пробрасывает хэш свежего коммита в контейнер
|
||||
# для его отображения в подвале страницы
|
||||
git rev-parse HEAD > commit
|
||||
7
hooks/post-merge
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
# хук пробрасывает хэш свежего коммита в контейнер
|
||||
# для его отображения в подвале страницы и очищает
|
||||
# кеш шаблонов twig после слияния веток
|
||||
# главным образом необходимо при git pull
|
||||
git rev-parse HEAD > commit
|
||||
docker exec -ti svc-main rm -rf cache/views
|
||||
86
iptv
@@ -1,10 +1,16 @@
|
||||
#!/bin/bash
|
||||
# https://gist.github.com/anthonyaxenov/89c99e09ddb195985707e2b24a57257d
|
||||
|
||||
CONTAINER="iptv-php" # the name of the container in which to 'exec' something
|
||||
set -e
|
||||
|
||||
[[ -f ./src/svc-main/.env ]] || cp ./src/svc-main/.env.example ./src/svc-main/.env
|
||||
[[ -f ./.env ]] || cp ./.env.example ./.env
|
||||
source ./.env
|
||||
|
||||
CONTAINER="iptv-main" # the name of the container in which to 'exec' something
|
||||
CONFIG="$(dirname $([ -L $0 ] && readlink -f $0 || echo $0))/docker-compose.yml" # path to compose yml file
|
||||
CMD="docker compose -f $CONFIG" # docker-compose command
|
||||
APP_URL='http://localhost:8080/'
|
||||
APP_URL="http://localhost:${IPTV_NGINX_PORT}/"
|
||||
|
||||
open_browser() {
|
||||
if which xdg-open > /dev/null; then
|
||||
@@ -15,18 +21,66 @@ open_browser() {
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
'' | 'help' ) echo -e "Provide one of operations: \t init, start, stop, up, down, restart, rebuild, open";
|
||||
echo "Otherwise all args will passed to 'docker exec -ti $CONTAINER ...'" ;;
|
||||
'init' ) cp src/.env.example src/.env && \
|
||||
./iptv up && \
|
||||
./iptv composer i && \
|
||||
echo "Project started successfully! $APP_URL" ;;
|
||||
'up' ) $CMD up -d --build && ./iptv open ;; # build and start containers
|
||||
'down' ) $CMD down --remove-orphans ;; # stop and remove containers
|
||||
'start' ) $CMD start ;; # start containers
|
||||
'stop' ) $CMD stop ;; # stop containers
|
||||
'restart' ) $CMD stop && $CMD start ;; # restart containers
|
||||
'rebuild' ) $CMD down --remove-orphans && $CMD up -d --build ;; # rebuild containers
|
||||
'open' ) open_browser $APP_URL && echo -e "\nYou're welcome!\n\t$APP_URL" ;;
|
||||
* ) docker exec -ti $CONTAINER $* ;; # exec anything else in container
|
||||
# help message
|
||||
''|'help')
|
||||
echo -e "Provide one of operations: \t init, start, stop, up, down, restart, rebuild, open, hooks"
|
||||
echo "Otherwise all args will passed to 'docker exec -ti $CONTAINER ...'"
|
||||
;;
|
||||
|
||||
# quick start
|
||||
'init')
|
||||
./iptv hooks
|
||||
./iptv up
|
||||
./iptv composer i
|
||||
echo "Project started successfully! $APP_URL"
|
||||
;;
|
||||
|
||||
# build and start containers
|
||||
'up')
|
||||
$CMD up -d --build
|
||||
./iptv open
|
||||
;;
|
||||
|
||||
# stop and remove containers
|
||||
'down')
|
||||
$CMD down --remove-orphans
|
||||
;;
|
||||
|
||||
# start containers
|
||||
'start')
|
||||
$CMD start
|
||||
;;
|
||||
|
||||
# stop containers
|
||||
'stop')
|
||||
$CMD stop
|
||||
;;
|
||||
|
||||
# restart containers
|
||||
'restart')
|
||||
$CMD stop
|
||||
$CMD start
|
||||
;;
|
||||
|
||||
# rebuild containers
|
||||
'rebuild')
|
||||
$CMD down --remove-orphans
|
||||
$CMD up -d --build
|
||||
;;
|
||||
|
||||
# open url in web-browser
|
||||
'open')
|
||||
open_browser $APP_URL
|
||||
echo -e "\nYou're welcome!\n\t$APP_URL" \
|
||||
;;
|
||||
|
||||
# install git hooks
|
||||
'hooks')
|
||||
сp -f hooks/* .git/hooks
|
||||
;;
|
||||
|
||||
# exec anything else in container
|
||||
*)
|
||||
docker exec -ti $CONTAINER $*
|
||||
;;
|
||||
esac
|
||||
|
||||
704
playlists.ini
@@ -1,18 +0,0 @@
|
||||
# config/app.php
|
||||
APP_DEBUG=false
|
||||
APP_ENV=prod
|
||||
APP_URL=http://localhost:8080
|
||||
APP_TITLE='IPTV Плейлисты'
|
||||
USER_AGENT='Mozilla/5.0 (Windows NT 10.0; Win64; x99) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36'
|
||||
PAGE_SIZE=10
|
||||
|
||||
# config/redis.php
|
||||
REDIS_HOST='keydb'
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
REDIS_DB=0
|
||||
REDIS_TTL_DAYS=14
|
||||
|
||||
# config/redis.php
|
||||
TWIG_USE_CACHE=true
|
||||
TWIG_DEBUG=false
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Random\RandomException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class ApiController extends BasicController
|
||||
{
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return ResponseInterface
|
||||
* @throws RandomException
|
||||
*/
|
||||
public function json(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
||||
{
|
||||
$code = $request->getAttributes()['code'];
|
||||
$playlist = $this->getPlaylist($code, true);
|
||||
$playlist->fetchContent();
|
||||
$playlist->parse();
|
||||
|
||||
$json = json_encode($playlist->toArray(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
$response->getBody()->write($json);
|
||||
|
||||
return $response
|
||||
->withHeader('Content-Type', 'application/json')
|
||||
->withHeader('Content-Length', strlen($json));
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Core\Playlist;
|
||||
use App\Errors\PlaylistNotFoundException;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Slim\Views\Twig;
|
||||
use Twig\Error\LoaderError;
|
||||
use Twig\Error\RuntimeError;
|
||||
use Twig\Error\SyntaxError;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class BasicController
|
||||
{
|
||||
/**
|
||||
* Отправляет сообщение о том, что метод не найден с кодом страницы 404
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return ResponseInterface
|
||||
* @throws LoaderError
|
||||
* @throws RuntimeError
|
||||
* @throws SyntaxError
|
||||
*/
|
||||
public function notFound(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
||||
{
|
||||
$response->withStatus(404);
|
||||
$this->view($request, $response, 'notfound.twig');
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @param string $template
|
||||
* @param array $data
|
||||
* @return ResponseInterface
|
||||
* @throws LoaderError
|
||||
* @throws RuntimeError
|
||||
* @throws SyntaxError
|
||||
*/
|
||||
protected function view(
|
||||
ServerRequestInterface $request,
|
||||
ResponseInterface $response,
|
||||
string $template,
|
||||
array $data = [],
|
||||
): ResponseInterface {
|
||||
$view = Twig::fromRequest($request);
|
||||
return $view->render($response, $template, $data);
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Core\ChannelLogo;
|
||||
use App\Errors\PlaylistNotFoundException;
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Twig\Error\LoaderError;
|
||||
use Twig\Error\RuntimeError;
|
||||
use Twig\Error\SyntaxError;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class WebController extends BasicController
|
||||
{
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return ResponseInterface
|
||||
* @throws LoaderError
|
||||
* @throws RuntimeError
|
||||
* @throws SyntaxError
|
||||
* @throws Exception
|
||||
*/
|
||||
public function home(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
||||
{
|
||||
ini()->load();
|
||||
|
||||
$playlists = ini()->playlists(false);
|
||||
$count = count($playlists);
|
||||
$page = (int)($request->getAttributes()['page'] ?? $request->getQueryParams()['page'] ?? 1);
|
||||
$pageSize = config('app.page_size');
|
||||
$pageCount = ceil($count / $pageSize);
|
||||
$offset = max(0, ($page - 1) * $pageSize);
|
||||
$list = array_slice($playlists, $offset, $pageSize, true);
|
||||
|
||||
return $this->view($request, $response, 'list.twig', [
|
||||
'updated_at' => ini()->updatedAt(),
|
||||
'playlists' => $list,
|
||||
'count' => $count,
|
||||
'pageCount' => $pageCount,
|
||||
'pageCurrent' => $page,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return ResponseInterface
|
||||
* @throws LoaderError
|
||||
* @throws RuntimeError
|
||||
* @throws SyntaxError
|
||||
*/
|
||||
public function faq(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
||||
{
|
||||
return $this->view($request, $response, 'faq.twig');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function redirect(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
||||
{
|
||||
ini()->load();
|
||||
$code = $request->getAttributes()['code'];
|
||||
try {
|
||||
$playlist = ini()->getPlaylist($code);
|
||||
return $response->withHeader('Location', $playlist->pls);
|
||||
} catch (PlaylistNotFoundException) {
|
||||
return $this->notFound($request, $response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return ResponseInterface
|
||||
* @throws \Random\RandomException
|
||||
* @throws LoaderError
|
||||
* @throws RuntimeError
|
||||
* @throws SyntaxError
|
||||
*/
|
||||
public function details(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
||||
{
|
||||
ini()->load();
|
||||
$code = $request->getAttributes()['code'];
|
||||
try {
|
||||
$playlist = ini()->getPlaylist($code);
|
||||
$response->withHeader('Location', $playlist->pls);
|
||||
} catch (PlaylistNotFoundException) {
|
||||
return $this->notFound($request, $response);
|
||||
}
|
||||
|
||||
$playlist->fetchContent();
|
||||
$playlist->parse();
|
||||
|
||||
return $this->view($request, $response, 'details.twig', $playlist->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ServerRequestInterface $request
|
||||
* @param ResponseInterface $response
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function logo(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
|
||||
{
|
||||
$input = $request->getQueryParams()['url'] ?? null;
|
||||
|
||||
$logo = new ChannelLogo($input);
|
||||
$logo->readFile() || $logo->fetch();
|
||||
$logo->size() === 0 && $logo->setDefault();
|
||||
$logo->store();
|
||||
$body = $logo->raw();
|
||||
$size = $logo->size();
|
||||
$mime = $logo->mimeType();
|
||||
|
||||
$response->getBody()->write($body);
|
||||
return $response->withHeader('Content-Type', $mime)
|
||||
->withHeader('Content-Length', $size);
|
||||
}
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Core;
|
||||
|
||||
use App\Core\TwigExtention as IptvTwigExtension;
|
||||
use Dotenv\Dotenv;
|
||||
use InvalidArgumentException;
|
||||
use Redis;
|
||||
use Slim\App;
|
||||
use Slim\Factory\AppFactory;
|
||||
use Slim\Views\Twig;
|
||||
use Slim\Views\TwigMiddleware;
|
||||
use Twig\Error\LoaderError;
|
||||
|
||||
/**
|
||||
* Загрузчик приложения
|
||||
*/
|
||||
final class Core
|
||||
{
|
||||
/**
|
||||
* @var Core
|
||||
*/
|
||||
private static Core $instance;
|
||||
|
||||
/**
|
||||
* @var App
|
||||
*/
|
||||
protected App $app;
|
||||
|
||||
/**
|
||||
* @var array Конфигурация приложения
|
||||
*/
|
||||
protected array $config = [];
|
||||
|
||||
/**
|
||||
* @var Redis
|
||||
*/
|
||||
protected Redis $redis;
|
||||
|
||||
/**
|
||||
* @var IniFile
|
||||
*/
|
||||
protected IniFile $iniFile;
|
||||
|
||||
/**
|
||||
* Закрытый конструктор
|
||||
*/
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает объект приложения
|
||||
*
|
||||
* @return Core
|
||||
*/
|
||||
public static function get(): Core
|
||||
{
|
||||
return self::$instance ??= new self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает приложение
|
||||
*
|
||||
* @return App
|
||||
* @throws LoaderError
|
||||
*/
|
||||
public function boot(): App
|
||||
{
|
||||
$this->app = AppFactory::create();
|
||||
|
||||
$this->bootSettings();
|
||||
$this->bootRoutes();
|
||||
$this->bootTwig();
|
||||
$this->bootRedis();
|
||||
$this->bootIni();
|
||||
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает значение из конфига
|
||||
*
|
||||
* @param string $key Ключ в формате "config.key"
|
||||
* @param mixed|null $default Значение по умолчанию
|
||||
* @return mixed
|
||||
*/
|
||||
public function config(string $key, mixed $default = null): mixed
|
||||
{
|
||||
$parts = explode('.', $key);
|
||||
return $this->config[$parts[0]][$parts[1]] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Redis
|
||||
*/
|
||||
public function redis(): Redis
|
||||
{
|
||||
return $this->redis;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return IniFile
|
||||
*/
|
||||
public function ini(): IniFile
|
||||
{
|
||||
return $this->iniFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return App
|
||||
*/
|
||||
public function app(): App
|
||||
{
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает файл .env или .env.$env
|
||||
*
|
||||
* @param string $env
|
||||
* @return array
|
||||
*/
|
||||
protected function loadDotEnvFile(string $env = ''): array
|
||||
{
|
||||
$filename = empty($env) ? '.env' : ".env.$env";
|
||||
if (!file_exists(root_path($filename))) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$dotenv = Dotenv::createMutable(root_path(), $filename);
|
||||
return $dotenv->safeLoad();
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает конфигурационные файлы
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function bootSettings(): void
|
||||
{
|
||||
$env = $this->loadDotEnvFile();
|
||||
|
||||
if (!empty($env['APP_ENV'])) {
|
||||
$this->loadDotEnvFile($env['APP_ENV']);
|
||||
}
|
||||
|
||||
foreach (glob(config_path() . '/*.php') as $file) {
|
||||
$key = basename($file, '.php');
|
||||
$this->config += [$key => require_once $file];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает маршруты
|
||||
*
|
||||
* @return void
|
||||
* @see https://www.slimframework.com/docs/v4/objects/routing.html
|
||||
*/
|
||||
protected function bootRoutes(): void
|
||||
{
|
||||
foreach ($this->config['routes'] as $route) {
|
||||
if (is_array($route['method'])) {
|
||||
$definition = $this->app->map($route['method'], $route['path'], $route['handler']);
|
||||
} else {
|
||||
$isPossible = in_array($route['method'], ['GET', 'POST', 'OPTIONS', 'PUT', 'PATCH', 'DELETE']);
|
||||
|
||||
$func = match (true) {
|
||||
$route['method'] === '*' => 'any',
|
||||
$isPossible => strtolower($route['method']),
|
||||
default => throw new InvalidArgumentException(sprintf('Неверный HTTP метод %s', $route['method']))
|
||||
};
|
||||
|
||||
$definition = $this->app->$func($route['path'], $route['handler']);
|
||||
}
|
||||
|
||||
if (!empty($route['name'])) {
|
||||
$definition->setName($route['name']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает шаблонизатор и его расширения
|
||||
*
|
||||
* @return void
|
||||
* @throws LoaderError
|
||||
* @see https://www.slimframework.com/docs/v4/features/twig-view.html
|
||||
*/
|
||||
protected function bootTwig(): void
|
||||
{
|
||||
$twig = Twig::create(root_path('views'), $this->config['twig']);
|
||||
$twig->addExtension(new IptvTwigExtension());
|
||||
$this->app->add(TwigMiddleware::create($this->app, $twig));
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализирует подключение к Redis
|
||||
*
|
||||
* @return void
|
||||
* @see https://github.com/phpredis/phpredis/?tab=readme-ov-file
|
||||
*/
|
||||
protected function bootRedis(): void
|
||||
{
|
||||
$options = [
|
||||
'host' => $this->config['redis']['host'],
|
||||
'port' => (int)$this->config['redis']['port'],
|
||||
];
|
||||
|
||||
if (!empty($this->config['redis']['password'])) {
|
||||
$options['auth'] = $this->config['redis']['password'];
|
||||
}
|
||||
|
||||
$this->redis = new Redis($options);
|
||||
$this->redis->select((int)$this->config['redis']['db']);
|
||||
$this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_JSON);
|
||||
}
|
||||
|
||||
/**
|
||||
* Инициализирует объект ini-файла
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function bootIni(): void
|
||||
{
|
||||
$this->iniFile = new IniFile();
|
||||
}
|
||||
}
|
||||
@@ -1,92 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Errors;
|
||||
|
||||
use Psr\Http\Message\{
|
||||
ResponseInterface,
|
||||
ServerRequestInterface};
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Slim\Handlers\ErrorHandler as SlimErrorHandler;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Обработчик ошибок
|
||||
*/
|
||||
class ErrorHandler extends SlimErrorHandler
|
||||
{
|
||||
/**
|
||||
* Логирует ошибку и отдаёт JSON-ответ с необходимым содержимым
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
* @param Throwable $exception
|
||||
* @param bool $displayErrorDetails
|
||||
* @param bool $logErrors
|
||||
* @param bool $logErrorDetails
|
||||
* @param LoggerInterface|null $logger
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function __invoke(
|
||||
ServerRequestInterface $request,
|
||||
Throwable $exception,
|
||||
bool $displayErrorDetails,
|
||||
bool $logErrors,
|
||||
bool $logErrorDetails,
|
||||
?LoggerInterface $logger = null
|
||||
): ResponseInterface {
|
||||
$payload = $this->payload($exception, $displayErrorDetails);
|
||||
|
||||
$response = app()->getResponseFactory()->createResponse();
|
||||
$response->getBody()->write(json_encode($payload, JSON_UNESCAPED_UNICODE));
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает структуру исключения для контекста
|
||||
*
|
||||
* @param Throwable $e Исключение
|
||||
* @param bool $logErrorDetails Признак дополнения деталями
|
||||
* @return array
|
||||
*/
|
||||
protected function context(Throwable $e, bool $logErrorDetails): array
|
||||
{
|
||||
$result = ['code' => $e->getCode()];
|
||||
|
||||
$logErrorDetails && $result += [
|
||||
'class' => $e::class,
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'trace' => $e->getTrace()
|
||||
];
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает структуру исключения для передачи в ответе
|
||||
*
|
||||
* @param Throwable $e Исключение
|
||||
* @param bool $displayErrorDetails Признак дополнения деталями
|
||||
* @return array
|
||||
*/
|
||||
protected function payload(Throwable $e, bool $displayErrorDetails): array
|
||||
{
|
||||
$result = [
|
||||
'error' => [
|
||||
'code' => $e->getCode(),
|
||||
'message' => $e->getMessage(),
|
||||
],
|
||||
];
|
||||
|
||||
$displayErrorDetails && $result['error'] += [
|
||||
'class' => $e::class,
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'trace' => $e->getTrace(),
|
||||
];
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Middleware;
|
||||
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
/**
|
||||
* Middleware для добавления запросу заголовка X-Request-ID
|
||||
*/
|
||||
class RequestId
|
||||
{
|
||||
/**
|
||||
* Добавляет запросу заголовок X-Request-ID
|
||||
*
|
||||
* @param ServerRequestInterface $request
|
||||
* @param RequestHandlerInterface $handler
|
||||
* @return ResponseInterface
|
||||
*/
|
||||
public function __invoke(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
|
||||
{
|
||||
$request = $request->withHeader('X-Request-ID', uniqid());
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
{
|
||||
"name": "axenov/iptv",
|
||||
"type": "project",
|
||||
"description": "Сервис для сбора IPTV-плейлистов и сокращения ссылок",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Anthony Axenov",
|
||||
"homepage": "https://axenov.dev/",
|
||||
"role": "author"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.3",
|
||||
"ext-json": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-redis": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"guzzlehttp/guzzle": "^7.8",
|
||||
"nyholm/psr7": "^1.6",
|
||||
"vlucas/phpdotenv": "*",
|
||||
"slim/slim": "^4.11",
|
||||
"slim/twig-view": "^3.4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "app/"
|
||||
},
|
||||
"files": [
|
||||
"app/helpers.php"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"clear-views": "rm -rf cache/views",
|
||||
"post-install-cmd": [
|
||||
"@clear-views"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
1860
src/composer.lock
generated
@@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'base_url' => env('APP_URL', 'http://localhost:8080'),
|
||||
'debug' => bool(env('APP_DEBUG', false)),
|
||||
'env' => env('APP_ENV', env('IPTV_ENV', 'prod')),
|
||||
'title' => env('APP_TITLE', 'IPTV Плейлисты'),
|
||||
'user_agent' => env('USER_AGENT'),
|
||||
'page_size' => (int)env('PAGE_SIZE', 10),
|
||||
'pls_encodings' => [
|
||||
'UTF-8',
|
||||
'CP1251',
|
||||
// 'CP866',
|
||||
// 'ISO-8859-5',
|
||||
],
|
||||
];
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'host' => env('REDIS_HOST', 'keydb'),
|
||||
'port' => (int)env('REDIS_PORT', 6379),
|
||||
'password' => env('REDIS_PASSWORD'),
|
||||
'db' => (int)env('REDIS_DB', 0),
|
||||
'ttl_days' => (int)env('REDIS_TTL_DAYS', 14) * 60 * 60 * 24, // 2 недели
|
||||
];
|
||||
@@ -1,52 +0,0 @@
|
||||
<?php
|
||||
|
||||
use App\Controllers\ApiController;
|
||||
use App\Controllers\BasicController;
|
||||
use App\Controllers\WebController;
|
||||
|
||||
return [
|
||||
[
|
||||
'method' => 'GET',
|
||||
'path' => '/[page/{page:[0-9]+}]',
|
||||
'handler' => [WebController::class, 'home'],
|
||||
'name' => 'home',
|
||||
],
|
||||
[
|
||||
'method' => 'GET',
|
||||
'path' => '/faq',
|
||||
'handler' => [WebController::class, 'faq'],
|
||||
'name' => 'faq',
|
||||
],
|
||||
[
|
||||
'method' => 'GET',
|
||||
'path' => '/logo',
|
||||
'handler' => [WebController::class, 'logo'],
|
||||
'name' => 'logo',
|
||||
],
|
||||
[
|
||||
'method' => 'GET',
|
||||
'path' => '/{code:[0-9a-zA-Z]+}',
|
||||
'handler' => [WebController::class, 'redirect'],
|
||||
'name' => 'redirect',
|
||||
],
|
||||
[
|
||||
'method' => 'GET',
|
||||
'path' => '/{code:[0-9a-zA-Z]+}/details',
|
||||
'handler' => [WebController::class, 'details'],
|
||||
'name' => 'details',
|
||||
],
|
||||
[
|
||||
'method' => 'GET',
|
||||
'path' => '/{code:[0-9a-zA-Z]+}/json',
|
||||
'handler' => [ApiController::class, 'json'],
|
||||
'name' => 'json',
|
||||
],
|
||||
[
|
||||
'method' => '*',
|
||||
'path' => '/{path:.*}',
|
||||
'handler' => [BasicController::class, 'notFound'],
|
||||
'name' => 'not-found',
|
||||
],
|
||||
// ...
|
||||
];
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'cache' => bool(env('TWIG_USE_CACHE', true)) ? cache_path() . '/views' : false,
|
||||
'debug' => bool(env('TWIG_DEBUG', false)),
|
||||
];
|
||||
@@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Слой_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 235.6 292.2" style="enable-background:new 0 0 235.6 292.2;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g id="b_1_">
|
||||
<path class="st0" d="M44.3,164.5L76.9,51.6H127l-10.1,35c-0.1,0.2-0.2,0.4-0.3,0.6L90,179.6h24.8c-10.4,25.9-18.5,46.2-24.3,60.9
|
||||
c-45.8-0.5-58.6-33.3-47.4-72.1 M90.7,240.6l60.4-86.9h-25.6l22.3-55.7c38.2,4,56.2,34.1,45.6,70.5
|
||||
c-11.3,39.1-57.1,72.1-101.7,72.1C91.3,240.6,91,240.6,90.7,240.6z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 735 B |
@@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require '../vendor/autoload.php';
|
||||
|
||||
core()->boot()->run();
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
TOOLS_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]:-$0}"; )" &> /dev/null && pwd 2> /dev/null; )";
|
||||
DL_DIR="$TOOLS_DIR/downloaded"
|
||||
INI_FILE="$(dirname "$TOOLS_DIR")/playlists.ini"
|
||||
INI_FILE="$(dirname "$TOOLS_DIR")/../../playlists.ini"
|
||||
|
||||
rm -rf "$DL_DIR" && \
|
||||
mkdir -p "$DL_DIR" && \
|
||||
0
src/cache/.gitkeep → src/svc-checker/LICENSE
Executable file → Normal file
23
src/svc-checker/go.mod
Normal file
@@ -0,0 +1,23 @@
|
||||
module iptv-tools
|
||||
|
||||
go 1.21
|
||||
|
||||
require (
|
||||
github.com/pawanpaudel93/go-m3u-parser v0.0.0-20230527184521-58d64dd2fddd
|
||||
github.com/spf13/cobra v1.8.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/VividCortex/ewma v1.1.1 // indirect
|
||||
github.com/cheggaaa/pb/v3 v3.0.8 // indirect
|
||||
github.com/fatih/color v1.10.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.12 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.12 // indirect
|
||||
github.com/pirsquare/country-mapper v0.0.0-20180107162822-0fffc2d62977 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
|
||||
)
|
||||
42
src/svc-checker/go.sum
Normal file
@@ -0,0 +1,42 @@
|
||||
github.com/VividCortex/ewma v1.1.1 h1:MnEK4VOv6n0RSY4vtRe3h11qjxL3+t0B8yOL8iMXdcM=
|
||||
github.com/VividCortex/ewma v1.1.1/go.mod h1:2Tkkvm3sRDVXaiyucHiACn4cqf7DpdyLvmxzcbUokwA=
|
||||
github.com/cheggaaa/pb/v3 v3.0.8 h1:bC8oemdChbke2FHIIGy9mn4DPJ2caZYQnfbRqwmdCoA=
|
||||
github.com/cheggaaa/pb/v3 v3.0.8/go.mod h1:UICbiLec/XO6Hw6k+BHEtHeQFzzBH4i2/qk/ow1EJTA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.12 h1:Y41i/hVW3Pgwr8gV+J23B9YEY0zxjptBuCWEaxmAOow=
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/pawanpaudel93/go-m3u-parser v0.0.0-20230527184521-58d64dd2fddd h1:FKiMnndpNfhIIsodF7LblIVQqvmQysnrrQMJhEeu7K0=
|
||||
github.com/pawanpaudel93/go-m3u-parser v0.0.0-20230527184521-58d64dd2fddd/go.mod h1:8jMDjt3ix1PbtPZMHnJNVG9o/R8OEs0Vs6vc6SBQfM4=
|
||||
github.com/pirsquare/country-mapper v0.0.0-20180107162822-0fffc2d62977 h1:y3eVd9XFG+pwC7qkuLiTuCz/EoV49vLYnPdATMX/NzI=
|
||||
github.com/pirsquare/country-mapper v0.0.0-20180107162822-0fffc2d62977/go.mod h1:AHizlkKHalvpAKqnCfCwGPIpfMEYa2HNgNcxaKUD8A4=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 h1:F5Gozwx4I1xtr/sr/8CFbb57iKi3297KFs0QDbGN60A=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
17
src/svc-checker/main.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/pawanpaudel93/go-m3u-parser/m3uparser"
|
||||
)
|
||||
|
||||
func main() {
|
||||
userAgent := "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36"
|
||||
timeout := 5
|
||||
parser := m3uparser.M3uParser{UserAgent: userAgent, Timeout: timeout}
|
||||
parser.ParseM3u("https://iptv.axenov.dev/d1", true, true)
|
||||
//parser.FilterBy("status", []string{"GOOD"}, true)
|
||||
parser.SortBy("title", true)
|
||||
|
||||
parser.ToFile("rowdy.json")
|
||||
//fmt.Println(parser.GetStreamsJSON())
|
||||
}
|
||||
677
src/svc-checker/pls2
Normal file
@@ -0,0 +1,677 @@
|
||||
#EXTM3U url-tvg="http://2.56.164.181/epg.xml.gz?q=eyJ1c2VySWQiOiJ0ZXN0In0.O2NtoPYMyNSQUxDLCHixQwezneQOFMrVUWCIOEvH5wdsyihh2LbQoq37IfNxQBB8qNAPJ_6dDlUVGwq5uo9SPg" description="Medium" size="Medium" background="#11609e"
|
||||
#EXTINF:-1 tvg-id="hlsproxy-362" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/pervy.png" group-title="Общественные",Первый (HD)
|
||||
http://2.56.164.181/channel/7e4e855f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-134" tvg-logo="http://epg.one/img2/2265.png" group-title="Общественные",360° (HD)
|
||||
http://2.56.164.181/channel/5b658560/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-156" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/rt-doc.png" group-title="Общественные",RTД (HD)
|
||||
http://2.56.164.181/channel/51f6b092/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-151" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/rtvi.png" group-title="Общественные",RTVi (EDTV 576p)
|
||||
http://2.56.164.181/channel/n26f746d6/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-3098" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tv-brics.png" group-title="Общественные",TV BRICS (HD)
|
||||
http://2.56.164.181/channel/237ef130/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-217" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/belarus1hd.png" group-title="Общественные",Беларусь 1 (EDTV 576p)
|
||||
http://2.56.164.181/channel/n563e1f1e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-219" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/belarus24.png" group-title="Общественные",Беларусь 24 (HD)
|
||||
http://2.56.164.181/channel/22bf7e98/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-446" tvg-logo="http://epg.it999.ru/img2/2294.png" group-title="Общественные",БелРос (WSVGA)
|
||||
http://2.56.164.181/channel/604f16a0/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53514" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/bolshaya-azia.png" group-title="Общественные",Большая Азия (HD ready)
|
||||
http://2.56.164.181/channel/17fdf18/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-288" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/vmeste-rf.png" group-title="Общественные",ВМЕСТЕ:РФ (HD)
|
||||
http://2.56.164.181/channel/363ac18c/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-227" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/vremia.png" group-title="Общественные",Время (HD)
|
||||
http://2.56.164.181/channel/7b9f297d/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-55266" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/dumatv.png" group-title="Общественные",ДУМАТВ (HD ready)
|
||||
http://2.56.164.181/channel/n6132f4af/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-259" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/zvezda.png" group-title="Общественные",Звезда (HD)
|
||||
http://2.56.164.181/channel/30514fd1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-51060" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/krasnaya-linia.png" group-title="Общественные",Красная линия (EDTV 480p)
|
||||
http://2.56.164.181/channel/6e2ca4ad/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-299" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/mir.png" group-title="Общественные",Мир (HD)
|
||||
http://2.56.164.181/channel/3ec05acd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-300" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/mir24.png" group-title="Общественные",Мир 24 (HD)
|
||||
http://2.56.164.181/channel/n4d6104bd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="neizvestnaya-rosia" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/neizvestnaya-rosia.png" group-title="Общественные",Неизвестная Россия (HD)
|
||||
#EXTVLCOPT:http-user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 13_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.69
|
||||
http://2.56.164.181/channel/n3ec44238/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-319" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/ntv.png" group-title="Общественные",НТВ (HD)
|
||||
http://2.56.164.181/channel/28910ed3/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-325" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/otr.png" group-title="Общественные",ОТР (EDTV 576p)
|
||||
http://2.56.164.181/channel/n6979bc8b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-10071" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/prnk-tv.png" group-title="Общественные",ПРНК (HD ready)
|
||||
http://2.56.164.181/channel/n29f04272/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-378" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/5kanal-ru.png" group-title="Общественные",Пятый канал (EDTV 576p)
|
||||
http://2.56.164.181/channel/1aa1558b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53502" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/ratnik.png" group-title="Общественные",Ратник (HD)
|
||||
http://2.56.164.181/channel/n778539da/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-382" tvg-logo="http://epg.one/img2/18.png" group-title="Общественные",Рен ТВ (EDTV 576p)
|
||||
http://2.56.164.181/channel/23b5de22/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-52966" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/rentv-int.png" group-title="Общественные",Рен ТВ Int (EDTV 576p)
|
||||
http://2.56.164.181/channel/7a984cee/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-391" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/rossia1.png" group-title="Общественные",Россия 1 (Тамбов) (WSVGA)
|
||||
http://2.56.164.181/channel/n58164086/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-391" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/rossia1.png" group-title="Общественные",Россия 1 (HD)
|
||||
http://2.56.164.181/channel/n3cde66fc/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-9230" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/stv-by.png" group-title="Общественные",CTV.BY (HD ready)
|
||||
http://2.56.164.181/channel/n4f0d50c4/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 catchup="append" catchup-days="3" catchup-source="&offset=-${offset}&utcstart=${timestamp}" tvg-id="hlsproxy-432" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tv3-ru.png" group-title="Общественные",ТВ3 (EDTV 480p)
|
||||
#EXTVLCOPT:http-user-agent=WINK/1.40.1 (AndroidTV/9) HlsWinkPlayer
|
||||
http://2.56.164.181/channel/n7fde110b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 catchup="append" catchup-days="3" catchup-source="&offset=-${offset}&utcstart=${timestamp}" tvg-id="hlsproxy-434" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tvcentr.png" group-title="Общественные",ТВ Центр (EDTV 480p)
|
||||
#EXTVLCOPT:http-user-agent=WINK/1.40.1 (AndroidTV/9) HlsWinkPlayer
|
||||
http://2.56.164.181/channel/318406/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-1006" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/ani.png" group-title="Детские",Ani (WSVGA)
|
||||
http://2.56.164.181/channel/n4fdc1c35/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="baby-time" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/baby-time.png" group-title="Детские",Baby Time (EDTV 576p)
|
||||
http://2.56.164.181/channel/469b2521/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="cartoon-classics" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/cartoon-classics.png" group-title="Детские",Cartoon Classics (EDTV 480p)
|
||||
http://2.56.164.181/channel/n6b11ecc5/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-52" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/cartoon-network.png" group-title="Детские",Cartoon Network (EDTV 576p)
|
||||
http://2.56.164.181/channel/n554be86a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-42" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/boomerang.png" group-title="Детские",Cartoonito (HD)
|
||||
http://2.56.164.181/channel/n3f6051ed/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-56" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/da-vinci.png" group-title="Детские",Da Vinci (EDTV 576p)
|
||||
http://2.56.164.181/channel/n169d83f1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-136" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/nickelodeon-ru.png" group-title="Детские",Nickelodeon (HD)
|
||||
http://2.56.164.181/channel/n596639e4/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-54368" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/nicktoons.png" group-title="Детские",Nicktoons (HD)
|
||||
http://2.56.164.181/channel/4c105d2b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8521" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/v-gostiax-u-skazki.png" group-title="Детские",В гостях у сказки (HD)
|
||||
http://2.56.164.181/channel/232b6444/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-2415" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/detkinoint-tviksel.png" group-title="Детские",Детское кино Int (768×432)
|
||||
http://2.56.164.181/channel/5038a1a7/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-239" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/detsky-mir.png" group-title="Детские",Детский мир (EDTV 576p)
|
||||
http://2.56.164.181/channel/n195abd67/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-277" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/karusel.png" group-title="Детские",Карусель (WSVGA)
|
||||
http://2.56.164.181/channel/74ae8d1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-51020" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/karusel.png" group-title="Детские",Карусель Int (EDTV 576p)
|
||||
http://2.56.164.181/channel/n4029471b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100674" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/liova.png" group-title="Детские",Лёва (HD)
|
||||
http://2.56.164.181/channel/n176a8a75/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-304" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/mama.png" group-title="Детские",Мама (SDTV 576i)
|
||||
http://2.56.164.181/channel/n6ec00cd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-314" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/mult.png" group-title="Детские",Мульт (HD)
|
||||
http://2.56.164.181/channel/54a6ef09/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-427" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/multimuzyka.png" group-title="Детские",МУЛЬТиМУЗЫКА(EDTV 576p)
|
||||
http://2.56.164.181/channel/3188c4d1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-315" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/multimania.png" group-title="Детские",Мультиландия (EDTV 576p)
|
||||
http://2.56.164.181/channel/n7848690/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-55000" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/multimania-lv.png" group-title="Детские",Мультимания (SDTV 576i)
|
||||
http://2.56.164.181/channel/46dab0b7/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-186" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/o_.png" group-title="Детские",О! (EDTV 576p)
|
||||
http://2.56.164.181/channel/7bc46034/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8457" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/pingvin-lolo.png" group-title="Детские",Пингвин (SDTV 576i)
|
||||
http://2.56.164.181/channel/19999c6d/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-51108" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/ryzhy.png" group-title="Детские",Рыжий (EDTV 576p)
|
||||
http://2.56.164.181/channel/3585bb07/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-388" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/radost-moya.png" group-title="Детские",Радость моя (WSVGA)
|
||||
http://2.56.164.181/channel/29663770/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-7178" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/smaylik-tv.png" group-title="Детские",Смайл ТВ (HD ready)
|
||||
http://2.56.164.181/channel/216e5045/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-66" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/solnce.png" group-title="Детские",Солнце (WSVGA)
|
||||
http://2.56.164.181/channel/n18de88f4/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-54501" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sts-kids-hd.png" group-title="Детские",СТС Kids (EDTV 576p)
|
||||
http://2.56.164.181/channel/n20bc481b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-54501" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sts-kids-hd.png" group-title="Детские",СТС Kids (HD)
|
||||
http://2.56.164.181/channel/faf01fd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-238" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/unikum.png" group-title="Детские",Уникум (EDTV 576p)
|
||||
http://2.56.164.181/channel/n7d2624c9/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-276" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/2na2.png" group-title="Развлекательные",2x2 (EDTV 576p)
|
||||
http://2.56.164.181/channel/3bdbd5d/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8383" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/7tv.png" group-title="Развлекательные",7 TV (EDTV 576p)
|
||||
http://2.56.164.181/channel/n6cedc370/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8263" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tv1-kg-hd.png" group-title="Развлекательные",TV1 KG (HD)
|
||||
http://2.56.164.181/channel/n754f4e8a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-340" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/e-tv.png" group-title="Развлекательные",E (HD)
|
||||
http://2.56.164.181/channel/bf1f73c/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100267" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/gags-network.png" group-title="Развлекательные",GagsNetwork (HD)
|
||||
http://2.56.164.181/channel/n66fe94fc/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-483" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tvmchannel.png" group-title="Развлекательные",TVM Channel (EDTV 576p)
|
||||
http://2.56.164.181/channel/5194e6a8/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-218" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/belarus2hd.png" group-title="Развлекательные",Беларусь 2 (HD)
|
||||
http://2.56.164.181/channel/227ed975/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8097" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/deviatka.png" group-title="Развлекательные",Девятка (HD)
|
||||
#EXTVLCOPT:http-user-agent=WINK/1.40.1 (AndroidTV/9) HlsWinkPlayer
|
||||
http://2.56.164.181/channel/n4535175f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 catchup="append" catchup-days="3" catchup-source="&offset=-${offset}&utcstart=${timestamp}" tvg-id="hlsproxy-246" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/domashny.png" group-title="Развлекательные",Домашний (EDTV 480p)
|
||||
#EXTVLCOPT:http-user-agent=WINK/1.40.1 (AndroidTV/9) HlsWinkPlayer
|
||||
http://2.56.164.181/channel/254e53e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-246" tvg-logo="http://epg.it999.ru/img2/304.png" group-title="Развлекательные",Домашний (HD)
|
||||
http://2.56.164.181/channel/3d1d31cd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-416" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/domashny-int.png" group-title="Развлекательные",Домашний Int (EDTV 576p)
|
||||
http://2.56.164.181/channel/5581685b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100325" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/zal-suda.png" group-title="Развлекательные",Зал суда (EDTV 576p)
|
||||
http://2.56.164.181/channel/n5e9f53cd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-7176" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kaleydoskop.png" group-title="Развлекательные",Калейдоскоп ТВ (EDTV 576p)
|
||||
http://2.56.164.181/channel/2276ca01/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-6059" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kluch.png" group-title="Развлекательные",Ключ (EDTV 576p)
|
||||
http://2.56.164.181/channel/n7619dcc0/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-680" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/perec.png" group-title="Развлекательные",Перец (EDTV 576p)
|
||||
http://2.56.164.181/channel/6c79aa15/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8071" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/prodvizhenie.png" group-title="Развлекательные",Продвижение (D1)
|
||||
http://2.56.164.181/channel/n7ac0f92b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-377" tvg-logo="http://epg.one/img2/1003.png" group-title="Развлекательные",Пятница! (EDTV 576p)
|
||||
http://2.56.164.181/channel/7f0749e5/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53848" tvg-logo="https://i.imgur.com/N2z3EZC.png" group-title="Развлекательные",Пятница! Int (EDTV 576p)
|
||||
http://2.56.164.181/channel/n4e176435/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-411" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sarafan.png" group-title="Развлекательные",Сарафан (EDTV 576p)
|
||||
http://2.56.164.181/channel/n61dfefd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-431" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/subbota.png" group-title="Развлекательные",Суббота (HD)
|
||||
http://2.56.164.181/channel/n7d032f19/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-51037" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/strk.png" group-title="Развлекательные",СТРК (HD ready)
|
||||
http://2.56.164.181/channel/4ab9355d/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 catchup="append" catchup-days="3" catchup-source="&offset=-${offset}&utcstart=${timestamp}" tvg-id="hlsproxy-407" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sts.png" group-title="Развлекательные",СТС (EDTV 480p)
|
||||
#EXTVLCOPT:http-user-agent=WINK/1.40.1 (AndroidTV/9) HlsWinkPlayer
|
||||
http://2.56.164.181/channel/n74f9526e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-407" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sts.png" group-title="Развлекательные",СТС (HD)
|
||||
http://2.56.164.181/channel/7e1ace47/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-409" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sts-love.png" group-title="Развлекательные",СТС Love (EDTV 576p)
|
||||
http://2.56.164.181/channel/38e985e4/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-408" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sts-int.png" group-title="Развлекательные",СТС Int (EDTV 576p)
|
||||
http://2.56.164.181/channel/n409bec4d/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-54686" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tvoyo-tv-hd.png" group-title="Развлекательные",Твоё ТВ (HD)
|
||||
http://2.56.164.181/channel/7676c4bb/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-54686" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tvoetv-humor.png" group-title="Развлекательные",Твоё ТВ Юмор (HD)
|
||||
http://2.56.164.181/channel/61b9c01f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-449" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/teatr.png" group-title="Развлекательные",Театр (EDTV 576p)
|
||||
http://2.56.164.181/channel/n1f38f1b7/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-518" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tochka-tv.png" group-title="Развлекательные",Точка ТВ (EDTV 576p)
|
||||
http://2.56.164.181/channel/n38beb1be/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 catchup="append" catchup-days="3" catchup-source="&offset=-${offset}&utcstart=${timestamp}" tvg-id="hlsproxy-439" tvg-logo="http://epg.it999.ru/img2/353.png" group-title="Развлекательные",ТНТ (EDTV 480p)
|
||||
#EXTVLCOPT:http-user-agent=WINK/1.40.1 (AndroidTV/9) HlsWinkPlayer
|
||||
http://2.56.164.181/channel/6a102e39/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-439" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tnt.png" group-title="Развлекательные",ТНТ (HD)
|
||||
http://2.56.164.181/channel/42c550d9/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-336" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tnt4.png" group-title="Развлекательные",ТНТ4 (EDTV 576p)
|
||||
http://2.56.164.181/channel/n1c12e518/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-6013" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/centralnoye-tv.png" group-title="Развлекательные",Центральное ТВ (EDTV 576p)
|
||||
http://2.56.164.181/channel/74d343/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-369" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/che.png" group-title="Развлекательные",Че! (EDTV 576p)
|
||||
http://2.56.164.181/channel/1a69b7cd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-474" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/yu.png" group-title="Развлекательные",Ю (HD ready)
|
||||
http://2.56.164.181/channel/1e1f8050/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-7" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/1hd-music.png" group-title="Музыкальные",1HD (HD)
|
||||
http://2.56.164.181/channel/n6ac424a3/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-44" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/bridge-tv.png" group-title="Музыкальные",Bridge (EDTV 576p)
|
||||
http://2.56.164.181/channel/n7454b039/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-180" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/bridge-tv-classic.png" group-title="Музыкальные",Bridge Classic (EDTV 576p)
|
||||
http://2.56.164.181/channel/nb771233/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-306" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/bridge-hd.png" group-title="Музыкальные",Bridge Deluxe (EDTV 576p)
|
||||
http://2.56.164.181/channel/n771f0bfc/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="bridge-tv-rock" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/bridge-tv-rock.png" group-title="Музыкальные",Bridge Rock (EDTV 576p)
|
||||
http://2.56.164.181/channel/n7ea954b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-57" tvg-logo="http://epg.one/img2/2024.png" group-title="Музыкальные",Bridge Hits (HD)
|
||||
http://2.56.164.181/channel/3153895a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-154" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/bridge-tv-ruxit.png" group-title="Музыкальные",Bridge Русский хит (EDTV 576p)
|
||||
http://2.56.164.181/channel/11680ba2/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-104" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/bridge-tv-shlager.png" group-title="Музыкальные",Bridge Шлягер (EDTV 576p)
|
||||
http://2.56.164.181/channel/n19a470f5/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-3073" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/clubbing-tv.png" group-title="Музыкальные",Clubbing TV (HD ready)
|
||||
http://2.56.164.181/channel/5b3a46dd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-119" tvg-logo="http://epg.one/img2/2409.png" group-title="Музыкальные",Music Box Russia (EDTV 576p)
|
||||
http://2.56.164.181/channel/n67020bbd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-351" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/o2tv.png" group-title="Музыкальные",О!2 (EDTV 576p)
|
||||
http://2.56.164.181/channel/47418fdd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-153" tvg-logo="http://epg.it999.ru/img2/2277.png" group-title="Музыкальные",RU TV (HD)
|
||||
http://2.56.164.181/channel/47ebaf0b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53632" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/zhar-ptica.png" group-title="Музыкальные",Жар-Птица (EDTV 480p)
|
||||
http://2.56.164.181/channel/n1335b8f1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-1500" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/zhara.png" group-title="Музыкальные",Жара (EDTV 576p)
|
||||
http://2.56.164.181/channel/1569ff7b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-302" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/maydan.png" group-title="Музыкальные",Майдан (EDTV 576p)
|
||||
#EXTVLCOPT:http-user-agent=WINK/1.40.1 (AndroidTV/9) HlsWinkPlayer
|
||||
http://2.56.164.181/channel/n294f7b38/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-301" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/muztv.png" group-title="Музыкальные",МузТВ (WSVGA)
|
||||
http://2.56.164.181/channel/6b210541/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-313" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/muzyka-pervogo.png" group-title="Музыкальные",Музыка Первого (EDTV 576p)
|
||||
http://2.56.164.181/channel/2032b2d1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="6266" tvg-logo="http://epg.one/img2/6266.png" group-title="Музыкальные",Музыка 1 Int (768×432)
|
||||
http://2.56.164.181/channel/4237bd6e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="6268" tvg-logo="http://epg.one/img2/6268.png" group-title="Музыкальные",Музыка 2 Int (768×432)
|
||||
http://2.56.164.181/channel/n63ecd851/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100199" tvg-logo="http://epg.one/img2/6270.png" group-title="Музыкальные",Музыка Кино Int (768×432)
|
||||
http://2.56.164.181/channel/n151e13a8/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-6012" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/radio-strana-fm-tv.png" group-title="Музыкальные",Страна FM (HD ready)
|
||||
http://2.56.164.181/channel/37606e7/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-30002" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tnt-music.png" group-title="Музыкальные",ТНТ Music (HD)
|
||||
http://2.56.164.181/channel/389da7dc/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-471" tvg-logo="http://epg.it999.ru/img2/2278.png" group-title="Музыкальные",Шансон ТВ (EDTV 576p)
|
||||
http://2.56.164.181/channel/641d8e36/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-163" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sony-turbo.png" group-title="Кинозал",.black (EDTV 576p)
|
||||
http://2.56.164.181/channel/n28d10f55/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-159" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sony.png" group-title="Кинозал",.red (EDTV 576p)
|
||||
http://2.56.164.181/channel/na0c3642/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-28" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sony-scifi.png" group-title="Кинозал",.sci-fi (EDTV 576p)
|
||||
http://2.56.164.181/channel/n54ea50c0/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-25" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/amedia1.png" group-title="Кинозал",Amedia 1 (EDTV 576p)
|
||||
http://2.56.164.181/channel/n4dc3261a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-26" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/amedia2.png" group-title="Кинозал",Amedia 2 (EDTV 576p)
|
||||
http://2.56.164.181/channel/n5f401f99/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-578" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/amedia-hit.png" group-title="Кинозал",Amedia Hit (HD)
|
||||
http://2.56.164.181/channel/63ef5693/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-31" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/amedia-premium.png" group-title="Кинозал",Amedia Premium (HD)
|
||||
http://2.56.164.181/channel/4c7afdcf/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-361" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/cinema.png" group-title="Кинозал",Cinema (EDTV 576p)
|
||||
http://2.56.164.181/channel/2c82fc91/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100587" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/timeless-dizi.png" group-title="Кинозал",Dizi (EDTV 576p)
|
||||
http://2.56.164.181/channel/3bc0429e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-55103" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/fanhd.png" group-title="Кинозал",FAN (EDTV 576p)
|
||||
http://2.56.164.181/channel/n73628843/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-81" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/fox.png" group-title="Кинозал",FX (EDTV 576p)
|
||||
http://2.56.164.181/channel/33522324/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-111" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/hollywood-hd.png" group-title="Кинозал",HollywooD (HD)
|
||||
http://2.56.164.181/channel/187218e1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53022" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kino-24.png" group-title="Кинозал",Kino 24 (EDTV 576p)
|
||||
http://2.56.164.181/channel/355a104f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100266" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kinojam2.png" group-title="Кинозал",Kinojam 2 (HD)
|
||||
http://2.56.164.181/channel/3b96d903/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="kinoliving" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kinoliving.png" group-title="Кинозал",KinoLiving (EDTV 576p)
|
||||
http://2.56.164.181/channel/n1ee676c7/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100559" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/plan-b.png" group-title="Кинозал",Plan B (HD)
|
||||
http://2.56.164.181/channel/2e167b36/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8196" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/pro100.png" group-title="Кинозал",Pro100 (EDTV 576p)
|
||||
http://2.56.164.181/channel/n61044cdc/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-2177" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/romance.png" group-title="Кинозал",Romance (HD)
|
||||
http://2.56.164.181/channel/n721c680/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-472" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/shot-tv.png" group-title="Кинозал",SHOT TV (EDTV 576p)
|
||||
http://2.56.164.181/channel/n6079f727/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100558" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/start-air.png" group-title="Кинозал",Start Air (HD)
|
||||
http://2.56.164.181/channel/7005eea5/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100557" tvg-logo="http://epg.it999.ru/img2/6240.png" group-title="Кинозал",Start World (HD)
|
||||
http://2.56.164.181/channel/16ab9edd/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-22" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tv1000-worldkino.png" group-title="Кинозал",Viasat Kino World (EDTV 480p)
|
||||
http://2.56.164.181/channel/n592f7a3f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="vhs-ka" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/vhs-ka.png" group-title="Кинозал",VHS-ка (HD)
|
||||
http://2.56.164.181/channel/n67380077/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-171" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tv1000.png" group-title="Кинозал",Viju TV1000 (HD)
|
||||
http://2.56.164.181/channel/4487cab/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-172" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tv1000-action.png" group-title="Кинозал",Viju TV1000 Action (EDTV 576p)
|
||||
http://2.56.164.181/channel/n6217aaee/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-173" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/vip-comedy.png" group-title="Кинозал",Viju+comedy (HD)
|
||||
http://2.56.164.181/channel/74a49f1a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-174" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/vip-megahit.png" group-title="Кинозал",Viju+megahit (HD)
|
||||
http://2.56.164.181/channel/711f39b6/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-175" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/vip-premiere.png" group-title="Кинозал",Viju+premiere (HD)
|
||||
http://2.56.164.181/channel/2c30d0ba/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-55135" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/vip-serial.png" group-title="Кинозал",Viju+serial (HD)
|
||||
http://2.56.164.181/channel/n7f9f64d8/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53747" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/dorama.png" group-title="Кинозал",Дорама (EDTV 576p)
|
||||
http://2.56.164.181/channel/n70212c81/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-253" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/eurokino.png" group-title="Кинозал",Еврокино (EDTV 576p)
|
||||
http://2.56.164.181/channel/5f7770b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-263" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/illuzion-plus.png" group-title="Кинозал",Иллюзион+ (EDTV 576p)
|
||||
http://2.56.164.181/channel/n28b8b8f0/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-604" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/russkaya-komedia.png" group-title="Кинозал",Комедия (EDTV 576p)
|
||||
http://2.56.164.181/channel/n6dd58062/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-283" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/komedijnoe.png" group-title="Кинозал",Комедийное (HD)
|
||||
http://2.56.164.181/channel/n6504ca3b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-1007012" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kineko.png" group-title="Кинозал",Кинеко (EDTV 576p)
|
||||
http://2.56.164.181/channel/n69a7f12a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="4780" tvg-logo="https://www.cityeden.info/logotv/logotip_kinodetektiv.png" group-title="Кинозал",КиноДетектив (HD ready)
|
||||
http://2.56.164.181/channel/ncb2caf4/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-290" tvg-logo="https://www.cityeden.info/logotv/logotip_siti_ehdem-kinokomedija.png" group-title="Кинозал",КиноКомедия (HD ready)
|
||||
http://2.56.164.181/channel/n2881dcac/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="4780" tvg-logo="https://www.cityeden.info/logotv/logotip_kinomostika.png" group-title="Кинозал",КиноМистика (nHD)
|
||||
http://2.56.164.181/channel/n6622988/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="4780" tvg-logo="https://www.cityeden.info/logotv/logotip_siti_ehdem-kinoehkshen2.png" group-title="Кинозал",КиноЭкшен (HD)
|
||||
http://2.56.164.181/channel/34213342/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-281" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kinopokaz.png" group-title="Кинозал",Кинопоказ (EDTV 576p)
|
||||
http://2.56.164.181/channel/3657af94/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="kino-bez-granic" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kino-bez-granic.png" group-title="Кинозал",Кино без границ (HD)
|
||||
http://2.56.164.181/channel/9eb0da9/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-794" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kinosat.png" group-title="Кинозал",Киноман (nHD)
|
||||
http://2.56.164.181/channel/n325cfcc9/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-279" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kino-tv.png" group-title="Кинозал",Кино ТВ (EDTV 576p)
|
||||
http://2.56.164.181/channel/387c8d32/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-385" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/lubimoe-kino.png" group-title="Кинозал",Любимое кино (EDTV 576p)
|
||||
http://2.56.164.181/channel/n1b7b0b7e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-344" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/nst.png" group-title="Кинозал",НСТ (EDTV 576p)
|
||||
http://2.56.164.181/channel/n61d7c9b2/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-576" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/ostrosiuzhetnoe-hd.png" group-title="Кинозал",Остросюжетное (HD)
|
||||
http://2.56.164.181/channel/5616f90e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-574" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/premialnoe-hd.png" group-title="Кинозал",Премиальное (HD)
|
||||
http://2.56.164.181/channel/n99f4877/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-390" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/retro-tv.png" group-title="Кинозал",Ретро (EDTV 576p)
|
||||
http://2.56.164.181/channel/n3f3ced9a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-1007010" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/sapfir.png" group-title="Кинозал",Сапфир (EDTV 576p)
|
||||
http://2.56.164.181/channel/n57c385c1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-282" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/shokiruyushchee-hd.png" group-title="Кинозал",Шокирующее (HD)
|
||||
http://2.56.164.181/channel/64fd460f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-55090" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/bolt.png" group-title="Русский кинозал",Bolt (EDTV 576p)
|
||||
http://2.56.164.181/channel/n6eb65573/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100265" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/kinojam1.png" group-title="Русский кинозал",Kinojam 1 (HD)
|
||||
http://2.56.164.181/channel/39e20064/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-55091" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/star-cinema.png" group-title="Русский кинозал",Star Cinema (EDTV 576p)
|
||||
http://2.56.164.181/channel/34d5eef1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-55092" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/star-family.png" group-title="Русский кинозал",Star Family (EDTV 576p)
|
||||
http://2.56.164.181/channel/n27cbd1c/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-429" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tv1000-russkoe-kino.png" group-title="Русский кинозал",Viju TV1000 Русское (EDTV 576p)
|
||||
http://2.56.164.181/channel/nfa44ac2/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100021" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/denpobedy.png" group-title="Русский кинозал",День Победы (HD)
|
||||
http://2.56.164.181/channel/n7de3cf08/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-244" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/domkino.png" group-title="Русский кинозал",Дом Кино (EDTV 576p)
|
||||
http://2.56.164.181/channel/n4c904b21/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-51107" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/domkino-premium.png" group-title="Русский кинозал",Дом кино Премиум (HD)
|
||||
http://2.56.164.181/channel/6f603b3/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-575" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/dushevnoe.png" group-title="Русский кинозал",Душевное (HD)
|
||||
http://2.56.164.181/channel/2bddd423/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="kino1int-tviksel" tvg-logo="http://epg.it999.ru/img2/6258.png" group-title="Русский кинозал",Кино 1 Int (480p)
|
||||
http://2.56.164.181/channel/d7c7d98/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-308" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/mir-seriala.png" group-title="Русский кинозал",Мир сериала (EDTV 576p)
|
||||
http://2.56.164.181/channel/n5cdad533/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100262" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/mosfilm.png" group-title="Русский кинозал",Мосфильм. Золотая коллекция (HD)
|
||||
http://2.56.164.181/channel/n26f58cd3/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-577" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/nashehd.png" group-title="Русский кинозал",Наше (HD)
|
||||
http://2.56.164.181/channel/n576deb5f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-212" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/ntv-xit.png" group-title="Русский кинозал",НТВ Хит (EDTV 576p)
|
||||
http://2.56.164.181/channel/47050326/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-55224" tvg-logo="http://epg.it999.ru/img2/2447.png" group-title="Русский кинозал",Победа (EDTV 576p)
|
||||
http://2.56.164.181/channel/67f9323b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-399" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/russky-bestseller.png" group-title="Русский кинозал",Русский бестселлер (EDTV 576p)
|
||||
http://2.56.164.181/channel/42afa308/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-400" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/russky-detektiv.png" group-title="Русский кинозал",Русский детектив (EDTV 576p)
|
||||
http://2.56.164.181/channel/n45be9966/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-401" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/russky-roman.png" group-title="Русский кинозал",Русский роман (HD)
|
||||
http://2.56.164.181/channel/n4c46c8b8/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-397" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/russky-illuzion.png" group-title="Русский кинозал",Русский иллюзион (EDTV 576p)
|
||||
http://2.56.164.181/channel/n68670784/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-452" tvg-logo="http://epg.it999.ru/img2/2304.png" group-title="Русский кинозал",Телекафе (EDTV 576p)
|
||||
http://2.56.164.181/channel/n2e08f71a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-464" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/feniks-plus-kino.png" group-title="Русский кинозал",Феникс плюс кино (HD)
|
||||
http://2.56.164.181/channel/2e9bfea8/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-51166" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/360-news.png" group-title="Новостные",360° Новости (HD)
|
||||
http://2.56.164.181/channel/n16147bfa/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-20151" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/izvestia.png" group-title="Новостные",Известия (HD)
|
||||
http://2.56.164.181/channel/n33a9bae6/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-51067" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/krik-tv.png" group-title="Новостные",Крик ТВ (HD)
|
||||
http://2.56.164.181/channel/16b5d0bf/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-393" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/rossia-24.png" group-title="Новостные",Россия 24 (WSVGA)
|
||||
http://2.56.164.181/channel/n7dd27c8c/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-380" tvg-logo="http://epg.it999.ru/img2/743.png" group-title="Новостные",РБК (HD)
|
||||
http://2.56.164.181/channel/6a9dd13d/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="solovjinypomiot" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/solovjinypomiot.png" group-title="Новостные",Соловьев.Live (HD)
|
||||
http://2.56.164.181/channel/n44e91628/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-75" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/extreme-sports.png" group-title="Спортивные",Extreme Sports (EDTV 576p)
|
||||
http://2.56.164.181/channel/3c9d260b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-72" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/eurosport1.png" group-title="Спортивные",Eurosport 1 (HD)
|
||||
http://2.56.164.181/channel/51d962ae/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-73" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/eurosport2.png" group-title="Спортивные",Eurosport 2 (HD)
|
||||
http://2.56.164.181/channel/n2c294ff9/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-398" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/russky-ekstrim.png" group-title="Спортивные",Russian Extreme (EDTV 576p)
|
||||
http://2.56.164.181/channel/2279da9/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-199" tvg-logo="http://epg.it999.ru/img2/2055.png" group-title="Спортивные",Viju+sport (HD)
|
||||
http://2.56.164.181/channel/n34e3fa15/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-221" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/belarus5hd.png" group-title="Спортивные",Беларусь 5 (HD)
|
||||
http://2.56.164.181/channel/n158cf5c/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-55018" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/belarus5-inet.png" group-title="Спортивные",Беларусь 5 Интернет (HD)
|
||||
http://2.56.164.181/channel/n6e009dca/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-587" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/konny-mir.png" group-title="Спортивные",Конный Мир (HD)
|
||||
http://2.56.164.181/channel/67f83eb/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-392" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/match-tv.png" group-title="Спортивные",Матч! (EDTV 576p)
|
||||
http://2.56.164.181/channel/n2d2c0fc8/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-55180" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/mir-basketbola.png" group-title="Спортивные",Мир баскетбола (HD)
|
||||
http://2.56.164.181/channel/n4ca4b598/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100272" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/footbolny.png" group-title="Спортивные",Мяч (HD)
|
||||
http://2.56.164.181/channel/783051b6/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53906" tvg-logo="http://epg.it999.ru/img2/2530.png" group-title="Спортивные",Старт (HD)
|
||||
http://2.56.164.181/channel/n76837d05/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="start-triumf" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/start-triumf.png" group-title="Спортивные",Старт Триумф (HD ready)
|
||||
http://2.56.164.181/channel/ad9f50a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-1333" tvg-logo="http://epg.one/img2/2782.png" group-title="Спортивные",Футбол (WSVGA)
|
||||
http://2.56.164.181/channel/685dad47/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8005" tvg-logo="http://epg.one/img2/2136.png" group-title="Христианские",Life TV (432p)
|
||||
http://2.56.164.181/channel/7dcc6cd1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-9135" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/nadezhda.png" group-title="Христианские",Надежда (HD ready)
|
||||
http://2.56.164.181/channel/n62d79ac6/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-547" tvg-logo="http://epg.it999.ru/img2/2413.png" group-title="Христианские",МузСоюз (WSVGA)
|
||||
http://2.56.164.181/channel/n76084609/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-418" tvg-logo="http://epg.it999.ru/img2/2448.png" group-title="Христианские",Союз (HD)
|
||||
http://2.56.164.181/channel/7fcf6843/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-419" tvg-logo="http://epg.it999.ru/img2/2141.png" group-title="Христианские",Спас (WSVGA)
|
||||
http://2.56.164.181/channel/59262060/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-50249" tvg-logo="http://epg.it999.ru/img2/2469.png" group-title="Христианские",Три Ангела (HD)
|
||||
http://2.56.164.181/channel/5bddbc5/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-34" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/animal-planet-eu.png" group-title="Познавательные",Animal Planet (HD)
|
||||
http://2.56.164.181/channel/1babdb8a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100684" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/big-planet.png" group-title="Познавательные",Big Planet (EDTV 576p)
|
||||
http://2.56.164.181/channel/n7064b6e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-61" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/discovery-channel.png" group-title="Познавательные",Discovery (HD)
|
||||
http://2.56.164.181/channel/n510da8ca/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-87" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/galaxy-tv.png" group-title="Познавательные",Galaxy TV (EDTV 576p)
|
||||
http://2.56.164.181/channel/n27691a00/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-101" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/idxtra.png" group-title="Познавательные",ID (HD)
|
||||
http://2.56.164.181/channel/n44111497/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-51532" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/nat-geo-wild.png" group-title="Познавательные",Nat Geo Wild (EDTV 576p)
|
||||
http://2.56.164.181/channel/6aa98390/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-54514" nano-hd" tvg-logo="https://iptvx.one/picons/nano-hd.png" group-title="Познавательные" tvg-logo="http://2.56.164.181/logos/nano-hd.png" group-title="Knowledge",Нано (WSVGA)
|
||||
#EXTGRP:Knowledge
|
||||
http://2.56.164.181/channel/299819ea/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-150" tvg-logo="http://epg.it999.ru/img2/648.png" group-title="Познавательные",RTG (HD)
|
||||
http://2.56.164.181/channel/792bf505/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-417" tvg-logo="http://epg.it999.ru/img2/275.png" group-title="Познавательные",Top Secret (EDTV 576p)
|
||||
http://2.56.164.181/channel/5032e937/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-1007013" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/terra-ru.png" group-title="Познавательные",TERRA (EDTV 576p)
|
||||
http://2.56.164.181/channel/7e26b499/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-611" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/univer-tv.png" group-title="Познавательные",UNIVER (WSVGA)
|
||||
http://2.56.164.181/channel/687d7c6/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-196" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/viasat-history.png" group-title="Познавательные",Viju HISTORY (EDTV 576p)
|
||||
http://2.56.164.181/channel/n2b417bf6/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-197" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/viasat-nature.png" group-title="Познавательные",Viju NATURE (EDTV 576p)
|
||||
http://2.56.164.181/channel/n61f55887/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-198" tvg-logo="http://epg.it999.ru/img2/2012.png" group-title="Познавательные",Viju+planet (HD)
|
||||
http://2.56.164.181/channel/n308b753c/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-262" tvg-logo="http://epg.it999.ru/img2/367.png" group-title="Познавательные",ZOOПАРК (EDTV 576p)
|
||||
http://2.56.164.181/channel/5a100a0f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-1993" tvg-logo="http://epg.it999.ru/img2/2768.png" group-title="Познавательные",Арсенал (HD)
|
||||
http://2.56.164.181/channel/3c7c1e9b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-220" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/belarus3hd.png" group-title="Познавательные",Беларусь 3 (EDTV 576p)
|
||||
http://2.56.164.181/channel/n6fda8839/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100025" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/v-mire-zhivotnyx.png" group-title="Познавательные",В мире животных (HD ready)
|
||||
http://2.56.164.181/channel/10938d68/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-230" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/voprosy-i-otvety.png" group-title="Познавательные",Вопросы и ответы (EDTV 576p)
|
||||
http://2.56.164.181/channel/3e93e59d/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-421" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/zhivaya-planeta.png" group-title="Познавательные",Живая Планета (EDTV 576p)
|
||||
http://2.56.164.181/channel/70d692d3/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-423" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/zhivaya-priroda.png" group-title="Познавательные",Живая Природа (HD)
|
||||
http://2.56.164.181/channel/ndc7597f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-261" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/zootv.png" group-title="Познавательные",Зоо ТВ (EDTV 576p)
|
||||
http://2.56.164.181/channel/n5f8df74c/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-326" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/istoria.png" group-title="Познавательные",История (SDTV 576i)
|
||||
http://2.56.164.181/channel/4370aa45/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-2250" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/mir-uvlecheniy.png" group-title="Познавательные",#КТОКУДА (EDTV 576p)
|
||||
http://2.56.164.181/channel/25534224/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8215" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/nauka-20.png" group-title="Познавательные",Наука (HD)
|
||||
http://2.56.164.181/channel/7073bb49/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-311" group-title="Познавательные" tvg-logo="http://2.56.164.181/logos/moya-planeta.png",Моя Планета (EDTV 576p)
|
||||
http://2.56.164.181/channel/1146cb8d/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-138" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/ocean-tv.png" group-title="Познавательные",ОКЕАН (EDTV 576p)
|
||||
http://2.56.164.181/channel/n65a87af4/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-69" tvg-logo="http://epg.it999.ru/img2/2310.png" group-title="Познавательные",Первый Космический (HD)
|
||||
http://2.56.164.181/channel/n1d15f0ce/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-867" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/poexali.png" group-title="Познавательные",Поехали! (EDTV 576p)
|
||||
http://2.56.164.181/channel/b8fd52c/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-375" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/prosveschenie.png" group-title="Познавательные",Просвещение (720×540)
|
||||
http://2.56.164.181/channel/n204b4153/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-376" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/psixologia-21.png" group-title="Познавательные",Психология (EDTV 576p)
|
||||
http://2.56.164.181/channel/77600009/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 id="187" tvg-logo="http://epg.it999.ru/img2/187.png" group-title="Познавательные" tvg-id="hlsproxy-395",Россия К (HD)
|
||||
http://2.56.164.181/channel/20009b0/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 audio-track="rus" tvg-id="hlsproxy-8088" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tlc.png" group-title="Хобби и увлечения",TLC (EDTV 576p)
|
||||
http://2.56.164.181/channel/n147c566b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-194" tvg-logo="http://epg.it999.ru/img2/521.png" group-title="Хобби и увлечения",Viju EXPLORE (EDTV 576p)
|
||||
http://2.56.164.181/channel/4f829389/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-286" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/bober.png" group-title="Хобби и увлечения",Бобёр (EDTV 576p)
|
||||
http://2.56.164.181/channel/n120b4d93/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-1131" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/glazami-turista.png" group-title="Досуг",Глазами туриста (WSVGA)
|
||||
http://2.56.164.181/channel/n7f5a063a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-52975" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/dialogi-o-rybalke.png" group-title="Хобби и увлечения",Диалоги о рыбалке (EDTV 576p)
|
||||
http://2.56.164.181/channel/537d84cc/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-9" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/doktor.png" group-title="Хобби и увлечения",Доктор (EDTV 576p)
|
||||
http://2.56.164.181/channel/n1881f313/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-245" tvg-logo="http://epg.it999.ru/img2/520.png" group-title="Хобби и увлечения",Домашние Животные (EDTV 576p)
|
||||
http://2.56.164.181/channel/3e76b10d/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53817" tvg-logo="http://epg.it999.ru/img2/2483.png" group-title="Хобби и увлечения",Дикая Охота (HD)
|
||||
http://2.56.164.181/channel/n4af1e159/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53818" tvg-logo="http://epg.it999.ru/img2/2484.png" group-title="Хобби и увлечения",Дикая Рыбалка (HD)
|
||||
http://2.56.164.181/channel/n5004b31b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53816" tvg-logo="http://epg.it999.ru/img2/2283.png" group-title="Хобби и увлечения",Дикий (EDTV 576p)
|
||||
http://2.56.164.181/channel/781cffcc/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-248" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/drive.png" group-title="Хобби и увлечения",ДРАЙВ (EDTV 576p)
|
||||
http://2.56.164.181/channel/n7c541f08/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-249" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/eda.png" group-title="Хобби и увлечения",Еда (nHD)
|
||||
http://2.56.164.181/channel/n1c713522/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-256" tvg-logo="http://epg.it999.ru/img2/5881.png" group-title="Хобби и увлечения",Живи Активно (HD)
|
||||
http://2.56.164.181/channel/n3796a2c2/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-257" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/zagorodnaya-zhizn.png" group-title="Хобби и увлечения",Загородная Жизнь (EDTV 576p)
|
||||
http://2.56.164.181/channel/n25c4c574/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-258" tvg-logo="http://epg.it999.ru/img2/2463.png" group-title="Хобби и увлечения",Загородный (480p)
|
||||
http://2.56.164.181/channel/n641e82b8/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-54555" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/zagorodny-int.png" group-title="Хобби и увлечения",Загородный Int (HD)
|
||||
http://2.56.164.181/channel/70f2163b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-260" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/zdorovoe-tv.png" group-title="Хобби и увлечения",Здоровое ТВ (EDTV 576p)
|
||||
http://2.56.164.181/channel/n6d31780e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="lapki-live" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/lapki-live.png" group-title="Хобби и увлечения",Лапки Live (EDTV 576p)
|
||||
http://2.56.164.181/channel/n3dc4a4b3/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-312" tvg-logo="http://epg.it999.ru/img2/2444.png" group-title="Хобби и увлечения",Мужской (EDTV 576p)
|
||||
http://2.56.164.181/channel/13a4c091/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-54166" tvg-logo="http://epg.it999.ru/img2/2433.png" group-title="Хобби и увлечения",Наша Тема (EDTV 576p)
|
||||
http://2.56.164.181/channel/60d1103e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8191" tvg-logo="http://epg.it999.ru/img2/1755.png" group-title="Хобби и увлечения",НТВ Стиль (EDTV 576p)
|
||||
http://2.56.164.181/channel/2591313f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-50276" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/otkryty-mir.png" group-title="Хобби и увлечения",Открытый мир (WSVGA)
|
||||
http://2.56.164.181/channel/4252b47f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-358" tvg-logo="http://epg.it999.ru/img2/2419.png" group-title="Хобби и увлечения",ОХОТА И РЫБАЛКА (EDTV 576p)
|
||||
http://2.56.164.181/channel/33ba513f/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-455" tvg-logo="http://epg.it999.ru/img2/2311.png" group-title="Хобби и увлечения",Приключения (WSVGA)
|
||||
http://2.56.164.181/channel/n34c8aa9d/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-359" tvg-logo="http://epg.one/img2/6646.png" group-title="Хобби и увлечения",Рыболов (EDTV 576p)
|
||||
http://2.56.164.181/channel/4265ce32/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8341" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/svetloe-tv.png" group-title="Хобби и увлечения",Светлое ТВ (EDTV 576p)
|
||||
http://2.56.164.181/channel/n2739d225/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-458" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/tonus-tv.png" group-title="Хобби и увлечения",Тонус (SDTV 576p)
|
||||
http://2.56.164.181/channel/4c9be80b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53833" tvg-logo="http://epg.it999.ru/img2/617.png" group-title="Хобби и увлечения",Точка Отрыва (EDTV 576p)
|
||||
http://2.56.164.181/channel/n138cb812/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-462" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/usadba.png" group-title="Хобби и увлечения",Усадьба (EDTV 576p)
|
||||
http://2.56.164.181/channel/n2df28637/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-6" tvg-logo="http://epg.it999.ru/img2/5841.png" group-title="Региональные",12 Канал (Омск) (WSVGA)
|
||||
http://2.56.164.181/channel/2818e0bb/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-545" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/astraxan24.png" group-title="Региональные",Астрахань 24 (HD)
|
||||
http://2.56.164.181/channel/df31056/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-224" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/brianskaya-gubernia.png" group-title="Региональные",Брянская губерния (HD)
|
||||
#EXTVLCOPT:http-user-agent=WINK/1.40.1 (AndroidTV/9) HlsWinkPlayer
|
||||
http://2.56.164.181/channel/2096b9e8/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-10152" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/vetta24.png" group-title="Региональные",Ветта 24 (Пермь) (EDTV 480p)
|
||||
http://2.56.164.181/channel/357faa02/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-229" tvg-logo="http://epg.it999.ru/img2/2468.png" group-title="Региональные",Волга (Нижний Новгород) (HD)
|
||||
http://2.56.164.181/channel/n2d36e625/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8069" tvg-logo="https://i.imgur.com/gFMnaU5.png" group-title="Региональные",Волгоград 24 (HD)
|
||||
http://2.56.164.181/channel/n2537eb99/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-53856" tvg-logo="https://i.imgur.com/zMNJfoV.png" group-title="Региональные",Городской телеканал Ярославль (EDTV 576p)
|
||||
http://2.56.164.181/channel/n17cef9d2/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-235" tvg-logo="https://i.imgur.com/IlL57Rm.png" group-title="Региональные",Губерния (Самара) (WSVGA)
|
||||
http://2.56.164.181/channel/3bfa9218/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-6046" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/don-24.png" group-title="Региональные",Дон 24 (Ростов-на-Дону) (nHD)
|
||||
http://2.56.164.181/channel/7153714e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-254" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/enisey-region.png" group-title="Региональные",Енисей (Красноярск) (HD)
|
||||
http://2.56.164.181/channel/27fa2b72/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-7149" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/krasnodar.png" group-title="Региональные",Краснодар (HD)
|
||||
http://2.56.164.181/channel/6b3767ff/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-598" tvg-logo="http://epg.it999.ru/img2/5810.png" group-title="Региональные",Липецкое время (HD ready)
|
||||
http://2.56.164.181/channel/n6a2dd0fe/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-310" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/moskva-24.png" group-title="Региональные",МОСКВА24 (EDTV 576p)
|
||||
http://2.56.164.181/channel/n7ffcbbca/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-242" tvg-logo="http://epg.one/img2/2308.png" group-title="Региональные",Москва Доверие (WSVGA)
|
||||
http://2.56.164.181/channel/134d54bc/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-12021" tvg-logo="http://epg.it999.ru/img2/6767.png" group-title="Региональные",МТВ (Волгоград) (HD ready)
|
||||
http://2.56.164.181/channel/546e1d21/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-316" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/saxa.png" group-title="Региональные",НВК Саха (HD)
|
||||
http://2.56.164.181/channel/n72ad94a6/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-671" tvg-logo="https://i.imgur.com/ZWgPVIC.png" group-title="Региональные",Нижний Новгород 24 (HD)
|
||||
http://2.56.164.181/channel/n33e1abac/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-682" tvg-logo="http://epg.it999.ru/img2/4628.png" group-title="Региональные",Новый Век (Тамбов) (HD ready)
|
||||
http://2.56.164.181/channel/n430e964e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-226" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/ntm.png" group-title="Региональные",НТМ (Саранск) (HD ready)
|
||||
http://2.56.164.181/channel/n6870acf9/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-2657" tvg-logo="http://epg.it999.ru/img2/6763.png" group-title="Региональные",РТВ (Раменск) (HD ready)
|
||||
http://2.56.164.181/channel/63bbb704/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-54195" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/region29.png" group-title="Региональные",Регион 29 (Архангельск) (HD ready)
|
||||
http://2.56.164.181/channel/ne75a71e/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-6061" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/svoyo-tv-stavropol.png" group-title="Региональные",Своё ТВ (Ставрополь) (HD)
|
||||
http://2.56.164.181/channel/8a8d179/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-7209" logo="https://iptvx.one/picons/s1-surgut.png" tvg-logo="https://dl.dropboxusercontent.com/s/nfbxgikry7p0xd6/surgut1.jpg" group-title="Regional",С1 (Сургут) (WSVGA)
|
||||
#EXTGRP:Regional
|
||||
http://2.56.164.181/channel/n68cc2f7a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8199" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/russky-sever.png" group-title="Региональные",Русский Север (Вологда) (HD)
|
||||
#EXTVLCOPT:http-user-agent=ExoPlayer2/2.37
|
||||
http://2.56.164.181/channel/43052b38/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-410" tvg-logo="http://epg.it999.ru/img2/690.png" group-title="Региональные",Санкт-Петербург (HD)
|
||||
http://2.56.164.181/channel/af429d6/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-54764" tvg-logo="http://epg.it999.ru/img2/6794.png" group-title="Региональные",Саров 24 (HD ready)
|
||||
http://2.56.164.181/channel/n3162b623/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-8475" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/insit-tv.png" group-title="Региональные",ЮУрГУ (Челябинск) (HD ready)
|
||||
http://2.56.164.181/channel/n7ecd9d31/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100142" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/avtoradio.png" group-title="Радио",Авторадио
|
||||
http://2.56.164.181/channel/fc4427a/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="dorozhnoe-radio" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/dorozhnoe-radio.png" group-title="Радио",Дорожное Радио
|
||||
http://2.56.164.181/channel/n4d8d9eb8/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-logo="https://toplogos.ru/images/thumbs/preview-logo-nashe-radio.png" group-title="Радио" tvg-id="hlsproxy-318",Наше радио
|
||||
http://2.56.164.181/channel/54c5e278/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100144" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/radio-dfm.png" group-title="Радио",Радио DFM
|
||||
http://2.56.164.181/channel/n312b050b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-51342" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/radio-mayak.png" group-title="Радио",Радио Маяк
|
||||
http://2.56.164.181/channel/n563163df/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100149" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/radio-mir.png" group-title="Радио",Радио Мир
|
||||
http://2.56.164.181/channel/n39e8e29b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="radio-na7xolmax" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/radio-na7xolmax.png" group-title="Радио",Радио на семи холмах
|
||||
http://2.56.164.181/channel/6e423960/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100155" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/radio-romantika.png" group-title="Радио",Радио Романтика
|
||||
http://2.56.164.181/channel/n6294a2d1/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-51167" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/radio-shanson.png" group-title="Радио",Радио Шансон
|
||||
http://2.56.164.181/channel/n18a8c5b4/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100156" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/radio-vania.png" group-title="Радио",Радио Ваня
|
||||
http://2.56.164.181/channel/57e84891/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100161" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/retro-fm.png" group-title="Радио",Ретро FM
|
||||
http://2.56.164.181/channel/n4a2363ac/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-618" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/xit-fm.png" group-title="Радио",Хит FM
|
||||
http://2.56.164.181/channel/n59e53757/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4
|
||||
#EXTINF:-1 tvg-id="hlsproxy-100162" tvg-logo="http://2.56.164.181/proxy/https://iptvx.one/picons/yumor-fm.png" group-title="Радио",Юмор FM
|
||||
http://2.56.164.181/channel/n1397fe5b/index.m3u8?q=94526308885ae17c240c4b63ace7ffe4#EXTINF:0 group-title="Anime" tvg-id="anime-tv" tvg-logo="https://assets-iptv2022.cdnvideo.ru/static/channel/15569/logo_256_1668760387.png" tvg-rec="0",Anime TV
|
||||
#EXTGRP:Anime
|
||||
https://free-tv.me/iptv/catcats/35676
|
||||
#EXTINF:0 group-title="Anime" tvg-id="anime-tv" tvg-logo="https://assets-iptv2022.cdnvideo.ru/static/channel/15569/logo_256_1668760387.png" tvg-rec="0",Anime TV2
|
||||
#EXTGRP:Anime
|
||||
https://free-tv.me/iptv/catcats/40954
|
||||
#EXTINF:0 group-title="Anime" tvg-id="anime-tv" tvg-logo="https://assets-iptv2022.cdnvideo.ru/static/channel/15569/logo_256_1668760387.png" tvg-rec="0",Anime TV3
|
||||
#EXTGRP:Anime
|
||||
https://free-tv.me/iptv/catcats/36798
|
||||
#EXTINF:0 group-title="Anime" tvg-id="anime-tv" tvg-logo="https://assets-iptv2022.cdnvideo.ru/static/channel/15569/logo_256_1668760387.png" tvg-rec="0",Anime TV4
|
||||
#EXTGRP:Anime
|
||||
https://free-tv.me/iptv/catcats/37524
|
||||
#EXTINF:0 group-title="Anime" tvg-id="anime-tv" tvg-logo="https://assets-iptv2022.cdnvideo.ru/static/channel/15569/logo_256_1668760387.png" tvg-rec="0",Anime TV5
|
||||
#EXTGRP:Anime
|
||||
https://free-tv.me/iptv/catcats/38311
|
||||
#EXTINF:0 group-title="Anime" tvg-id="anime-tv" tvg-logo="https://img.catcast.tv/uploads/28042024/logos/46775-662e075a0f6a2.png" tvg-rec="0",Том и Джери
|
||||
#EXTGRP:Anime
|
||||
https://free-tv.me/iptv/catcats/46775
|
||||
#EXTINF:0 group-title="Новости" tvg-id="news" tvg-logo="https://cdn-st1.smotrim.ru/vh/pictures/svg/486/730/4.svg" tvg-rec="0",Соловьев LIVE
|
||||
#EXTGRP:Новости
|
||||
https://player.smotrim.ru/iframe/stream/live_id/63338
|
||||
#EXTINF:0 group-title="Anime" tvg-id="anime-tv" tvg-logo="https://img.catcast.tv/uploads/31102020/logos/39373-5f9dbfc65b650.png" tvg-rec="0",Jetix
|
||||
#EXTGRP:Anime
|
||||
https://free-tv.me/iptv/catcats/39373
|
||||
#EXTINF:0 group-title="fun" tvg-id="fun" tvg-logo="https://img.catcast.tv/uploads/24122020/logos/39567-5fe497beed5c2.png" tvg-rec="0",Наша Russia
|
||||
#EXTGRP:Развлечение
|
||||
https://free-tv.me/iptv/catcats/39567
|
||||
#EXTINF:0 group-title="fun" tvg-id="fun" tvg-logo="https://img.smotreshka.tv/image/aHR0cDovL2ltZy5iNjEyLnRpZ2h0dmlkZW8uY29tL2NoYW5uZWxzL3N0c19raWRzX25ldy5wbmc=?width=270&height=150" tvg-rec="0",CTC Kids
|
||||
#EXTGRP:Развлечение
|
||||
http://stream02.vnet.am/DisneyChannel/mono.m3u8
|
||||
#EXTINF:0 group-title="fun" tvg-id="fun" tvg-logo="https://epgx.site/p/sts-love.png" tvg-rec="0",CTC Love
|
||||
#EXTGRP:Развлечение
|
||||
http://178.212.71.253:8002/play/a00r/index.m3u8
|
||||
#EXTINF:0 group-title="fun" tvg-id="fun" tvg-logo="https://epgx.site/p/cartoon-network.png" tvg-rec="0",Cartoon Network
|
||||
#EXTGRP:Развлечение
|
||||
http://stream01.vnet.am/Kinosemya/tracks-v1a1/mono.m3u8
|
||||
#EXTINF:0 group-title="fun" tvg-id="fun" tvg-logo="https://epgx.site/p/ani.png" tvg-rec="0",Ani
|
||||
#EXTGRP:Развлечение
|
||||
http://stv.mediacdn.ru/live/cdn/ani/playlist_sdhigher.m3u8
|
||||
6343
src/svc-checker/rowdy.json
Normal file
15
src/svc-main/.env.example
Normal file
@@ -0,0 +1,15 @@
|
||||
APP_TITLE='Плейлисты IPTV'
|
||||
APP_URL=http://localhost:${IPTV_NGNIX_PORT}
|
||||
|
||||
TWIG_CACHE=1
|
||||
TWIG_DEBUG=0
|
||||
|
||||
FLIGHT_CASE_SENSITIVE=0
|
||||
FLIGHT_HANDLE_ERRORS=1
|
||||
FLIGHT_LOG_ERRORS=1
|
||||
|
||||
REDIS_HOST=iptv-keydb
|
||||
REDIS_PORT=6379
|
||||
REDIS_DB=0
|
||||
REDIS_USER=
|
||||
REDIS_PASS=
|
||||
10
src/svc-main/.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
vendor/
|
||||
cache/
|
||||
|
||||
views/custom.twig
|
||||
playlists.ini
|
||||
commit
|
||||
*.log
|
||||
.env
|
||||
|
||||
!/**/.gitkeep
|
||||
32
src/svc-main/composer.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"require": {
|
||||
"php": "^8.4",
|
||||
"ext-json": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-redis": "*",
|
||||
"mikecao/flight": "^3.12",
|
||||
"symfony/dotenv": "^7.1",
|
||||
"twig/twig": "^3.14"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Core\\": "core/",
|
||||
"Controllers\\": "controllers/",
|
||||
"Exceptions\\": "exceptions/"
|
||||
},
|
||||
"files": [
|
||||
"helpers.php"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"clear-views": "rm -rf cache/views",
|
||||
"post-install-cmd": [
|
||||
"@clear-views"
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
552
src/svc-main/composer.lock
generated
Normal file
@@ -0,0 +1,552 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "4d763eef27bbfd40014e392726e5afc1",
|
||||
"packages": [
|
||||
{
|
||||
"name": "mikecao/flight",
|
||||
"version": "v3.13.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/flightphp/core.git",
|
||||
"reference": "1307e8a39d89fadba69d0c2dad53b6e0da83fd96"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/flightphp/core/zipball/1307e8a39d89fadba69d0c2dad53b6e0da83fd96",
|
||||
"reference": "1307e8a39d89fadba69d0c2dad53b6e0da83fd96",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": ">=7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-pdo_sqlite": "*",
|
||||
"flightphp/runway": "^0.2.3 || ^1.0",
|
||||
"league/container": "^4.2",
|
||||
"level-2/dice": "^4.0",
|
||||
"phpstan/extension-installer": "^1.3",
|
||||
"phpstan/phpstan": "^1.10",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"rregeer/phpunit-coverage-check": "^0.3.1",
|
||||
"squizlabs/php_codesniffer": "^3.8"
|
||||
},
|
||||
"suggest": {
|
||||
"latte/latte": "Latte template engine",
|
||||
"phpstan/phpstan": "PHP Static Analyzer",
|
||||
"tracy/tracy": "Tracy debugger"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"flight/autoload.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mike Cao",
|
||||
"email": "mike@mikecao.com",
|
||||
"homepage": "http://www.mikecao.com/",
|
||||
"role": "Original Developer"
|
||||
},
|
||||
{
|
||||
"name": "Franyer Sánchez",
|
||||
"email": "franyeradriansanchez@gmail.com",
|
||||
"homepage": "https://faslatam.000webhostapp.com",
|
||||
"role": "Maintainer"
|
||||
},
|
||||
{
|
||||
"name": "n0nag0n",
|
||||
"email": "n0nag0n@sky-9.com",
|
||||
"role": "Maintainer"
|
||||
}
|
||||
],
|
||||
"description": "Flight is a fast, simple, extensible framework for PHP. Flight enables you to quickly and easily build RESTful web applications. This is the maintained fork of mikecao/flight",
|
||||
"homepage": "http://flightphp.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/flightphp/core/issues",
|
||||
"source": "https://github.com/flightphp/core/tree/v3.13.0"
|
||||
},
|
||||
"time": "2024-10-30T19:52:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v3.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6",
|
||||
"reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.5-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"function.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-25T14:20:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/dotenv",
|
||||
"version": "v7.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/dotenv.git",
|
||||
"reference": "28347a897771d0c28e99b75166dd2689099f3045"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/dotenv/zipball/28347a897771d0c28e99b75166dd2689099f3045",
|
||||
"reference": "28347a897771d0c28e99b75166dd2689099f3045",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.2"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/console": "<6.4",
|
||||
"symfony/process": "<6.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "^6.4|^7.0",
|
||||
"symfony/process": "^6.4|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Dotenv\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Registers environment variables from a .env file",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"dotenv",
|
||||
"env",
|
||||
"environment"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/dotenv/tree/v7.2.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-11-27T11:18:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gert de Pagter",
|
||||
"email": "BackEndTea@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for ctype functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"ctype",
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
|
||||
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php81",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php81.git",
|
||||
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
|
||||
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php81\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.17.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "677ef8da6497a03048192aeeb5aa3018e379ac71"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/677ef8da6497a03048192aeeb5aa3018e379ac71",
|
||||
"reference": "677ef8da6497a03048192aeeb5aa3018e379ac71",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-ctype": "^1.8",
|
||||
"symfony/polyfill-mbstring": "^1.3",
|
||||
"symfony/polyfill-php81": "^1.29"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"psr/container": "^1.0|^2.0",
|
||||
"symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Resources/core.php",
|
||||
"src/Resources/debug.php",
|
||||
"src/Resources/escaper.php",
|
||||
"src/Resources/string_loader.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Twig\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Twig Team",
|
||||
"role": "Contributors"
|
||||
},
|
||||
{
|
||||
"name": "Armin Ronacher",
|
||||
"email": "armin.ronacher@active-4.com",
|
||||
"role": "Project Founder"
|
||||
}
|
||||
],
|
||||
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||
"homepage": "https://twig.symfony.com",
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.17.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-12T09:58:10+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": "^8.4",
|
||||
"ext-json": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-redis": "*"
|
||||
},
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
30
src/svc-main/config.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
// https://flightphp.com/learn#configuration
|
||||
'flight.base_url' => env('APP_URL', 'http://localhost:' . env('IPTV_NGNIX_PORT')),
|
||||
'flight.case_sensitive' => bool(env('FLIGHT_CASE_SENSITIVE', false)),
|
||||
'flight.handle_errors' => bool(env('FLIGHT_HANDLE_ERRORS', true)),
|
||||
'flight.log_errors' => bool(env('FLIGHT_LOG_ERRORS', true)),
|
||||
'flight.views.path' => views_path(),
|
||||
'flight.views.extension' => '.twig',
|
||||
|
||||
'twig.cache' => bool(env('TWIG_CACHE', true)) ? cache_path() . '/views' : false,
|
||||
'twig.debug' => bool(env('TWIG_DEBUG', false)),
|
||||
|
||||
'app.title' => env('APP_TITLE', 'IPTV Playlists'),
|
||||
'app.pls_encodings' => [
|
||||
'UTF-8',
|
||||
'CP1251',
|
||||
// 'CP866',
|
||||
// 'ISO-8859-5',
|
||||
],
|
||||
|
||||
'redis.host' => env('REDIS_HOST', 'iptv-keydb'),
|
||||
'redis.port' => (int)env('REDIS_PORT', 6379),
|
||||
// 'redis.user' => env('REDIS_USER'),
|
||||
// 'redis.password' => env('REDIS_PASS'),
|
||||
'redis.database' => (int)env('REDIS_DB', 0),
|
||||
];
|
||||
85
src/svc-main/controllers/Controller.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Controllers;
|
||||
|
||||
use Core\IniFile;
|
||||
use Core\Playlist;
|
||||
use Exception;
|
||||
use Exceptions\PlaylistNotFoundException;
|
||||
use Flight;
|
||||
use Random\RandomException;
|
||||
|
||||
/**
|
||||
* Абстрактный контроллер для расширения
|
||||
*/
|
||||
abstract class Controller
|
||||
{
|
||||
/**
|
||||
* @var IniFile Класс для работы с ini-файлом плейлистов
|
||||
*/
|
||||
protected IniFile $ini;
|
||||
|
||||
/**
|
||||
* Конструктор
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->ini = Flight::get('ini');
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает плейлист по его ID для обработки
|
||||
*
|
||||
* @param string $id
|
||||
* @param bool $asJson
|
||||
* @return Playlist
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getPlaylist(string $id, bool $asJson = false): Playlist
|
||||
{
|
||||
if ($this->ini->getRedirection($id)) {
|
||||
Flight::redirect(base_url($this->ini->getRedirection($id) . ($asJson ? '/json' : '/details')));
|
||||
die;
|
||||
}
|
||||
|
||||
try {
|
||||
return $this->ini->getPlaylist($id);
|
||||
} catch (PlaylistNotFoundException) {
|
||||
$this->notFound($id, $asJson);
|
||||
die;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает обработанный плейлист для ответа
|
||||
*
|
||||
* @param string $id ID плейлиста
|
||||
* @param bool $asJson Обрабатывать как json
|
||||
* @return array
|
||||
* @throws RandomException
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function getPlaylistResponse(string $id, bool $asJson = false): array
|
||||
{
|
||||
$playlist = $this->getPlaylist($id, $asJson);
|
||||
$playlist->download();
|
||||
$playlist->parse();
|
||||
return $playlist->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Перебрасывает на страницу 404 при ненайденном плейлисте
|
||||
*
|
||||
* @param string $id ID плейлиста
|
||||
* @param bool $asJson Обрабатывать как json
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function notFound(string $id, bool $asJson = false): void
|
||||
{
|
||||
Flight::response()->status(404)->sendHeaders();
|
||||
$asJson || view('notfound', ['id' => $id]);
|
||||
}
|
||||
}
|
||||
62
src/svc-main/controllers/HomeController.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Controllers;
|
||||
|
||||
use Exception;
|
||||
use Flight;
|
||||
|
||||
/**
|
||||
* Контроллер домашней страницы (списка плейлистов)
|
||||
*/
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Отображает главную страницу с учётом пагинации списка плейлистов
|
||||
*
|
||||
* @param int $page Текущая страница списка
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function index(int $page = 1): void
|
||||
{
|
||||
$redis = Flight::get('redis');
|
||||
|
||||
// если пришёл любой get-параметр, то считаем его как id плейлиста и перебрасываем на страницу о нём
|
||||
if (Flight::request()->query->count() > 0) {
|
||||
$id = Flight::request()->query->keys()[0];
|
||||
Flight::redirect(base_url($id));
|
||||
die;
|
||||
}
|
||||
|
||||
// иначе формируем и сортируем список при необходимости, рисуем страницу
|
||||
$perPage = 20;
|
||||
$playlists = $this->ini->playlists(false);
|
||||
$count = count($playlists);
|
||||
$pageCount = ceil($count / $perPage);
|
||||
$offset = max(0, ($page - 1) * $perPage);
|
||||
$list = array_slice($playlists, $offset, $perPage, true);
|
||||
|
||||
view('list', [
|
||||
'updated_at' => $this->ini->updatedAt(),
|
||||
'count' => $count,
|
||||
'pages' => [
|
||||
'count' => $pageCount,
|
||||
'current' => $page,
|
||||
],
|
||||
'playlists' => $list,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Отображает страницу FAQ
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function faq(): void
|
||||
{
|
||||
view('faq');
|
||||
}
|
||||
}
|
||||
89
src/svc-main/controllers/PlaylistController.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Controllers;
|
||||
|
||||
use Core\ChannelLogo;
|
||||
use Exception;
|
||||
use Exceptions\PlaylistNotFoundException;
|
||||
use Flight;
|
||||
|
||||
/**
|
||||
* Контроллер методов получения описания плейлистов
|
||||
*/
|
||||
class PlaylistController extends Controller
|
||||
{
|
||||
/**
|
||||
* Отправляет запрос с клиента по прямой ссылке плейлиста
|
||||
*
|
||||
* @param string $id ID плейлиста
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function download(string $id): void
|
||||
{
|
||||
try {
|
||||
$playlist = $this->ini->getPlaylist($id);
|
||||
Flight::redirect($playlist->pls);
|
||||
} catch (PlaylistNotFoundException) {
|
||||
$this->notFound($id);
|
||||
}
|
||||
die;
|
||||
}
|
||||
|
||||
/**
|
||||
* Отображает страницу описания плейлиста
|
||||
*
|
||||
* @param string $id ID плейлиста
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function details(string $id): void
|
||||
{
|
||||
$result = $this->getPlaylistResponse($id);
|
||||
view('details', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает JSON с описанием плейлиста
|
||||
*
|
||||
* @param string $id ID плейлиста
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function json(string $id): void
|
||||
{
|
||||
$result = $this->getPlaylistResponse($id, true);
|
||||
Flight::json($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает логотип канала, кэшируя при необходимости
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function logo(): void
|
||||
{
|
||||
$input = Flight::request()->query['url'] ?? null;
|
||||
|
||||
$logo = new ChannelLogo($input);
|
||||
if (!$logo->readFile()) {
|
||||
$logo->fetch();
|
||||
}
|
||||
|
||||
if ($logo->size() === 0) {
|
||||
$logo->setDefault();
|
||||
}
|
||||
|
||||
$logo->store();
|
||||
$body = $logo->raw();
|
||||
$size = $logo->size();
|
||||
$mime = $logo->mimeType();
|
||||
|
||||
Flight::response()
|
||||
->write($body)
|
||||
->header('Content-Type', $mime)
|
||||
->header('Content-Length', (string)$size);
|
||||
}
|
||||
}
|
||||
91
src/svc-main/core/Bootstrapper.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Core;
|
||||
|
||||
use Flight;
|
||||
use Twig\Environment;
|
||||
use Twig\Extension\DebugExtension;
|
||||
use Twig\Loader\FilesystemLoader;
|
||||
|
||||
/**
|
||||
* Сборщик приложения
|
||||
*/
|
||||
final class Bootstrapper
|
||||
{
|
||||
/**
|
||||
* Загружает конфигурацию приложения в контейнер
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function bootSettings(): void
|
||||
{
|
||||
$config = require_once root_path('config.php');
|
||||
foreach ($config as $key => $value) {
|
||||
Flight::set($key, $value);
|
||||
}
|
||||
Flight::set('config', $config);
|
||||
}
|
||||
|
||||
public static function bootCore(): void
|
||||
{
|
||||
$loader = new IniFile();
|
||||
$loader->load();
|
||||
|
||||
Flight::set('ini', $loader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает шаблонизатор и его расширения
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function bootTwig(): void
|
||||
{
|
||||
$twigCfg = [
|
||||
'cache' => config('twig.cache'),
|
||||
'debug' => config('twig.debug'),
|
||||
];
|
||||
|
||||
$closure = static function ($twig) {
|
||||
/** @var Environment $twig */
|
||||
Flight::set('twig', $twig);
|
||||
$twig->addExtension(new TwigFunctions());
|
||||
$twig->addExtension(new DebugExtension());
|
||||
};
|
||||
|
||||
$loader = new FilesystemLoader(config('flight.views.path'));
|
||||
Flight::register('view', Environment::class, [$loader, $twigCfg], $closure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Загружает маршруты
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function bootRoutes(): void
|
||||
{
|
||||
$routes = require_once root_path('routes.php');
|
||||
foreach ($routes as $route => $handler) {
|
||||
Flight::route($route, $handler);
|
||||
}
|
||||
}
|
||||
|
||||
public static function bootRedis(): void
|
||||
{
|
||||
$options = [
|
||||
'host' => config('redis.host'),
|
||||
'port' => config('redis.port'),
|
||||
// 'username' => config('redis.user'),
|
||||
// 'pass' => config('redis.password'),
|
||||
'connectTimeout' => 1,
|
||||
];
|
||||
|
||||
$redis = new \Redis($options);
|
||||
$redis->select((int)config('redis.database'));
|
||||
$redis->setOption(\Redis::OPT_SERIALIZER, \Redis::SERIALIZER_JSON);
|
||||
|
||||
Flight::set('redis', $redis);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Core;
|
||||
namespace Core;
|
||||
|
||||
class ChannelLogo implements \Stringable
|
||||
{
|
||||
@@ -41,7 +41,7 @@ class ChannelLogo implements \Stringable
|
||||
*/
|
||||
public function __construct(string $url)
|
||||
{
|
||||
$url = empty($url) ? base_url('public/no-tvg-logo.png') : $this->prepareUrl($url);
|
||||
$url = $this->prepareUrl($url);
|
||||
if (is_string($url)) {
|
||||
$this->url = $url;
|
||||
$this->hash = md5($url);
|
||||
@@ -57,15 +57,17 @@ class ChannelLogo implements \Stringable
|
||||
*/
|
||||
protected function prepareUrl(string $url): false|string
|
||||
{
|
||||
$parts = parse_url(trim($url));
|
||||
if (!is_array($parts) || count($parts) < 2) {
|
||||
$url = filter_var(trim($url), FILTER_VALIDATE_URL);
|
||||
if ($url === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = $parts['scheme'] . '://' . $parts['host'];
|
||||
$result .= (empty($parts['port']) ? '' : ':' . $parts['port']);
|
||||
$parts = parse_url($url);
|
||||
if (!is_array($parts)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $result . $parts['path'];
|
||||
return $parts['scheme'] . '://' . $parts['host'] . $parts['path'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,7 +122,7 @@ class ChannelLogo implements \Stringable
|
||||
public function setDefault(): bool
|
||||
{
|
||||
$this->path = root_path('public/no-tvg-logo.png');
|
||||
return $this->readFile();
|
||||
return$this->readFile();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Core;
|
||||
namespace Core;
|
||||
|
||||
use App\Errors\PlaylistNotFoundException;
|
||||
use Exception;
|
||||
use Exceptions\PlaylistNotFoundException;
|
||||
|
||||
/**
|
||||
* Класс для работы с ini-файлом плейлистов
|
||||
@@ -15,7 +15,7 @@ class IniFile
|
||||
/**
|
||||
* @var array Считанное из файла содержимое ini-файла
|
||||
*/
|
||||
protected array $ini;
|
||||
protected array $rawIni;
|
||||
|
||||
/**
|
||||
* @var Playlist[] Коллекция подгруженных плейлистов
|
||||
@@ -40,30 +40,13 @@ class IniFile
|
||||
*/
|
||||
public function load(): void
|
||||
{
|
||||
$ini = redis()->hGetAll('_playlists_');
|
||||
if (empty($ini)) {
|
||||
$filepath = config_path('playlists.ini');
|
||||
$ini = parse_ini_file($filepath, true);
|
||||
$this->updated_at = date('d.m.Y h:i', filemtime($filepath));
|
||||
$order = array_keys($ini);
|
||||
}
|
||||
$filepath = root_path('playlists.ini');
|
||||
$this->updated_at = date('d.m.Y h:i', filemtime($filepath));
|
||||
|
||||
$order ??= redis()->get('_order_');
|
||||
$this->ini ??= $ini;
|
||||
$this->updated_at ??= redis()->get('_updated_at_');
|
||||
$transaction = redis()->multi();
|
||||
foreach ($order as $id) {
|
||||
$data = $this->ini[$id];
|
||||
$this->playlists[(string)$id] = $pls = $this->makePlaylist($id, $data);
|
||||
$transaction->hSet('_playlists_', $id, $pls);
|
||||
$this->rawIni = parse_ini_file($filepath, true);
|
||||
foreach ($this->rawIni as $id => $data) {
|
||||
$this->playlists[(string)$id] = $this->makePlaylist($id, $data);
|
||||
}
|
||||
|
||||
$expireAfter = config('redis.ttl_days');
|
||||
$transaction
|
||||
->expire('_playlists_', $expireAfter)
|
||||
->set('_order_', $order, ['EX' => $expireAfter])
|
||||
->set('_updated_at_', $this->updated_at, ['EX' => $expireAfter])
|
||||
->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,9 +57,11 @@ class IniFile
|
||||
*/
|
||||
public function playlists(bool $all = true): array
|
||||
{
|
||||
return $all
|
||||
? $this->playlists
|
||||
: array_filter($this->playlists, static fn ($playlist) => is_null($playlist->redirectId));
|
||||
if ($all) {
|
||||
return $this->playlists;
|
||||
}
|
||||
|
||||
return array_filter($this->playlists, static fn ($playlist) => is_null($playlist->redirectId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,7 +111,7 @@ class IniFile
|
||||
$id = (string)$id;
|
||||
if (isset($params['redirect'])) {
|
||||
$this->redirections[$id] = $redirectId = (string)$params['redirect'];
|
||||
$params = $this->ini[$redirectId];
|
||||
$params = $this->rawIni[$redirectId];
|
||||
return $this->makePlaylist($id, $params, $redirectId);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Core;
|
||||
namespace Core;
|
||||
|
||||
use CurlHandle;
|
||||
use Exception;
|
||||
use Random\RandomException;
|
||||
|
||||
@@ -87,19 +86,17 @@ class Playlist
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function fetchContent(): void
|
||||
public function download(): void
|
||||
{
|
||||
$cached = redis()->get($this->id);
|
||||
if (is_array($cached)) {
|
||||
$this->downloadStatus['httpCode'] = $cached['httpCode'];
|
||||
$this->downloadStatus['errCode'] = $cached['errCode'];
|
||||
$this->downloadStatus['errText'] = $cached['errText'];
|
||||
$this->downloadStatus['possibleStatus'] = $cached['possibleStatus'];
|
||||
$this->rawContent = $cached['content'];
|
||||
return;
|
||||
}
|
||||
$curl = curl_init();
|
||||
curl_setopt_array($curl, [
|
||||
CURLOPT_URL => $this->pls,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_HEADER => false,
|
||||
CURLOPT_FAILONERROR => true,
|
||||
]);
|
||||
|
||||
$curl = $this->makeCurl();
|
||||
$content = curl_exec($curl);
|
||||
$this->rawContent = $content === false ? null : $content;
|
||||
$this->downloadStatus['httpCode'] = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
|
||||
@@ -107,16 +104,6 @@ class Playlist
|
||||
$this->downloadStatus['errText'] = curl_error($curl);
|
||||
$this->downloadStatus['possibleStatus'] = $this->guessStatus($this->downloadStatus['errCode']);
|
||||
curl_close($curl);
|
||||
|
||||
if ($cached === false) {
|
||||
redis()->set($this->id, [
|
||||
'httpCode' => $this->downloadStatus['httpCode'],
|
||||
'errCode' => $this->downloadStatus['errCode'],
|
||||
'errText' => $this->downloadStatus['errText'],
|
||||
'possibleStatus' => $this->downloadStatus['possibleStatus'],
|
||||
'content' => $this->rawContent,
|
||||
], ['EX' => config('redis.ttl_days')]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -251,53 +238,6 @@ class Playlist
|
||||
return $this->parsedContent = $result;
|
||||
}
|
||||
|
||||
public function check(): bool
|
||||
{
|
||||
$curl = $this->makeCurl([
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_NOBODY => true,
|
||||
CURLOPT_HEADER => true,
|
||||
CURLOPT_CUSTOMREQUEST => 'HEAD',
|
||||
]);
|
||||
|
||||
$content = curl_exec($curl);
|
||||
$this->rawContent = $content === false ? null : $content;
|
||||
$this->downloadStatus['httpCode'] = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
|
||||
$this->downloadStatus['errCode'] = curl_errno($curl);
|
||||
$this->downloadStatus['errText'] = curl_error($curl);
|
||||
$this->downloadStatus['possibleStatus'] = $this->guessStatus($this->downloadStatus['errCode']);
|
||||
curl_close($curl);
|
||||
|
||||
return $this->downloadStatus['httpCode'] < 400;
|
||||
}
|
||||
|
||||
protected function makeCurl(array $customOptions = []): CurlHandle
|
||||
{
|
||||
$options = [
|
||||
CURLOPT_URL => $this->pls,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_HEADER => false,
|
||||
CURLOPT_FAILONERROR => true,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 5,
|
||||
CURLOPT_USERAGENT => config('app.user_agent'),
|
||||
];
|
||||
|
||||
$curl = curl_init();
|
||||
|
||||
foreach ($options as $option => $value) {
|
||||
curl_setopt($curl, $option, $value);
|
||||
}
|
||||
|
||||
// array_merge($options, $customOptions) loses keys
|
||||
foreach ($customOptions as $option => $value) {
|
||||
curl_setopt($curl, $option, $value);
|
||||
}
|
||||
|
||||
return $curl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Парсит атрибуты строки и возвращает ассоциативный массив
|
||||
*
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Core;
|
||||
namespace Core;
|
||||
|
||||
use Twig\Extension\AbstractExtension;
|
||||
use Twig\TwigFunction;
|
||||
|
||||
class TwigExtention extends AbstractExtension
|
||||
class TwigFunctions extends AbstractExtension
|
||||
{
|
||||
public function getFunctions(): array
|
||||
{
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Errors;
|
||||
namespace Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Core\Core;
|
||||
use App\Core\IniFile;
|
||||
use Slim\App;
|
||||
use flight\Engine;
|
||||
use flight\net\Response;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
/**
|
||||
* Returns path to root application directory
|
||||
@@ -17,17 +17,6 @@ function root_path(string $path = ''): string
|
||||
return rtrim(sprintf('%s/%s', dirname($_SERVER['DOCUMENT_ROOT']), $path), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return path to application configuration directory
|
||||
*
|
||||
* @param string $path
|
||||
* @return string
|
||||
*/
|
||||
function config_path(string $path = ''): string
|
||||
{
|
||||
return root_path("config/$path");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns path to app cache
|
||||
*
|
||||
@@ -58,7 +47,7 @@ function views_path(string $path = ''): string
|
||||
*/
|
||||
function base_url(string $route = ''): string
|
||||
{
|
||||
return rtrim(sprintf('%s/%s', env('APP_URL'), $route), '/');
|
||||
return rtrim(sprintf('%s/%s', config('flight.base_url'), $route), '/');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +59,7 @@ function base_url(string $route = ''): string
|
||||
*/
|
||||
function env(string $key, mixed $default = null): mixed
|
||||
{
|
||||
return $_ENV[$key] ?? $_SERVER[$key] ?? $default;
|
||||
return $_ENV[$key] ?? $default;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,23 +78,23 @@ function view(mixed $template, array $data = []): void
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns core object
|
||||
* Returns response object
|
||||
*
|
||||
* @return Core
|
||||
* @return Response
|
||||
*/
|
||||
function core(): Core
|
||||
function response(): Response
|
||||
{
|
||||
return Core::get();
|
||||
return Flight::response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns app object
|
||||
*
|
||||
* @return App
|
||||
* @return Engine
|
||||
*/
|
||||
function app(): App
|
||||
function app(): Engine
|
||||
{
|
||||
return Core::get()->app();
|
||||
return Flight::app();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,25 +124,5 @@ function bool(mixed $value): bool
|
||||
*/
|
||||
function config(string $key, mixed $default = null): mixed
|
||||
{
|
||||
return Core::get()->config($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Redis instance
|
||||
*
|
||||
* @return Redis
|
||||
*/
|
||||
function redis(): Redis
|
||||
{
|
||||
return Core::get()->redis();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ini-file instance
|
||||
*
|
||||
* @return IniFile
|
||||
*/
|
||||
function ini(): IniFile
|
||||
{
|
||||
return Core::get()->ini();
|
||||
return Flight::get('config')[$key] ?? $default;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
21
src/svc-main/public/index.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Core\Bootstrapper;
|
||||
use Symfony\Component\Dotenv\Dotenv;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Bootstrap all classes, settings, etc.
|
||||
|--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
require '../vendor/autoload.php';
|
||||
(new Dotenv())->loadEnv(root_path() . '/.env');
|
||||
Bootstrapper::bootSettings();
|
||||
Bootstrapper::bootTwig();
|
||||
Bootstrapper::bootCore();
|
||||
Bootstrapper::bootRoutes();
|
||||
Bootstrapper::bootRedis();
|
||||
Flight::start();
|
||||
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
17
src/svc-main/routes.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Controllers\HomeController;
|
||||
use Controllers\PlaylistController;
|
||||
|
||||
return [
|
||||
'GET /' => [HomeController::class, 'index'],
|
||||
'GET /page/@page:[0-9]+' => [HomeController::class, 'index'],
|
||||
'GET /faq' => [HomeController::class, 'faq'],
|
||||
'GET /logo' => [PlaylistController::class, 'logo'],
|
||||
'GET /@id:[a-zA-Z0-9_-]+' => [PlaylistController::class, 'download'],
|
||||
'GET /?[a-zA-Z0-9_-]+' => [PlaylistController::class, 'download'],
|
||||
'GET /@id:[a-zA-Z0-9_-]+/details' => [PlaylistController::class, 'details'],
|
||||
'GET /@id:[a-zA-Z0-9_-]+/json' => [PlaylistController::class, 'json'],
|
||||
];
|
||||
120
src/svc-main/views/list.twig
Normal file
@@ -0,0 +1,120 @@
|
||||
{% extends "template.twig" %}
|
||||
|
||||
{% block header %}
|
||||
<p class="text-muted small">
|
||||
Обновлено: {{ updated_at }} МСК<br/>
|
||||
Плейлистов в списке: <strong>{{ count }}</strong>
|
||||
</p>
|
||||
<hr/>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-responsive table-dark table-hover small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Информация о плейлисте</th>
|
||||
<th>Каналов</th>
|
||||
<th class="d-none d-sm-table-cell">Ссылка для ТВ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for id, playlist in playlists %}
|
||||
<tr class="pls" data-playlist-id="{{ id }}">
|
||||
<td class="text-center font-monospace id">{{ id }}</td>
|
||||
<td class="info">
|
||||
<span class="badge small bg-secondary text-dark status">loading</span>
|
||||
<strong>{{ playlist.name }}</strong>
|
||||
<div class="small mt-2">
|
||||
{% if playlist.desc|length > 0 %}
|
||||
<p class="my-1 d-none d-lg-block">{{ playlist.desc }}</p>
|
||||
{% endif %}
|
||||
<a href="{{ base_url(id ~ '/details') }}" class="text-light">Подробнее...</a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center count">
|
||||
<div class="spinner-border text-success" role="status">
|
||||
<span class="visually-hidden">загрузка...</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="col-3 d-none d-sm-table-cell">
|
||||
<span onclick="prompt('Скопируй адрес плейлиста', '{{ playlist.url }}')"
|
||||
title="Нажми на ссылку, чтобы скопировать её в буфер обмена"
|
||||
class="font-monospace cursor-pointer">
|
||||
{{ playlist.url }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if pages.count > 0 %}
|
||||
<div aria-label="pages">
|
||||
<ul class="pagination justify-content-center">
|
||||
{% for page in range(1, pages.count) %}
|
||||
{% if page == pages.current %}
|
||||
<li class="page-item active" aria-current="page">
|
||||
<span class="page-link">{{ page }}</span>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item">
|
||||
<a class="page-link bg-dark border-secondary text-light" href="{{ base_url('page/' ~ page) }}">{{ page }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
<script>
|
||||
document.querySelectorAll('tr.pls').forEach((tr) => {
|
||||
const id = tr.attributes['data-playlist-id'].value
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.responseType = 'json'
|
||||
xhr.timeout = 60000 // ms = 1 min
|
||||
let el_status = tr.querySelector('span.status')
|
||||
let el_count = tr.querySelector('td.count')
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
el_status.classList.remove('bg-secondary')
|
||||
el_status.innerText = xhr.response?.status.possibleStatus ?? 'error'
|
||||
el_count.innerText = xhr.response?.content.channelCount ?? 0
|
||||
switch (el_status.innerText) {
|
||||
case 'online':
|
||||
el_status.classList.add('bg-success')
|
||||
break
|
||||
case 'timeout':
|
||||
el_status.classList.add('bg-warning')
|
||||
break
|
||||
default:
|
||||
el_status.classList.add('bg-danger')
|
||||
break
|
||||
}
|
||||
if (xhr.response?.error) {
|
||||
el_status.title = '[' + xhr.response.error.code + '] ' + xhr.response.error.message
|
||||
}
|
||||
}
|
||||
}
|
||||
xhr.onerror = () => {
|
||||
el_status.classList.add('bg-danger')
|
||||
el_status.innerText = 'error'
|
||||
el_count.innerText = 0
|
||||
}
|
||||
xhr.onabort = () => {
|
||||
el_status.classList.add('bg-secondary')
|
||||
el_count.innerText = 0
|
||||
}
|
||||
xhr.ontimeout = () => {
|
||||
el_status.classList.add('bg-secondary')
|
||||
el_status.innerText = 'timeout'
|
||||
el_count.innerText = 0
|
||||
}
|
||||
xhr.open('GET', '/' + id + '/json')
|
||||
xhr.send()
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -16,7 +16,6 @@
|
||||
<meta name="msapplication-TileColor" content="#00aba9">
|
||||
<meta name="msapplication-TileImage" content="{{ base_url('/favicon/mstile-144x144.png') }}">
|
||||
<meta name="theme-color" content="#212529">
|
||||
<style>.boosty{vertical-align:baseline;float:left;display:inline;width:20px}</style>
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body class="bg-dark text-light">
|
||||
@@ -50,12 +49,6 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://t.me/iptv_aggregator">Telegram</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://boosty.to/anthonyaxenov">
|
||||
<img class="boosty" src="{{ base_url('boosty.svg') }}" alt="Boosty">
|
||||
Boosty
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -74,6 +67,11 @@
|
||||
href="https://git.axenov.dev/anthony/iptv">Gitea</a> | <a
|
||||
href="https://axenov.dev">axenov.dev</a> | <a
|
||||
href="https://t.me/iptv_aggregator">Telegram</a><br>
|
||||
<span class="small text-muted">
|
||||
commit <a class="text-muted" target="_blank"
|
||||
href="https://github.com/anthonyaxenov/iptv/commit/{{ commit() }}"
|
||||
>{{ commit()[:8] }}</a>
|
||||
</span>
|
||||
</footer>
|
||||
</div>
|
||||
{% include("custom.twig") ignore missing %}
|
||||
@@ -1,66 +0,0 @@
|
||||
{% extends "template.twig" %}
|
||||
|
||||
{% block header %}
|
||||
<p class="text-muted small">
|
||||
Обновлено: {{ updated_at }} МСК<br/>
|
||||
Плейлистов в списке: <strong>{{ count }}</strong>
|
||||
</p>
|
||||
<hr/>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-responsive table-dark table-hover small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">ID</th>
|
||||
<th>Информация о плейлисте</th>
|
||||
<th class="d-none d-sm-table-cell">Ссылка для ТВ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for id, playlist in playlists %}
|
||||
<tr class="pls" data-playlist-id="{{ id }}">
|
||||
<td class="text-center font-monospace id">{{ id }}</td>
|
||||
<td class="info">
|
||||
<a href="{{ base_url(id ~ '/details') }}" class="text-light fw-bold text-decoration-none">{{ playlist.name }}</a>
|
||||
<div class="small mt-2">
|
||||
{% if playlist.desc|length > 0 %}
|
||||
<p class="my-1 d-none d-lg-block">{{ playlist.desc }}</p>
|
||||
{% endif %}
|
||||
<a href="{{ base_url(id ~ '/details') }}" class="text-light">Подробнее...</a>
|
||||
</div>
|
||||
</td>
|
||||
<td class="col-3 d-none d-sm-table-cell">
|
||||
<span onclick="prompt('Скопируй адрес плейлиста', '{{ playlist.url }}')"
|
||||
title="Нажми на ссылку, чтобы скопировать её в буфер обмена"
|
||||
class="font-monospace cursor-pointer">
|
||||
{{ playlist.url }}
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% if pageCount > 0 %}
|
||||
<div aria-label="pages">
|
||||
<ul class="pagination justify-content-center">
|
||||
{% for page in range(1, pageCount) %}
|
||||
{% if page == pageCurrent %}
|
||||
<li class="page-item active" aria-current="page">
|
||||
<span class="page-link">{{ page }}</span>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="page-item">
|
||||
<a class="page-link bg-dark border-secondary text-light" href="{{ base_url('page/' ~ page) }}">{{ page }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer %}
|
||||
{% endblock %}
|
||||