Superb quality and spec AB-Com PULSe 4K SE. Crazy offer! Only £99! FREE UK DELIVERY! 4K UHD, Enigma 2, Multiboot 4 images & more!...
Superb quality and spec AB-Com PULSe 4K Rev II Twin Satellite tuner only £149! FREE UK DELIVERY! 4K UHD, Enigma 2, SATA HDD facility, Multiboot 4 images & more!...

[ABM-MISC] ABM Hacks Examples

Status
Not open for further replies.

Huevos

Administrator
Staff member
Joined
Jun 20, 2010
Messages
15,671
Reaction score
494
Points
83
Location
38.5N, 0.5W
This thread is for example ABM Hacks.

Example files now go in:
/etc/enigma2/AutoBouquetsMaker/custom

The old location was:
/usr/lib/enigma2/python/Plugins/SystemPlugins/AutoBouquetsMaker/custom
 
Last edited by a moderator:
Sort channels in each section alphabetically.

This can be used for any provider but the attached file would need to be correctly named for the provider being modified. Switch "swap channels" to "no".

Code:
<custommix>
	<hacks>
<![CDATA[

section_numbers = sorted(sections.keys())
for this_section in section_numbers:
	if section_numbers.index(this_section)+1 < len(section_numbers):#this_section < 1000:
		next_section = section_numbers[section_numbers.index(this_section)+1]
	else:
		next_section = 65535
	sort_list = []
	for service in sorted(customised["video"].keys()):
		if service in range(this_section, next_section):
			if 'interactive_name' in customised["video"][service]:
				sort_list.append((customised["video"][service], re.sub('^(?![a-z])', 'zzzzz', customised["video"][service]['interactive_name'].lower())))
			else:
				sort_list.append((customised["video"][service], re.sub('^(?![a-z])', 'zzzzz', customised["video"][service]['service_name'].lower())))
			del customised["video"][service]
	sort_list = sorted(sort_list, key=lambda listItem: listItem[1])
	i = this_section
	for service in sort_list:
		customised["video"][i] = service[0]
		i += 1
			
]]>
	</hacks>
</custommix>
 

Attachments

Create an ITV regions bouquet.

Hades 018+.

For use in conjunction with "Sky UK". This will create an ITV regions bouquet as the last but one bouquet. In ABM -> Configure, "Include not indexed channels" must be set to "Yes".

sat_282_sky_uk_CustomMix.xml:
Code:
<custommix>
	<hacks>
<![CDATA[

ITVs = []
ITVsPlusOne = []
rest = []
last_section = max(sections.keys())
last_section_name = sections[last_section]

for service in sorted(services["sat_282_sky_uk"]["video"].keys()):
	if service in range(last_section, 1450) or service in [103, 133, 178]:
		# ITV regions
		if 'interactive_name' in services["sat_282_sky_uk"]["video"][service] and (service in [103,178] or (service in range(last_section, 1450) and '+1' not in services["sat_282_sky_uk"]["video"][service]["interactive_name"] and ('ITV' in services["sat_282_sky_uk"]["video"][service]["interactive_name"] or 'STV' in services["sat_282_sky_uk"]["video"][service]["interactive_name"] or 'UTV' in services["sat_282_sky_uk"]["video"][service]["interactive_name"]))):
			ITVs.append(services["sat_282_sky_uk"]["video"][service])
			
		# ITV +1 regions
		elif 'interactive_name' in services["sat_282_sky_uk"]["video"][service] and (service in [133] or (service in range(last_section, 1450) and '+1' in services["sat_282_sky_uk"]["video"][service]["interactive_name"] and ('ITV' in services["sat_282_sky_uk"]["video"][service]["interactive_name"] or 'STV' in services["sat_282_sky_uk"]["video"][service]["interactive_name"] or 'UTV' in services["sat_282_sky_uk"]["video"][service]["interactive_name"]))):
			ITVsPlusOne.append(services["sat_282_sky_uk"]["video"][service])
		
		else:
			rest.append(services["sat_282_sky_uk"]["video"][service])

i = last_section
sections[i] = "ITV Regions"

sort_list = []
for x in ITVs:
	sort_list.append((x, re.sub('^(?![a-z])', 'zzzzz', x['interactive_name'].lower())))
sort_list = sorted(sort_list, key=lambda listItem: listItem[1])
for service in sort_list:
	customised["video"][i] = service[0]
	i += 1
			
sort_list = []
for x in ITVsPlusOne:
	sort_list.append((x, re.sub('^(?![a-z])', 'zzzzz', x['interactive_name'].lower())))
sort_list = sorted(sort_list, key=lambda listItem: listItem[1])
for service in sort_list:
	customised["video"][i] = service[0]
	i += 1
		
sections[i] = last_section_name	
sort_list = []
for x in rest:
	sort_list.append((x, re.sub('^(?![a-z])', 'zzzzz', x['service_name'].lower())))
sort_list = sorted(sort_list, key=lambda listItem: listItem[1])
for service in sort_list:
	customised["video"][i] = service[0]
	i += 1
			
]]>
	</hacks>
</custommix>

grab.webp
 

Attachments

Last edited:
Create a timeshift bouquet.

For Sky UK. Creates a bouquet with "+1", "+2" and "+24" channels. Bouquet is placed after the interactive sections so as not to interfere with numbering.

Code:
<custommix>
	<hacks>
<![CDATA[

timeshift = []
rest = []
last_section = max(sections.keys())
last_section_name = sections[last_section]

for service in sorted(services["sat_282_sky_uk"]["video"].keys()):
	if service in range(last_section, 1450):
		rest.append(services["sat_282_sky_uk"]["video"][service])
	elif service < 1000 and ("+1" in services["sat_282_sky_uk"]["video"][service]["service_name"] or "+2" in services["sat_282_sky_uk"]["video"][service]["service_name"]):
		timeshift.append(services["sat_282_sky_uk"]["video"][service])
		
i = last_section
sections[i] = "Timeshift"

sort_list = []
for x in timeshift:
	sort_list.append((x, re.sub('^(?![a-z])', 'zzzzz', x['service_name'].lower())))
sort_list = sorted(sort_list, key=lambda listItem: listItem[1])
for service in sort_list:
	customised["video"][i] = service[0]
	i += 1

sections[i] = last_section_name	
sort_list = []
for x in rest:
	sort_list.append((x, re.sub('^(?![a-z])', 'zzzzz', x['service_name'].lower())))
sort_list = sorted(sort_list, key=lambda listItem: listItem[1])
for service in sort_list:
	customised["video"][i] = service[0]
	i += 1
			
]]>
	</hacks>
</custommix>

grab.webp
 

Attachments

For those who want number printed next to channel name.

Only 1-999 are numbered (inclusive of enforced numbers, i.e where we give a channel a number in that range. Eg Setanta sports)

This will break SNPicons

Code:
<custommix>
    <hacks>
<![CDATA[

for service in sorted(services[section_identifier]["video"].keys()):
    if service in range(1,1000):
        if "interactive_name" in services[section_identifier]["video"][service]:
            services[section_identifier]["video"][service]["interactive_name"] = str(services[section_identifier]["video"][service]["number"]) + " - " + services[section_identifier]["video"][service]["interactive_name"]
        else:
            services[section_identifier]["video"][service]["interactive_name"] = str(services[section_identifier]["video"][service]["number"]) + " - " + services[section_identifier]["video"][service]["service_name"]
            
]]>

    </hacks>
</custommix>



To show channel numbers on Info bars:
Menu > Setup > System > User Interface > Settings > Show channel number in infobar
Change this to yes and Restart E2 for setting to be applied.

N.B
Enigma2 does not have numbering. The numbers are dynamic and based on the order in which bouquets/channels are loaded. As such not easy to do for Graphical EPG screen.


Edit: mark II version... allows swap to display the correct numbers. For use in OpenViX 4.2.001+.

Code:
<custommix>
	<hacks>
<![CDATA[

# swap channel numbers. Only swaps number. Channel swap is still done in bouquetwriter.py
if providerConfig.isSwapChannels() and "swapchannels" in providers[section_identifier] and len(providers[section_identifier]["swapchannels"]) > 0 and "preferred_order" in providers[section_identifier]["swapchannels"][0]:
	for swaprule in providers[section_identifier]["swapchannels"][0]["preferred_order"]:
		if swaprule[0] in services[section_identifier]["video"] and swaprule[1] in services[section_identifier]["video"] and services[section_identifier]["video"][swaprule[1]]["service_type"] >= 17:
			customised["video"][swaprule[0]]["number"] = swaprule[1]
			customised["video"][swaprule[1]]["number"] = swaprule[0]
			
for service in sorted(customised["video"].keys()):
    if service in range(1,1000):
        if "interactive_name" in customised["video"][service]:
            customised["video"][service]["interactive_name"] = str(customised["video"][service]["number"]) + " - " + customised["video"][service]["interactive_name"]
        else:
            customised["video"][service]["interactive_name"] = str(customised["video"][service]["number"]) + " - " + customised["video"][service]["service_name"]

]]>

    </hacks>
</custommix>
 

Attachments

Last edited by a moderator:
Create csv file

These will make a csv file containing:
Interactive name
Service reference
Channel Name
Official LCN (Logical Channel Number)
EPG/Channel ID
Encryption type (some are wrong on the tables)
Provider name
IPTV link
TSID
Service type
Ocram Picon SRP value


EDIT:
These are not compatible with Python 3 images
 

Attachments

Last edited:
This is a test provider file. It goes in the provider folder. You can sort by the Channel/EPG ID, LCN, Name
 

Attachments

Last edited by a moderator:
Add FTV channels to FTA only

Code:
<custommix>
    <hacks>
<![CDATA[

ftv_IDs = [
    1016, # Liverpool TV
    1078, # Birmingham TV
    1758, # 4Music
    2615, # YESTERDAY +1
    5043, # Tyne & Wear TV
    5090, # London Live
    5315, # Bristol TV
    5536, # Cardiff TV
    5537, # Leeds TV
]

for number in customised["video"].keys():
    if customised["video"][number]["channel_id"] in ftv_IDs:
        customised["video"][number]["free_ca"] = 0
    elif customised["video"][number]["free_ca"] == 1:
        del customised["video"][number]
            
]]>
    </hacks>
</custommix>

grab1.webp

grab2.webp

grab3.webp

grab4-jpg.webp
 

Attachments

Last edited by a moderator:
Place all News channels in the News bouquet.

N.B. You will get an "All channels" bouquet as a result of this hack.

Code:
<custommix>
    <hacks>
<![CDATA[

exceptions = {
    570:"News",
    571:"News",
    572:"News",
    573:"News",
    574:"News",
    575:"News",
    576:"News",
    577:"News",
    578:"News",
    579:"News"
}

hacked_bouquets = {}
next_lcn = max(customised["video"].keys())+1
sections_copy = {min(sections.keys()): "All channels"}
for section in sections:
    hacked_bouquets[sections[section]] = []

for service in sorted(services[section_identifier]["video"].keys()):
    if service in exceptions and exceptions[service] in hacked_bouquets:
        hacked_bouquets[exceptions[services[section_identifier]["video"][service]["number"]]].append(services[section_identifier]["video"][service])
    else:
        sec_list = []
        for x in sections:
            if int(x) <= service:
                sec_list.append(x)
        section_number = max(sec_list)
        hacked_bouquets[sections[section_number]].append(services[section_identifier]["video"][service])
        
for section in sorted(sections.keys()):
    sections_copy[next_lcn] = sections[section]
    for service in hacked_bouquets[sections[section]]:
        customised["video"][next_lcn] = service
        next_lcn += 1
        
sections = sections_copy
            
]]>
    </hacks>
</custommix>

Edit: No longer valid after 2018-05-01 changes.
 

Attachments

Last edited by a moderator:
Rename channels based on numbers

Code:
<custommix>
    <hacks>
<![CDATA[

rename = {
    101: "My name for 101",
    102: "My name for 102",
    103: "My name for 103"
    }
    
# Rename channels
for channel_number in sorted(customised["video"].keys()):
    if channel_number in rename:
        customised["video"][channel_number]["interactive_name"] = rename[channel_number]
    
]]>
    </hacks>
</custommix>
 

Attachments

Class that contains some tools for working on <hacks>
Code:
import re

class FavTools():
	def makeSpace(self, customised, sections, pos, length):
		# make some space part way through the channel list to insert a section.
		# all channels below will be shifted down and renumbered
		customised_tmp = {}
		sections_tmp = {}
		
		for sec_num in sorted(sections.keys()):
			sections_tmp[sec_num + (0 if sec_num < pos else length)] = sections[sec_num]
		sections = sections_tmp
		
		for service in sorted(customised["video"].keys()):
			customised_tmp[service + (0 if service < pos else length)] = customised["video"][service]
		customised["video"] = customised_tmp
		return customised, sections
		
	def getSectionNumber(self, sections, section_name):
		# returns section number for any given section name
		for section, name in sections.iteritems():
			if name == section_name:
				return section
	
	def getNextSection(self, sections, section_name):
		#returns next section number when given the name of the current section
		thisSection = self.getSectionNumber(sections, section_name)
		if thisSection is None:
			return
		for section in sorted(sections.keys()):
			if section > thisSection:
				return section
				
	def getLastServiceInSection(self, services, sections, section_name):
		ret = None
		thisSection = self.getSectionNumber(sections, section_name)
		if thisSection is None:
			return
		nextSection = self.getNextSection(sections, section_name)
		lastService = 0
		if nextSection is None:
			return max(services.keys())
		for service in sorted(services.keys()):
			if service >= thisSection and service < nextSection:
				ret = service
		return ret
		
	def listChannelsInSection(self, services, providers, provider, section_name):
		# returns LCN list
		if provider not in services:
			return []
		thisSection = self.getSectionNumber(sections, section_name)
		if thisSection is None:
			return []
		nextSection = self.getNextSection(sections, section_name)
		if nextSection is none:
			nextSection = 65536
		ret = []
		for service in sorted(services[sky]["video"].keys()):
			if service >= thisSection and service < nextSection:
				ret.append(service)
		return ret		

	def sortListFlatAlpha(self, services):
		#returns list of services in alphabetical order by service name (or interactive name if it is set).
		sort_list = []
		for service in services:
			if 'interactive_name' in service:
				sort_list.append((service, re.sub('^(?![a-z])', 'zzzzz', service['interactive_name'].lower())))
			else:
				sort_list.append((service, re.sub('^(?![a-z])', 'zzzzz', service['service_name'].lower())))
		sort_list = sorted(sort_list, key=lambda listItem: listItem[1])
		return [i[0] for i in sort_list]
		
	def sortDictFlatAlpha(self, services):
		# services is a dict with LCNs as keys
		# returns keys, sorted flat alphabetic by service name (or interactive name if it is set).
		sort_list = []
		for lcn in services:
			if "interactive_name" in services[lcn]:
				sort_list.append((lcn, re.sub('^(?![a-z])', 'zzzzz', services[lcn]['interactive_name'].lower())))
			else:
				sort_list.append((lcn, re.sub('^(?![a-z])', 'zzzzz', services[lcn]['service_name'].lower())))
		sort_list = sorted(sort_list, key=lambda listItem: listItem[1])
		return [i[0] for i in sort_list]
		
	def getHDchannelList(self, services, providers, providerConfigs, provider, skipLastSection=False):
		# returns LCNs
		HD_channels_numbers = []
		last_section = 65536
		if skipLastSection:
			last_section = max(providers[provider]["sections"].keys())
		for service in sorted(services[provider]["video"].keys()):
			if service < last_section and services[provider]["video"][service]["service_type"] in DvbScanner.HD_ALLOWED_TYPES:
				HD_channels_numbers.append(service)
		
		# Apply channels-on-top
		hd_channels_numbers_tmp = HD_channels_numbers
		if providerConfigs[provider].getArea().startswith('sd'):
			channels_on_top = providers[provider]["sdchannelsontop"]
			channels_on_top_tmp = list(providers[provider]["sdchannelsontop"])
		else:
			channels_on_top = providers[provider]["hdchannelsontop"]
			channels_on_top_tmp = list(providers[provider]["hdchannelsontop"])
		channels_on_top_tmp = list(channels_on_top)
		for number in channels_on_top:
			if number in hd_channels_numbers_tmp:
				hd_channels_numbers_tmp.remove(number)
			else:
				channels_on_top_tmp.remove(number)
		hd_channels_numbers = channels_on_top_tmp
		hd_channels_numbers += hd_channels_numbers_tmp
		return hd_channels_numbers
Tool for getting ITV channels and sorting them.
Code:
def SkyUKITVs(services, providers):
	sky = "sat_282_sky_uk"
	if sky not in services:
		return []
	ITVs = []
	ITVsPlusOne = []
	last_sky_section = max(providers[sky]["sections"].keys())
	not_indexed_itv = []
	
	for service in sorted(services[sky]["video"].keys()):
		if service in range(last_sky_section, 1450) or service in [103, 133, 178]:
			# ITV regions
			if 'interactive_name' in services[sky]["video"][service] and (service in [103,178] or (service in range(last_sky_section, 1450) and '+1' not in services[sky]["video"][service]["interactive_name"] and ('ITV' in services[sky]["video"][service]["interactive_name"] or 'STV' in services[sky]["video"][service]["interactive_name"] or 'UTV' in services[sky]["video"][service]["interactive_name"]))):
				ITVs.append(services[sky]["video"][service])
				if service >= last_sky_section:
					not_indexed_itv.append(service)
	
			# ITV +1 regions
			elif 'interactive_name' in services[sky]["video"][service] and (service in [133] or (service in range(last_sky_section, 1450) and '+1' in services[sky]["video"][service]["interactive_name"] and ('ITV' in services[sky]["video"][service]["interactive_name"] or 'STV' in services[sky]["video"][service]["interactive_name"] or 'UTV' in services[sky]["video"][service]["interactive_name"]))):
				ITVsPlusOne.append(services[sky]["video"][service])
				if service >= last_sky_section:
					not_indexed_itv.append(service)
	
	ITVs = FavTools().sortListFlatAlpha(ITVs)
	ITVs += FavTools().sortListFlatAlpha(ITVsPlusOne)
	return ITVs, not_indexed_itv
 
Using the Humber region and the latest provider file, I get ITV Yorkshire West HD on 103 and ITV Yorkshire East on 176...
That is the default behaviour. If there is not a simulcast HD channel available ABM will select the substitute HD channel provided by the broadcaster. More on that here: ITV HD channel scanned by ABM doesn't match local region.

If you want to override that behaviour and only swap the simulcast versions of BBC/ITV, not the substitutes, you can try the following:
Code:
<custommix>
	<hacks>
<![CDATA[

# this hack prevents non-similcast services between 101 and 103 from swapping. Based on the premise that a service is only similcast if it is in the 800's.
if providerConfig.isSwapChannels():
	providerConfig.unsetSwapChannels()
	swapDict = {}
	for swaprule in providers[section_identifier]["swapchannels"]:
		if swaprule[0] in services[section_identifier]["video"] and swaprule[1] in services[section_identifier]["video"] and services[section_identifier]["video"][swaprule[1]]["service_type"] in DvbScanner.HD_ALLOWED_TYPES and services[section_identifier]["video"][swaprule[0]]["service_type"] not in DvbScanner.HD_ALLOWED_TYPES:
			conditional = len(swaprule) > 2 and swaprule[2] or None
			if not conditional or eval(conditional, {}, {'service_sd': services[section_identifier]["video"][swaprule[0]], 'service_hd': services[section_identifier]["video"][swaprule[1]]}):
				if swaprule[0] in range(101,104) and swaprule[1] not in range(801,804):
					continue
				swapDict[swaprule[0]] = swaprule[1]
				swapDict[swaprule[1]] = swaprule[0]
	for number in swapDict:
		customised["video"][number] = services[section_identifier]["video"][swapDict[number]]
		
]]>
    </hacks>
</custommix>

ABM-config.webp

ABM-main.webp

ABM-HD.webp
 

Attachments

Last edited:
Add CH 4 HD to Freesat at position 126 without scanning Sky UK.

CH 4 HD is no longer part of Freesat but as long as it exists in lamedb it can be inserted into the Freesat line up without needing to scan other providers.

The channel will be added to 126, so enable swap to place it into 104

Code:
<custommix>
    <hacks>
<![CDATA[

customised["video"][126] = {'service_type': 0x19, 'service_id': 0x52d0, 'transport_stream_id': 0x0814, 'original_network_id': 0x0002, 'namespace': 0x011a0000, 'free_ca': 0x0} # CH 4 HD

]]>
    </hacks>
</custommix>
 

Attachments

Last edited by a moderator:
Delete some services that cannot be received. Particularly useful for users in Freeview light areas

Code:
<custommix>
    <deletes>
    <!-- Delete channels that do not work --> 
        <delete target="8"></delete>
        <delete target="9"></delete>
        <delete target="11"></delete>
        <delete target="12"></delete>
        <delete target="16"></delete>
        <delete target="17"></delete>
        <delete target="18"></delete>
        <delete target="19"></delete>
        <delete target="20"></delete>
        <delete target="21"></delete>
        <delete target="22"></delete>
        <delete target="23"></delete>
        <delete target="25"></delete>
        <delete target="26"></delete>
        <delete target="27"></delete>
        <delete target="29"></delete>
        <delete target="30"></delete>
        <delete target="31"></delete>
        <delete target="32"></delete>
        <delete target="34"></delete>
        <delete target="35"></delete>
        <delete target="36"></delete>
        <delete target="37"></delete>
        <delete target="38"></delete>
        <delete target="39"></delete>
        <delete target="40"></delete>
        <delete target="41"></delete>
        <delete target="42"></delete>
        <delete target="43"></delete>
        <delete target="44"></delete>
        <delete target="46"></delete>
        <delete target="47"></delete>
        <delete target="48"></delete>
        <delete target="49"></delete>
        <delete target="50"></delete>
        <delete target="54"></delete>
        <delete target="57"></delete>
        <delete target="58"></delete>
        <delete target="59"></delete>
        <delete target="60"></delete>
        <delete target="61"></delete>
        <delete target="62"></delete>
        <delete target="63"></delete>
        <delete target="64"></delete>
        <delete target="65"></delete>
        <delete target="66"></delete>
        <delete target="68"></delete>
        <delete target="70"></delete>
        <delete target="71"></delete>
        <delete target="72"></delete>
        <delete target="74"></delete>
        <delete target="77"></delete>
        <delete target="79"></delete>
        <delete target="80"></delete>
        <delete target="81"></delete>
        <delete target="83"></delete>
        <delete target="85"></delete>
        <delete target="203"></delete>
        <delete target="206"></delete>
        <delete target="207"></delete>
        <delete target="208"></delete>
        <delete target="233"></delete>
        <delete target="234"></delete>
        <delete target="672"></delete>
        <delete target="673"></delete>
        <delete target="674"></delete>
        <delete target="675"></delete>
        <delete target="678"></delete>
        <delete target="679"></delete>
    </deletes>
    <hacks>
<![CDATA[

]]>

    </hacks>
</custommix>
 

Attachments

Create a stream relay bouquet

Code:
<custommix>
    <hacks>
<![CDATA[

# TSIDs that contain services that need stream relay (or this could be done by LCN or CHID).
TSIDs = [0x7D3, 0x7D7, 0x7D8, 0x7DB, 0x7DC, 0x7E0, 0x7E3, 0x7E4, 0x7E5, 0x7E7, 0x7E8, 0x7E9, 0x7EA, 0x7EB, 0x7EC, 0x7ED, 0x7EE, 0x7F0, 0x7F2, 0x811, 0x838, 0x841, 0x842]

for service in sorted(list(services[section_identifier]["video"].keys())):
		serv = services[section_identifier]["video"][service]
		if serv["transport_stream_id"] in TSIDs and "free_ca" in serv and serv["free_ca"] == 1: # only on listed transponders and only encrypted services
			url = "http://127.0.0.1:17999/1:0:1:%x:%x:%x:%x:0:0:0:" % (
				serv["service_id"],
				serv["transport_stream_id"],
				serv["original_network_id"],
				serv["namespace"],
			)
			serv["stream"] = quote(url)
			serv["namespace"] = 33 # writing a dummy namespace is a requirement of stream relay
            
]]>
    </hacks>
</custommix>

In the above example above there is a TSID list that belongs to 28.2E so we know which service lines to modify. Do similar with other providers.

As stream relay services are on transponders that are currently disabled in the provider file "broken_TSIDS" will need commenting out... and then run the scan on an "sdcustom" region.

Code:
	broken_TSIDS = [
#		2007, #7d7 20170518
#		2011, #7db 20170425
#		2012, #7dc 20170518
#		2019, #7e3 20170518
#		2021, #7e5 20170516
#		2023, #7e7 20170331
#		2025, #7e9 20170518
#		2026, #7ea 20170425
#		2029, #7ed 20170516
	]
 
Create a stream relay bouquet by LCN

Code:
<custommix>
    <hacks>
<![CDATA[

# LCNs (channel numbers) that need stream relay.
LCNs = [106, 107]

for service in sorted(list(services[section_identifier]["video"].keys())):
		serv = services[section_identifier]["video"][service]
		if service in LCNs and ("free_ca" not in serv or serv["free_ca"] == 1): # only on listed transponders and only encrypted services
			url = "http://127.0.0.1:17999/1:0:1:%x:%x:%x:%x:0:0:0:" % (
				serv["service_id"],
				serv["transport_stream_id"],
				serv["original_network_id"],
				serv["namespace"],
			)
			serv["stream"] = quote(url)
			serv["namespace"] = 33 # writing a dummy namespace is a requirement of stream relay
            
]]>
    </hacks>
</custommix>
 
Creates a whitelist file.
Code:
<!-- Do not use ABM custom providers while using this mix file -->
<custommix>
    <hacks>
<![CDATA[

def makeServiceRef(service):
	return "1:0:%X:%X:%X:%X:%X:0:0:0:" % (
		service["service_type"],
		service["service_id"],
		service["transport_stream_id"],
		service["original_network_id"],
		service["namespace"],
	)

TSIDs = [0x7D3, 0x7D7, 0x7D8, 0x7DB, 0x7DC, 0x7E0, 0x7E3, 0x7E4, 0x7E5, 0x7E7, 0x7E8, 0x7E9, 0x7EA, 0x7EB, 0x7EC, 0x7ED, 0x7EE, 0x7F0, 0x7F2, 0x811, 0x82D, 0x838, 0x841, 0x842]
CHIDs = [0x44B, 0x48F, 0x490, 0x492, 0x4BA, 0x4C2, 0x4E2, 0x4F6, 0x551, 0xB00, 0xFC2, 0xFD2, 0xFD6, 0x177E]

changed = False

streamrelayrefs = [line.strip() for line in open('/etc/enigma2/whitelist_streamrelay', 'r').readlines()] if os.path.isfile('/etc/enigma2/whitelist_streamrelay') else []

for service in sorted(list(services[section_identifier]["video"].keys())):
	serv = services[section_identifier]["video"][service]
	if serv["transport_stream_id"] in TSIDs and ("free_ca" not in serv or serv["free_ca"] == 1) and (serv["service_type"] not in DvbScanner.HD_ALLOWED_TYPES or "channel_id" in serv and serv["channel_id"] in CHIDs):
		sref = makeServiceRef(serv)
		if sref not in streamrelayrefs:
			streamrelayrefs.append(sref)
			changed = True
	elif ("free_ca" not in serv or serv["free_ca"] == 1) and serv["service_type"] in DvbScanner.HD_ALLOWED_TYPES:
		del services[section_identifier]["video"][service]
		del customised["video"][service]

if changed:
	streamrelayrefs.sort(key=lambda ref: ((x:=ref.split(":"))[6], x[5], x[4], x[3]))
	open('/etc/enigma2/whitelist_streamrelay', 'w').write('\n'.join(streamrelayrefs))
	try:
		from Screens.InfoBarGenerics import reload_streamrelay
		reload_streamrelay()
	except:
		pass
            
]]>
    </hacks>
</custommix>
 
Stream Relay OpenViX 6.4.010 and above

Code:
<!-- Do not use ABM custom providers while using this mix file -->
<custommix>
    <hacks>
<![CDATA[

def makeServiceRef(service):
	return "1:0:%X:%X:%X:%X:%X:0:0:0:" % (
		service["service_type"],
		service["service_id"],
		service["transport_stream_id"],
		service["original_network_id"],
		service["namespace"],
	)

TSIDs = [0x7D3, 0x7D7, 0x7D8, 0x7DB, 0x7DC, 0x7E0, 0x7E3, 0x7E4, 0x7E5, 0x7E7, 0x7E8, 0x7E9, 0x7EA, 0x7EB, 0x7EC, 0x7ED, 0x7EE, 0x7F0, 0x7F2, 0x82D, 0x838, 0x841, 0x842]
CHIDs = [0x44B, 0x48F, 0x490, 0x492, 0x4BA, 0x4C2, 0x4E2, 0x4F6, 0x551, 0xB00, 0xFC2, 0xFD2, 0xFD6, 0x177E]
whitelist = [1372, 3812, 3831, 4039, 4056]

changed = False

try:
	from Screens.InfoBarGenerics import streamrelay
except:
	streamrelay = None

streamrelayrefs = streamrelay and streamrelay.data[:] or [line.strip() for line in open('/etc/enigma2/whitelist_streamrelay', 'r').readlines()] if os.path.isfile('/etc/enigma2/whitelist_streamrelay') else []

for service in sorted(list(services[section_identifier]["video"].keys())):
	serv = services[section_identifier]["video"][service]
	if serv["transport_stream_id"] in TSIDs and ("free_ca" not in serv or serv["free_ca"] == 1) and (serv["service_type"] not in DvbScanner.HD_ALLOWED_TYPES or "channel_id" in serv and serv["channel_id"] in CHIDs):
		sref = makeServiceRef(serv)
		if sref not in streamrelayrefs:
			streamrelayrefs.append(sref)
			changed = True
	elif ("free_ca" not in serv or serv["free_ca"] == 1) and serv["service_type"] in DvbScanner.HD_ALLOWED_TYPES and "channel_id" in serv and serv["channel_id"] not in whitelist:
		del services[section_identifier]["video"][service]
		del customised["video"][service]

if changed:
	if streamrelay:
		streamrelay.data = streamrelayrefs
	else:
		open('/etc/enigma2/whitelist_streamrelay', 'w').write('\n'.join(streamrelayrefs))
            
]]>
    </hacks>
</custommix>
 
Create an ITV regions bouquet

Updated version of #3 which is now 9 years old.

Code:
<custommix>
	<hacks>
<![CDATA[

ITVs = []
ITVsPlusOne = []
rest = []
last_section = max(sections.keys())
last_section_name = sections[last_section]

for service in sorted(services["sat_282_sky_uk"]["video"].keys()):
	if service in range(last_section, 1450) or service in (103, 203):
		# ITV regions
		ch_name = 'interactive_name' in services["sat_282_sky_uk"]["video"][service] and services["sat_282_sky_uk"]["video"][service]["interactive_name"] or services["sat_282_sky_uk"]["video"][service]["service_name"]
		if ch_name.startswith(("ITV", "STV", "UTV")):
			services["sat_282_sky_uk"]["video"][service]["ch_name"] = ch_name
			if "+1" not in ch_name:
				ITVs.append(services["sat_282_sky_uk"]["video"][service])
			else:
				ITVsPlusOne.append(services["sat_282_sky_uk"]["video"][service])
		else:
			rest.append(services["sat_282_sky_uk"]["video"][service])

i = last_section
sections[i] = "ITV Regions"

for service in sorted(ITVs, key=lambda x: x["ch_name"].lower()) + sorted(ITVsPlusOne, key=lambda x: x["ch_name"].lower()):
	customised["video"][i] = service
	i += 1

sections[i] = last_section_name
sort_list = []
for x in rest:
	sort_list.append((x, re.sub('^(?![a-z])', 'zzzzz', x['service_name'].lower())))
sort_list = sorted(sort_list, key=lambda listItem: listItem[1])
for service in sort_list:
	customised["video"][i] = service[0]
	i += 1

]]>
	</hacks>
</custommix>
 
Status
Not open for further replies.

OpenViX Feeds Status

Back
Top