整理torrent-TV播放列表(Super Wash)

UPD 内容的主要来源Torrent-TV服务已经死亡,因此该文章没有实际意义。

非法Torrent-TV服务(超级清洗)中的流绝大多数是来自运营商的原始流,或者来自卫星的未经夹持的流。 这些主要是隔行视频流。 洪流电视提供了最高的质量,但稳定性较低。 今天有一些频道,明天没有。 今天,某些频道运作良好,明天则不好。 此服务不适合连续无故障使用-他们为此付费 没有付款,便收到了。 但是,当您需要观看高质量的节目时(如果该频道在此刻稳定运行),这很棒。 另一个问题是形成方便的个人播放列表。 这将在注释中讨论。



基本的torrent-TV播放列表(Super Wash)包含1200多个频道。 各种地区,不同国家,标清和高清的副本,不同的垃圾渠等。200-300个频道属于俄罗斯观众。 但是,并不是每个人都对采用的渠道分组感到满意。 看来您可以从Torrent TV中获取播放列表,并根据完美主义者的灵魂进行安排。 问题在于,与频道的AceStream链接会定期更改,并且准备好的播放列表将变得无用。 即 您需要以一种方便的形式自动生成新的最新播放列表。 那就是我们要做的。

您将需要:

  • 具有设置观看Torrent电视(“超级清洗”)并了解其内容的经验。
  • 具有Entware支持的路由器(如有必要,还可以使用一些技能轻松调整包装盒上有关OpenWrt或Entware的说明)。

该说明未解决问题:

  • 选择和配置IPTV管理器。
  • 整体上用于观看Torrent电视的系统设置。
  • 特定Android机顶盒的功能,适用于一般隔行视频,尤其是Torrent TV。

我们将在路由器上使用该程序,当该链接请求时,该程序将下载当前的Torrent-TV播放列表,并从中形成一个新的播放列表并提供以下内容:

  • 您自己的频道列表基于准备好的收藏频道列表。
  • 如果高清频道匹配,您可以自动排除它们。
  • 根据您的需求对组及其名称进行排序。
  • 根据需要显示频道名称。
  • 按HD / SD(主要)和名称对组中的频道进行排序。
  • 内置到EPG来源的链接。
  • 徽标的来源(以及徽标本身)以及所选渠道的EPG兼容性。

调整后一切将如何工作?


在IPTV管理器中,添加指向播放列表http://192.168.0.1:81/playlist.cgi的链接(将192.168.0.1替换为路由器的内部地址)。 做完了



操作原理非常简单。 路由器上的playlist.cgi脚本启动ttv.py程序,该程序基于当前的洪流电视播放列表(在访问时加载)和给定的收藏频道列表,生成一个新的播放列表,然后将其分发。

在路由器上安装必要的软件


通过SSH连接到路由器。 在Windows上,您可以使用PuTTY客户端连接连接。

安装必要的软件:

opkg update opkg install wget ca-certificates mc python3 lighttpd-mod-cgi 

wget是用于下载文件的程序。 仅在初始设置时才需要。

ca-certificates -wget的证书。

mc-午夜指挥官文件管理器。 仅由于方便的mcedit编辑器,才需要它。 如果您习惯于使用其他文本编辑器,则无法安装mc。

python3是Python解释器。

lighttpd-mod-cgi -lighttpd Web服务器。

下载主要文件


 mkdir -p /opt/etc/ttv wget --no-check-certificate -O /opt/etc/ttv/ttv.py https://raw.githubusercontent.com/Kyrie1965/ttv/master/ttv.py wget --no-check-certificate -O /opt/share/www/playlist.cgi https://raw.githubusercontent.com/Kyrie1965/ttv/master/playlist.cgi chmod +x /opt/share/www/playlist.cgi 

稍后我将介绍他们的约会,但是现在我只显示其中的内容。 不要发现Python代码有问题,直到这一刻我还没有用Python编写任何东西。

内容/opt/etc/ttv/ttv.py
 PLAYLIST_LOAD_URL = "http://91.92.66.82/trash/ttv-list/as.all.tag.player.m3u" TEMPLATE_SAVE_PATH = "/opt/etc/ttv/template.txt" FAVORITES_LOAD_PATH = "/opt/etc/ttv/favorites.txt" PLAYLIST_SAVE_PATH = "/opt/etc/ttv/playlist.m3u" LOGOS_URL = "" #LOGOS_URL = "https://raw.githubusercontent.com/Kyrie1965/ttv/master/logos/{}" #LOGOS_URL = "{}" STREAM_URL = "http://127.0.0.1:6878/ace/getstream?id={}&.mp4" #STREAM_URL = "acestream://{}" EPG_LINKS = "https://teleguide.info/download/new3/xmltv.xml.gz" #EPG_LINKS = "https://teleguide.info/download/new3/xmltv.xml.gz,http://programtv.ru/xmltv.xml.gz,http://api.torrent-tv.ru/ttv.xmltv.xml.gz" import re import urllib.request import os from operator import itemgetter as i from functools import cmp_to_key from urllib.parse import urlencode import gzip def cmp(a, b): return (a > b) - (a < b) def multikeysort(items, columns): comparers = [ ((i(col[1:].strip()), -1) if col.startswith('-') else (i(col.strip()), 1)) for col in columns ] def comparer(left, right): comparer_iter = ( cmp(fn(left), fn(right)) * mult for fn, mult in comparers ) return next((result for result in comparer_iter if result), 0) return sorted(items, key=cmp_to_key(comparer)) def loadChannels(content): lines = content.splitlines() returnChannels = {} pattern = re.compile("group-title=\"(.*?)\"") pattern2 = re.compile("tvg-logo=\"(.*?)\"") channelName = "" channelGroup = "" channelLogoLink = "" channelStreamID = "" waitURI = False for line in lines: if line.startswith("acestream"): if waitURI: channelStreamID = line[12:] HD = False if ("HD" in channelName) or ("UHD" in channelName) or ("4K" in channelName): HD = True tmpDict = {"name": channelName, "group": channelGroup, "stream": channelStreamID, "hd": HD, "logolink": channelLogoLink} returnChannels[channelName.upper()] = tmpDict waitURI = False elif line.startswith("#EXTINF"): index = line.rfind("\",") if (index == -1): continue channelName = line[index+2:] match = pattern.search(line) if match: channelGroup = match.group(1) else: channelGroup = "" match = pattern2.search(line) if match: channelLogoLink = match.group(1) else: channelLogoLink = "" waitURI = True return returnChannels def saveTemplate(content, channels, path): lines = content.splitlines() pattern = re.compile("group-title=\"(.*?)\"") waitURI = False channelName = "" channelReplace = "" channelNewName = "" channelEPG = "" channelGroup = "" channelStreamID = "" groupDict = {} currentGroup = 1 template="" for line in lines: if line.startswith("acestream"): if waitURI: channelStreamID = line[12:] template += channelName template += "/" template += channelReplace template += "/" template += channelNewName template += "/" template += channelEPG template += "/" template += channelName + ".png" template += "/" template += channelGroup template += "\n" waitURI = False elif line.startswith("#EXTINF"): x = line.split("\",") if (len(x) != 2): continue channelName = x[1] channelNewName = x[1] channelEPG = x[1] if (channels.get(channelName.upper() + " HD") != None): channelReplace = channelName + " HD" else: channelReplace = "-" match = pattern.search(x[0]) if match: channelGroup = match.group(1) if (groupDict.get(channelGroup)): channelGroup = groupDict.get(channelGroup) else: newGroupName = "{:02d}_{}".format(currentGroup, channelGroup) currentGroup += 1 groupDict[channelGroup] = newGroupName channelGroup = newGroupName else: channelGroup = "00_Unsigned" waitURI = True file = open(path,'w', encoding='utf-8') file.write(template) file.close() return def loadFavorites(content): returnChannels = {} lines = content.splitlines() for line in lines: parts = line.split('/') if len(parts) == 6: tmpDict = {"name": parts[0], "replace": parts[1], "newName": parts[2], "EPG": parts[3], "logo": parts[4], "group": parts[5]} returnChannels[parts[0].upper()] = tmpDict elif len(parts) == 5: #    tmpDict = {"name": parts[0], "replace": parts[1], "newName": parts[2], "EPG": parts[3], "group": parts[4], "logo": parts[0] + ".png"} returnChannels[parts[0].upper()] = tmpDict return returnChannels def savePlaylist(channels, favorites, path): returnChannels = [] currentChannels = set() for key, chDict in favorites.items(): if chDict["replace"] != "-": if favorites.get(chDict["replace"].upper()) != None and channels.get(chDict["replace"].upper()) != None: currentChannels.add(chDict["replace"]) elif channels.get(chDict["name"].upper()) != None: currentChannels.add(chDict["name"]) elif channels.get(chDict["name"].upper()) != None: currentChannels.add(chDict["name"]) for ch in currentChannels: chFromFavorites = favorites.get(ch.upper()) chFromChannels = channels.get(ch.upper()) tmpDict = {"name": chFromFavorites.get("newName"), "oldName": chFromFavorites.get("name"), "EPG": chFromFavorites.get("EPG"), "group": chFromFavorites.get("group"), "logof": chFromFavorites.get("logo"), "logoc": chFromChannels.get("logolink"), "stream": chFromChannels.get("stream"), "hd": chFromChannels.get("hd")} returnChannels.append(tmpDict) result = multikeysort(returnChannels, ['group', '-hd', 'name']) template="" template += "#EXTM3U url-tvg=" template += "\"" template += EPG_LINKS template += "\"" template += "\n" for n in result: group = n.get("group") if group.find("_", 2, 3) != -1: group = group[3:] if len(LOGOS_URL) > 0: template += "#EXTINF:-1 tvg-name=\"{}\" tvg-logo=\"{}\" group-title=\"{}\",{}".format(n.get("EPG"), LOGOS_URL.format(urllib.parse.quote(n.get("logof"))), group, n.get("name")) else: template += "#EXTINF:-1 tvg-name=\"{}\" tvg-logo=\"{}\" group-title=\"{}\",{}".format(n.get("EPG"), n.get("logoc"), group, n.get("name")) template += "\n" template += STREAM_URL.format(n.get("stream")) template += "\n" file = open(path,'w', encoding='utf-8') file.write(template) file.close() return result #response = urllib.request.urlopen(PLAYLIST_LOAD_URL) #content = response.read().decode("utf-8") #channels = loadChannels(content) content = "" request = urllib.request.Request(PLAYLIST_LOAD_URL) request.add_header('Accept-encoding', 'gzip') response = urllib.request.urlopen(request) if response.info().get('Content-Encoding') == 'gzip': gzipFile = gzip.GzipFile(fileobj=response) content = gzipFile.read().decode("utf-8") else: content = response.read().decode("utf-8") channels = loadChannels(content) if channels == None or (len(channels.keys()) == 0): exit() saveTemplate(content, channels, TEMPLATE_SAVE_PATH) exists = os.path.isfile(FAVORITES_LOAD_PATH) if exists: file = open(FAVORITES_LOAD_PATH,'r', encoding='utf-8') content = file.read() favorites = loadFavorites(content) savePlaylist(channels, favorites, PLAYLIST_SAVE_PATH) 


内容/opt/share/www/playlist.cgi
 #!/bin/sh PATH=/opt/sbin:/opt/bin:/opt/usr/sbin:/opt/usr/bin:/usr/sbin:/usr/bin:/sbin:/bin python3 /opt/etc/ttv/ttv.py echo "Content-Type: text/plain; charset=UTF-8" echo "" echo "$(cat /opt/etc/ttv/playlist.m3u)" 


Web服务器配置和启动


打开文件/opt/etc/lighttpd/lighttpd.conf

 mcedit /opt/etc/lighttpd/lighttpd.conf 

要从缓冲区粘贴,请使用Shift +插入,保存-F2,退出-F10。

将行#server.port = 80更改为:

 server.port = 81 

打开文件/opt/etc/lighttpd/conf.d/30-cgi.conf

 mcedit /opt/etc/lighttpd/conf.d/30-cgi.conf 

“ .cgi” =>“ / opt / bin / perl”更改为:

 ".cgi" => "/bin/sh" 

启动Web服务器:

 /opt/etc/init.d/S80lighttpd start 

创建一个收藏频道列表


运行ttv.py程序:

 python3 /opt/etc/ttv/ttv.py 

模板文件template.txt将在/ opt / etc / ttv文件夹中创建。 这是一个简单的文本文件。 这将始终是相关的,即 程序启动时,将被当前数据覆盖。

该文件中的每一行对应一个Torrent-TV频道,其格式为:
CHANNEL_NAME / CHANGE_CHANNEL / YOUR_CHANNEL_NAME /YOUR_CHANNEL_NAME__EPG/ YOUR_LOGO /您的群组

例如:

Amedia Premium / Amedia Premium HD / Amedia Premium / Amedia Premium / Amedia Premium.png / 11_电影
Amedia Premium HD /-/ Amedia Premium HD / Amedia Premium HD / Amedia Premium HD.png / 11_电影

将此文件保存在计算机上以便于编辑(例如,使用WinSCP )。 将其重命名为favorite.txt。

编辑文件,仅保留所需的通道。

CHANNEL_NAME-原始播放列表中的频道名称。

CHANGE_CHANNEL-原始播放列表中要替换的频道的名称。 如果不需要替换,请输入“-”。 默认情况下,如果通道具有HD选项,则会在模板中自动替换替换项。 例如,原始播放列表中有Amedia Premium和Amedia Premium HD。 最终播放列表中将只有Amedia Premium HD。

YOUR_CHANNEL_NAME是IPTV管理器中的显示名称。 它可以是任何内容,并且仅影响IPTV管理器中显示的名称。 例如,原始频道称为“ Paramount Comedy HD(俄罗斯)”,而您将其重命名为“ Paramount Comedy HD”。

YOUR_CHANNEL_B__EPG_NAME-这是完全符合所选EPG来源所必需的。 例如,原始频道称为“ Match TV HD”。 在EPG中,此频道称为“匹配!”。 将此参数更改为“匹配!” 并完全符合您的EPG来源。 因此,对于所有渠道,您都可以使EPG合规性接近100%。

YOUR_LOGO-徽标文件的名称。 默认情况下,ttv.py会从原始播放列表中获取徽标链接,即 您的徽标将被忽略。 要使用它,您需要在ttv.py中更改LOGOS_URL参数(稍后将详细了解)。

YOUR_GROUP-频道组的名称。 您可以在组名之前使用索引(两位数)。 此索引确定最终播放列表中组的顺序(从较小到较大)。 排序后,索引将自动从组名中删除。

这是一个编辑的收藏夹.txt文件的示例
 Amedia Premium/Amedia Premium HD/Amedia Premium/Amedia Premium/Amedia Premium.png/11_   Amedia Premium HD/-/Amedia Premium HD/Amedia Premium HD/Amedia Premium HD.png/11_   / HD///.png/12_  HD/-/ HD/ HD/ HD.png/12_ Viasat History/Viasat History HD/Viasat History/Viasat History/Viasat History.png/01_ Viasat History HD/-/Viasat History HD/Viasat History/Viasat History.png/01_ Discovery Channel/Discovery Channel HD/Discovery Channel/Discovery Channel/Discovery Channel.png/01_ Discovery Channel HD/-/Discovery Channel HD/Discovery Channel HD/Discovery Channel HD.png/01_ Discovery Science/Discovery Science HD/Discovery Science/Discovery Science/Discovery Science.png/01_ Discovery Science HD/-/Discovery Science HD/Discovery Science HD/Discovery Science HD.png/01_ Amedia Hit/Amedia Hit HD/Amedia Hit/Amedia Hit/Amedia Hit.png/11_   Amedia Hit HD/-/Amedia Hit HD/Amedia Hit HD/Amedia Hit HD.png/11_    /  HD/!/!/ .png/03_   HD/-/! HD/!/  HD.png/03_ Eurosport 1/Eurosport 1 HD/Eurosport 1/Eurosport 1/Eurosport 1.png/03_ Eurosport 1 HD/-/Eurosport 1 HD/Eurosport 1 HD/Eurosport 1 HD.png/03_ Paramount Comedy HD ()/-/Paramount Comedy HD/Paramount Comedy HD ()/Paramount Comedy HD ().png/11_   !  1/!  1 HD/!  1/!  1/!  1.png/03_ !  1 HD/-/!  1 HD/!  1 HD/!  1 HD.png/03_  1/ HD/ 1/ 1/ 1.png/13_-  HD/-/ HD/ HD/ HD.png/13_- 


将准备好的favorite.txt文件复制到路由器上的/ opt / etc / ttv文件夹中

一切准备就绪。 您可以从http://192.168.0.1:81/playlist.cgi选取播放列表(将192.168.0.1替换为路由器的内部地址)。 只需在IPTV管理器中指定链接,您将始终拥有当前的播放列表。 脚本playlist.cgi启动ttv.py程序,该程序基于当前的洪流电视播放列表(在调用时加载)和收藏夹.txt,生成一个新的播放列表,然后提供此新的播放列表。

在输出中,如果所有频道都存在于当前播放列表中(否则,缺少的频道将被忽略),您将获得一个简洁的播放列表:

播放清单
#EXTM3U url-tvg="https://teleguide.info/download/new3/xmltv.xml.gz"
#EXTINF:-1 tvg-name="Discovery Channel HD" tvg-logo="http://1ttv.org/uploads/SmWnYlOvkJn8GzttT2UY0vmo8PYfMg.png" group-title="",Discovery Channel HD
http://127.0.0.1:6878/ace/getstream?id=b6e518df35bdffc7ea8fdd05025cec851941a102&.mp4
#EXTINF:-1 tvg-name="Discovery Science HD" tvg-logo="http://1ttv.org/uploads/Yjj1p6idV0HGD56Wz7JX5IeKfD44vz.png" group-title="",Discovery Science HD
http://127.0.0.1:6878/ace/getstream?id=03fb28986da9168dd56ec6891253bcc496c13eb5&.mp4
#EXTINF:-1 tvg-name="Viasat History" tvg-logo="http://1ttv.org/uploads/MWGbB8wJp5Gm4vbPHl0ktohDDjMKdr.png" group-title="",Viasat History
http://127.0.0.1:6878/ace/getstream?id=c6d943e1aac03c179b3af9e99d97ac6779c947c7&.mp4
#EXTINF:-1 tvg-name="Eurosport 1 HD" tvg-logo="http://1ttv.org/uploads/DpFTzUEA3y67Z6ObTPF4xH0XLNRAZm.png" group-title="",Eurosport 1 HD
http://127.0.0.1:6878/ace/getstream?id=70bd87520c622ba7dd6e41aface77d5b2f437f87&.mp4
#EXTINF:-1 tvg-name="!" tvg-logo="http://1ttv.org/uploads/MXyy9Uud7oDuH8JqVisjsD0csgAHnQ.png" group-title="",! HD
http://127.0.0.1:6878/ace/getstream?id=9af7ac309216464e67092deb23d312a20c483674&.mp4
#EXTINF:-1 tvg-name="! 1 HD" tvg-logo="http://1ttv.org/uploads/9PM8M6cN21wQ3M5isVZgjNepzUI4Ry.png" group-title="",! 1 HD
http://127.0.0.1:6878/ace/getstream?id=b8a1e8458419b63ad1c3fa7bd79431d9625c322d&.mp4
#EXTINF:-1 tvg-name="Amedia Hit HD" tvg-logo="http://1ttv.org/uploads/HdnTfcZCgP7Odm1cOKNq9j4yJDRiFP.png" group-title=" ",Amedia Hit HD
http://127.0.0.1:6878/ace/getstream?id=ed6d00e9b6c50c95902b33c841302dd709b214da&.mp4
#EXTINF:-1 tvg-name="Amedia Premium HD" tvg-logo="http://1ttv.org/uploads/ornzQpk6WCW6xk0lyBhlwqH8u2QyU7.png" group-title=" ",Amedia Premium HD
http://127.0.0.1:6878/ace/getstream?id=c38a7580985fa85fa6e0a82c6fd7403e8e5c2b50&.mp4
#EXTINF:-1 tvg-name="Paramount Comedy HD ()" tvg-logo="http://1ttv.org/uploads/VowjbL265DoceAryIEtqNuPv3NDhFK.png" group-title=" ",Paramount Comedy HD
http://127.0.0.1:6878/ace/getstream?id=a9023adab9228b8aa7f1b508b553140b69cecd80&.mp4
#EXTINF:-1 tvg-name=" HD" tvg-logo="http://1ttv.org/uploads/m6ODa3HXr9QNAbSThJNvWeOIEYGp7q.png" group-title="", HD
http://127.0.0.1:6878/ace/getstream?id=4318416741f8d35f2de38e7100b89831e0ef0617&.mp4
#EXTINF:-1 tvg-name=" HD" tvg-logo="http://1ttv.org/uploads/ghvqmVpPWqn9x6POAm9UJBvXFzTrqN.png" group-title="-", HD
http://127.0.0.1:6878/ace/getstream?id=39b9b54a5031846e4936735ec62d157d5eca56e0&.mp4


 : Discovery Channel HD Discovery Science HD Viasat History : Eurosport 1 HD ! HD !  1 HD   : Amedia Hit HD Amedia Premium HD Paramount Comedy HD :  HD -:  HD 

如有必要,可以在ttv.py程序中更改一些参数:

 mcedit /opt/etc/ttv/ttv.py 

可供更改的选项
PLAYLIST_LOAD_URL = "http://91.92.66.82/trash/ttv-list/as.all.tag.player.m3u"
TEMPLATE_SAVE_PATH = "/opt/etc/ttv/template.txt"
FAVORITES_LOAD_PATH = "/opt/etc/ttv/favorites.txt"
PLAYLIST_SAVE_PATH = "/opt/etc/ttv/playlist.m3u"
LOGOS_URL = ""
#LOGOS_URL = "https://raw.githubusercontent.com/Kyrie1965/ttv/master/logos/{}"
#LOGOS_URL = "{}"
STREAM_URL = "http://127.0.0.1:6878/ace/getstream?id={}&.mp4"
#STREAM_URL = "acestream://{}"
EPG_LINKS = "https://teleguide.info/download/new3/xmltv.xml.gz"
#EPG_LINKS = "https://teleguide.info/download/new3/xmltv.xml.gz,http://programtv.ru/xmltv.xml.gz,http://api.torrent-tv.ru/ttv.xmltv.xml.gz"


PLAYLIST_LOAD_URL-链接,用于下载当前的Torrent-TV播放列表。
TEMPLATE_SAVE_PATH-保存模板的路径。
FAVORITES_LOAD_PATH-加载收藏频道列表的路径。
PLAYLIST_SAVE_PATH-保存新播放列表的路径。
LOGOS_URL-链接通道的徽标。 您可以使用空字符串(“”)来获取原始播放列表中的链接,而favourites.txt中的徽标将被忽略。
STREAM_URL-最终播放列表中流链接的视图。 这可以是指向Ace Stream的直接链接,也可以是指向Ace Stream代理的链接。 取决于您使用的IPTV管理员。
EPG_LINKS -EPG链接列表。 所有IPTV管理员都是不同的。 有些人不知道如何从播放列表中链接到EPG。 有些播放器仅支持播放列表中的一个EPG来源。 有些人不知道如何合并来自不同来源的EPG。

您只会对STREAM_URL,LOGOS_URL,EPG_LINKS感兴趣,因为 最终播放列表的外观取决于它们。 对于他们,文件中提供了替代示例。

结论


结果,您将获得带有您自己的频道列表,您自己的频道名称,您自己的组及其任意排序,您自己的徽标,您自己的EPG映射,能够排除重复的HD / SD,具有排序功能的实际Torrent电视播放列表(Super Wash)按HD / SD和名称分组的频道。 您只需一次配置所有内容,即可创建自己喜欢的频道的文件。 然后,您的家庭网络上的所有设备都将通过该链接接收所需的播放列表,无需任何其他设置即可立即执行“一切都很好”。



UPD 2019/02/19:

  • 加载原始播放列表时添加了gzip支持(“ superwash”现在仅在gzip中提供ttv.all.tag.player.m3u)。 与以前一样,您创建的播放列表将以文本/纯文本形式给出。
  • 新增了从原始播放列表获取徽标链接的功能。

Source: https://habr.com/ru/post/zh-CN438842/


All Articles