Skip to content

Instantly share code, notes, and snippets.

@nfedera
Last active August 29, 2015 14:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nfedera/5d32e157eb4fe5ef2369 to your computer and use it in GitHub Desktop.
Save nfedera/5d32e157eb4fe5ef2369 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# cc2m3u.py - channels.conf to m3u converter for Inverto IDL based Sat>IP boxes
#
# Copyright (c) 2015 Norbert Federa
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the copyright holders nor the names of any
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# channels.conf specification:
# http://www.vdr-wiki.de/wiki/index.php/Channels.conf
# outout based on m3u files found here:
# http://www.inverto.tv/downloads/support.php?id=1789
import getopt, sys
def usage(exitcode):
sys.stderr.write('Usage:\n')
sys.stderr.write('cc2m3u.py [-i channels.conf] [-o result.m3u] [-p protocol] [-s server]\n')
sys.stderr.write('- without -i channels.conf data is read from stdin\n')
sys.stderr.write('- without -o m3u data is written to stdout\n')
sys.stderr.write('- default protocol is http\n')
sys.stderr.write('- default server is \'<?=StatusIP?>\'\n')
sys.stderr.write('Example:\n')
sys.stderr.write('Convert file channels.conf for http iptv server http://192.168.123.40:8080\n')
sys.stderr.write(' cc2m3u.py -p http -s 192.168.123.40:8080 -i channels.conf -o playlist.m3u\n')
sys.exit(exitcode)
try:
opts, args = getopt.getopt(sys.argv[1:], "hi:o:p:s:", ["help", "output=", "input=", "protocol=", "server="])
except getopt.GetoptError as err:
print str(err)
usage(1)
input = sys.stdin
output = sys.stdout
ifile = ''
ofile = ''
server = '<?=StatusIP?>'
protocol = 'http'
for opt, arg in opts:
if opt in ("-h", "--help"):
usage(0)
elif opt in ("-i", "--input"):
ifile = arg;
elif opt in ("-o", "--output"):
ofile = arg;
elif opt in ("-s", "--server"):
server = arg;
elif opt in ("-p", "--protocol"):
protocol = arg;
else:
usage(1)
if len(ifile):
input = open(ifile, 'r')
if len(ofile):
output = open(ofile, 'w')
output.write('#EXTM3U\n')
for line in input.readlines():
values = line.strip().split(':')
if len(values) != 13:
continue
name, freq, params, src, srate, vpid, apid, tpid, caid, sid, nid, tid, rid = values
name = name.split(';')[0].replace(' ','_')
if len(name) < 1:
continue
f = int(freq)
if f < 11000 or f > 13000:
continue
params = params.lower();
msys=''
if 's0' in params:
msys = 'dvbs'
elif 's1' in params:
msys = 'dvbs2'
else:
continue;
pol =''
if 'h' in params:
pol = 'h'
elif 'v' in params:
pol='v'
else:
continue;
pids = [0]
p = int(vpid.split('=')[0].split('+')[0]);
if p < 2:
continue;
if not p in pids:
pids.append(p)
for p1 in apid.split(','):
for p2 in p1.split(';'):
p = int(p2.split('=')[0])
if not p in pids:
pids.append(p)
p = int(tid)
if not p in pids:
pids.append(p)
pids.sort()
url = protocol + '://' + server + '/'
url += '?src=1'
url += '&freq={0:d}'.format(int(freq))
url += '&sr={0:d}'.format(int(srate))
url += '&pol={0:s}'.format(pol)
url += '&msys={0:s}'.format(msys)
url += '&pids={0:2}'.format(','.join(map(str,pids)))
url += '\n'
output.write('#EXTINF:-1,{0:s}\n'.format(name))
output.write(url)
input.close()
output.close()
@3PO
Copy link

3PO commented May 1, 2015

Doesnt work on my VDR: :(

vdr01_64 vdr # ./cc2m3u.py -i channels.conf -s 192.168.177.11 -p rtsp -o channels-rtsp.m3u
  File "./cc2m3u.py", line 55
    print str(err)
            ^
SyntaxError: invalid syntax
vdr01_64 vdr #

@3PO
Copy link

3PO commented May 1, 2015

With the following Patch it works. ;)

--- cc2m3u.py.orig  2015-05-01 14:48:28.854571078 +0200
+++ cc2m3u.py   2015-05-01 14:49:09.000000000 +0200
@@ -52,7 +52,7 @@
 try:
     opts, args = getopt.getopt(sys.argv[1:], "hi:o:p:s:", ["help", "output=", "input=", "protocol=", "server="])
 except getopt.GetoptError as err:
-    print str(err)
+    print(file=sys.stderr)
     usage(1)

 input = sys.stdin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment