|
a/rdpl2stream/StreamDecoder.py |
|
b/rdpl2stream/StreamDecoder.py |
|
... |
|
... |
15 |
#
|
15 |
#
|
16 |
# You should have received a copy of the GNU General Public License
|
16 |
# You should have received a copy of the GNU General Public License
|
17 |
# along with Radio Tray. If not, see <http://www.gnu.org/licenses/>.
|
17 |
# along with Radio Tray. If not, see <http://www.gnu.org/licenses/>.
|
18 |
#
|
18 |
#
|
19 |
##########################################################################
|
19 |
##########################################################################
|
|
|
20 |
from __future__ import print_function
|
|
|
21 |
|
20 |
import urllib2
|
22 |
import urllib2
|
|
|
23 |
import sys
|
21 |
from lib.common import USER_AGENT
|
24 |
from lib.common import USER_AGENT
|
22 |
from lib.DummyMMSHandler import DummyMMSHandler
|
25 |
from lib.DummyMMSHandler import DummyMMSHandler
|
23 |
from PlsPlaylistDecoder import PlsPlaylistDecoder
|
26 |
from PlsPlaylistDecoder import PlsPlaylistDecoder
|
24 |
from M3uPlaylistDecoder import M3uPlaylistDecoder
|
27 |
from M3uPlaylistDecoder import M3uPlaylistDecoder
|
25 |
from AsxPlaylistDecoder import AsxPlaylistDecoder
|
28 |
from AsxPlaylistDecoder import AsxPlaylistDecoder
|
26 |
from XspfPlaylistDecoder import XspfPlaylistDecoder
|
29 |
from XspfPlaylistDecoder import XspfPlaylistDecoder
|
27 |
from AsfPlaylistDecoder import AsfPlaylistDecoder
|
30 |
from AsfPlaylistDecoder import AsfPlaylistDecoder
|
28 |
from RamPlaylistDecoder import RamPlaylistDecoder
|
31 |
from RamPlaylistDecoder import RamPlaylistDecoder
|
29 |
from UrlInfo import UrlInfo
|
32 |
from UrlInfo import UrlInfo
|
30 |
import logging
|
|
|
31 |
|
33 |
|
|
|
34 |
class Logger:
|
|
|
35 |
def mprint(self, m):
|
|
|
36 |
#print("%s"%m, file=sys.stderr)
|
|
|
37 |
pass
|
|
|
38 |
def error(self, m):
|
|
|
39 |
self.mprint(m)
|
|
|
40 |
def warn(self, m):
|
|
|
41 |
self.mprint(m)
|
|
|
42 |
def info(self, m):
|
|
|
43 |
self.mprint(m)
|
|
|
44 |
def debug(self, m):
|
|
|
45 |
self.mprint(m)
|
|
|
46 |
|
32 |
class StreamDecoder:
|
47 |
class StreamDecoder:
|
33 |
|
48 |
|
34 |
def __init__(self, cfg_provider):
|
49 |
def __init__(self, cfg_provider):
|
35 |
plsDecoder = PlsPlaylistDecoder()
|
50 |
plsDecoder = PlsPlaylistDecoder()
|
36 |
m3uDecoder = M3uPlaylistDecoder()
|
51 |
m3uDecoder = M3uPlaylistDecoder()
|
37 |
asxDecoder = AsxPlaylistDecoder()
|
52 |
asxDecoder = AsxPlaylistDecoder()
|
38 |
xspfDecoder = XspfPlaylistDecoder()
|
53 |
xspfDecoder = XspfPlaylistDecoder()
|
39 |
asfDecoder = AsfPlaylistDecoder()
|
54 |
asfDecoder = AsfPlaylistDecoder()
|
40 |
ramDecoder = RamPlaylistDecoder()
|
55 |
ramDecoder = RamPlaylistDecoder()
|
41 |
|
56 |
|
42 |
self.log = logging.getLogger('radiotray')
|
57 |
self.log = Logger()
|
43 |
|
58 |
|
44 |
self.decoders = [plsDecoder, asxDecoder, asfDecoder, xspfDecoder, ramDecoder, m3uDecoder]
|
59 |
self.decoders = [plsDecoder, asxDecoder, asfDecoder, xspfDecoder, ramDecoder, m3uDecoder]
|
45 |
|
60 |
|
46 |
self.url_timeout = None
|
61 |
self.url_timeout = None
|
47 |
|
62 |
|
|
... |
|
... |
54 |
except Exception, e:
|
69 |
except Exception, e:
|
55 |
self.log.warn("Couldn't find url_timeout configuration")
|
70 |
self.log.warn("Couldn't find url_timeout configuration")
|
56 |
self.url_timeout = 100
|
71 |
self.url_timeout = 100
|
57 |
cfg_provider.setConfigValue("url_timeout", str(self.url_timeout))
|
72 |
cfg_provider.setConfigValue("url_timeout", str(self.url_timeout))
|
58 |
|
73 |
|
59 |
self.log.info('Using url timeout = %s', str(self.url_timeout))
|
74 |
self.log.info('Using url timeout = %s'% str(self.url_timeout))
|
60 |
|
75 |
|
61 |
|
76 |
|
62 |
def getMediaStreamInfo(self, url):
|
77 |
def getMediaStreamInfo(self, url):
|
63 |
|
78 |
|
64 |
if url.startswith("http") == False:
|
79 |
if url.startswith("http") == False:
|
65 |
self.log.info('Not an HTTP url. Maybe direct stream...')
|
80 |
self.log.info('Not an HTTP url. Maybe direct stream...')
|
66 |
return UrlInfo(url, False, None)
|
81 |
return UrlInfo(url, False, None)
|
67 |
|
82 |
|
68 |
self.log.info('Requesting stream... %s', url)
|
83 |
self.log.info('Requesting stream... %s'% url)
|
69 |
req = urllib2.Request(url)
|
84 |
req = urllib2.Request(url)
|
70 |
req.add_header('User-Agent', USER_AGENT)
|
85 |
req.add_header('User-Agent', USER_AGENT)
|
71 |
|
86 |
|
72 |
try:
|
87 |
try:
|
73 |
opener = urllib2.build_opener(DummyMMSHandler())
|
88 |
opener = urllib2.build_opener(DummyMMSHandler())
|
74 |
f = opener.open(req, timeout=float(self.url_timeout))
|
89 |
f = opener.open(req, timeout=float(self.url_timeout))
|
75 |
|
90 |
|
76 |
except urllib2.HTTPError, e:
|
91 |
except urllib2.HTTPError, e:
|
77 |
self.log.warn('HTTP Error: No radio stream found for %s - %s', url, str(e))
|
92 |
self.log.warn('HTTP Error: No radio stream found for %s - %s' %
|
|
|
93 |
(url, str(e)))
|
78 |
return None
|
94 |
return None
|
79 |
except urllib2.URLError, e:
|
95 |
except urllib2.URLError, e:
|
80 |
self.log.info('No radio stream found for %s', url)
|
96 |
self.log.info('No radio stream found for %s'% url)
|
81 |
if str(e.reason).startswith('MMS REDIRECT'):
|
97 |
if str(e.reason).startswith('MMS REDIRECT'):
|
82 |
newurl = e.reason.split("MMS REDIRECT:",1)[1]
|
98 |
newurl = e.reason.split("MMS REDIRECT:",1)[1]
|
83 |
self.log.info('Found mms redirect for: %s', newurl)
|
99 |
self.log.info('Found mms redirect for: %s' % newurl)
|
84 |
return UrlInfo(newurl, False, None)
|
100 |
return UrlInfo(newurl, False, None)
|
85 |
else:
|
101 |
else:
|
86 |
return None
|
102 |
return None
|
87 |
except Exception, e:
|
103 |
except Exception, e:
|
88 |
self.log.warn('No radio stream found. Error: %s', str(e))
|
104 |
self.log.warn('No radio stream found. Error: %s'% str(e))
|
89 |
return None
|
105 |
return None
|
90 |
|
106 |
|
91 |
metadata = f.info()
|
107 |
metadata = f.info()
|
92 |
firstbytes = f.read(500)
|
108 |
firstbytes = f.read(500)
|
93 |
f.close()
|
109 |
f.close()
|
94 |
|
110 |
|
95 |
try:
|
111 |
try:
|
96 |
self.log.debug('Metadata obtained...')
|
112 |
self.log.debug('Metadata obtained...')
|
97 |
contentType = metadata["Content-Type"]
|
113 |
contentType = metadata["Content-Type"]
|
98 |
self.log.info('Content-Type: %s', contentType)
|
114 |
self.log.info('Content-Type: %s'% contentType)
|
99 |
|
115 |
|
100 |
|
116 |
|
101 |
except Exception, e:
|
117 |
except Exception, e:
|
102 |
self.log.info("Couldn't read content-type. Maybe direct stream...")
|
118 |
self.log.info("Couldn't read content-type. Maybe direct stream...")
|
103 |
self.log.info('Error: %s',e)
|
119 |
self.log.info('Error: %s'%e)
|
104 |
return UrlInfo(url, False, None)
|
120 |
return UrlInfo(url, False, None)
|
105 |
|
121 |
|
106 |
for decoder in self.decoders:
|
122 |
for decoder in self.decoders:
|
107 |
|
123 |
|
108 |
self.log.info('Checking decoder')
|
124 |
self.log.info('Checking decoder')
|