Exemple #1
0
class TestPluginStream(unittest.TestCase):
    def setUp(self):
        self.session = Livestreamer()

    def assertDictHas(self, a, b):
        for key, value in a.items():
            self.assertEqual(b[key], value)

    def _test_akamaihd(self, surl, host, streamname):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, AkamaiHDStream))
        self.assertEqual(stream.host, host)
        self.assertEqual(stream.streamname, streamname)

    def _test_hls(self, surl, url):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, HLSStream))
        self.assertEqual(stream.url, url)

    def _test_rtmp(self, surl, url, params):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, RTMPStream))
        self.assertEqual(stream.params["rtmp"], url)
        self.assertDictHas(params, stream.params)

    def test_plugin(self):
        self._test_rtmp("rtmp://hostname.se/stream",
                        "rtmp://hostname.se/stream", dict())

        self._test_rtmp("rtmp://hostname.se/stream live=1 num=47",
                        "rtmp://hostname.se/stream", dict(live=True, num=47))

        self._test_rtmp(
            "rtmp://hostname.se/stream live=1 qarg='a \'string' noq=test",
            "rtmp://hostname.se/stream",
            dict(live=True, qarg='a \'string', noq="test"))

        self._test_hls("hls://http://hostname.se/playlist.m3u8",
                       "http://hostname.se/playlist.m3u8")

        self._test_akamaihd("akamaihd://http://hostname.se/stream",
                            "http://hostname.se", "stream")
class TestSession(unittest.TestCase):
    PluginPath = os.path.join(os.path.dirname(__file__), "plugins")

    def setUp(self):
        self.session = Livestreamer()
        self.session.load_plugins(self.PluginPath)

    def test_exceptions(self):
        try:
            self.session.resolve_url("invalid url")
            self.assertTrue(False)
        except NoPluginError:
            self.assertTrue(True)

    def test_load_plugins(self):
        plugins = self.session.get_plugins()
        self.assertTrue(plugins["testplugin"])

    def test_builtin_plugins(self):
        plugins = self.session.get_plugins()
        self.assertTrue("justintv" in plugins)

    def test_resolve_url(self):
        plugins = self.session.get_plugins()
        channel = self.session.resolve_url("http://test.se/channel")
        self.assertTrue(isinstance(channel, Plugin))
        self.assertTrue(isinstance(channel, plugins["testplugin"]))

    def test_options(self):
        self.session.set_option("test_option", "option")
        self.assertEqual(self.session.get_option("test_option"), "option")
        self.assertEqual(self.session.get_option("non_existing"), None)

        self.assertEqual(
            self.session.get_plugin_option("testplugin", "a_option"),
            "default")
        self.session.set_plugin_option("testplugin", "another_option", "test")
        self.assertEqual(
            self.session.get_plugin_option("testplugin", "another_option"),
            "test")
        self.assertEqual(
            self.session.get_plugin_option("non_existing", "non_existing"),
            None)
        self.assertEqual(
            self.session.get_plugin_option("testplugin", "non_existing"), None)

    def test_plugin(self):
        channel = self.session.resolve_url("http://test.se/channel")
        streams = channel.get_streams()

        self.assertTrue("best" in streams)
        self.assertTrue(streams["best"] is streams["1080p"])
        self.assertTrue(isinstance(streams["rtmp"], RTMPStream))
        self.assertTrue(isinstance(streams["http"], HTTPStream))
        self.assertTrue(isinstance(streams["hls"], HLSStream))
        self.assertTrue(isinstance(streams["akamaihd"], AkamaiHDStream))
class TestPluginStream(unittest.TestCase):
    def setUp(self):
        self.session = Livestreamer()

    def assertDictHas(self, a, b):
        for key, value in a.items():
            self.assertEqual(b[key], value)

    def _test_akamaihd(self, surl, host, streamname):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, AkamaiHDStream))
        self.assertEqual(stream.host, host)
        self.assertEqual(stream.streamname, streamname)

    def _test_hls(self, surl, url):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, HLSStream))
        self.assertEqual(stream.url, url)

    def _test_rtmp(self, surl, url, params):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, RTMPStream))
        self.assertEqual(stream.params["rtmp"], url)
        self.assertDictHas(params, stream.params)

    def test_plugin(self):
        self._test_rtmp("rtmp://hostname.se/stream",
                         "rtmp://hostname.se/stream", dict())

        self._test_rtmp("rtmp://hostname.se/stream live=1 num=47",
                        "rtmp://hostname.se/stream", dict(live=True, num=47))

        self._test_rtmp("rtmp://hostname.se/stream live=1 qarg='a \'string' noq=test",
                        "rtmp://hostname.se/stream", dict(live=True, qarg='a \'string', noq="test"))

        self._test_hls("hls://http://hostname.se/playlist.m3u8",
                       "http://hostname.se/playlist.m3u8")

        self._test_akamaihd("akamaihd://http://hostname.se/stream",
                            "http://hostname.se", "stream")
class TestSession(unittest.TestCase):
    PluginPath = os.path.join(os.path.dirname(__file__), "plugins")

    def setUp(self):
        self.session = Livestreamer()
        self.session.load_plugins(self.PluginPath)

    def test_exceptions(self):
        try:
            self.session.resolve_url("invalid url")
            self.assertTrue(False)
        except NoPluginError:
            self.assertTrue(True)

    def test_load_plugins(self):
        plugins = self.session.get_plugins()
        self.assertTrue(plugins["testplugin"])

    def test_builtin_plugins(self):
        plugins = self.session.get_plugins()
        self.assertTrue("justintv" in plugins)

    def test_resolve_url(self):
        plugins = self.session.get_plugins()
        channel = self.session.resolve_url("http://test.se/channel")
        self.assertTrue(isinstance(channel, Plugin))
        self.assertTrue(isinstance(channel, plugins["testplugin"]))

    def test_options(self):
        self.session.set_option("test_option", "option")
        self.assertEqual(self.session.get_option("test_option"), "option")
        self.assertEqual(self.session.get_option("non_existing"), None)

        self.assertEqual(self.session.get_plugin_option("testplugin", "a_option"), "default")
        self.session.set_plugin_option("testplugin", "another_option", "test")
        self.assertEqual(self.session.get_plugin_option("testplugin", "another_option"), "test")
        self.assertEqual(self.session.get_plugin_option("non_existing", "non_existing"), None)
        self.assertEqual(self.session.get_plugin_option("testplugin", "non_existing"), None)

    def test_plugin(self):
        channel = self.session.resolve_url("http://test.se/channel")
        streams = channel.get_streams()

        self.assertTrue("best" in streams)
        self.assertTrue(streams["best"] is streams["1080p"])
        self.assertTrue(isinstance(streams["rtmp"], RTMPStream))
        self.assertTrue(isinstance(streams["http"], HTTPStream))
        self.assertTrue(isinstance(streams["hls"], HLSStream))
        self.assertTrue(isinstance(streams["akamaihd"], AkamaiHDStream))
Exemple #5
0
def GetYoutubeFullLink(url):
    from livestreamer import Livestreamer
    livestr = Livestreamer()
    channel = livestr.resolve_url(url)
    streams = channel.get_streams()
    stream = streams["best"]
    return stream.url
Exemple #6
0
def GetYoutubeFullLink(url):
	from livestreamer import Livestreamer
	livestr = Livestreamer()
	channel = livestr.resolve_url(url)
	streams = channel.get_streams()
	stream = streams["best"]
	return stream.url
Exemple #7
0
def face_detect(x, y, width, height, stream_url):
    x = x*426/651
    y = y*240/398
    width = width*426/651
    height = height*240/398
    cascade_fn = "haarcascade_frontalface_alt.xml"
    nested_fn = "haarcascade_eye.xml"

    cascade = cv2.CascadeClassifier(cascade_fn)
    nested = cv2.CascadeClassifier(nested_fn)

    FFMPEG_BIN = 'C:/ffmpeg/bin/ffmpeg.exe'

    livestreamer = Livestreamer()
    plugin = livestreamer.resolve_url(stream_url)
    streams = plugin.get_streams()
    stream = streams.get("best")
    VIDEO_URL = stream.url
    print VIDEO_URL
    pipe = sp.Popen([FFMPEG_BIN, "-i", VIDEO_URL,
                     "-loglevel", "quiet",  # no text output
                     "-an",  # disable audio
                     "-f", "image2pipe",
                     "-pix_fmt", "bgr24",
                     "-vcodec", "rawvideo", "-"],
                    stdin=sp.PIPE, stdout=sp.PIPE)
    interval = 0
    while True:
        raw_image = pipe.stdout.read(426 * 240 * 3)  # read 432*240*3 bytes (= 1 frame)
        img = np.fromstring(raw_image, dtype='uint8').reshape((240, 426, 3))
        img = img[y:(y + height), x:(x + width)]
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        gray = cv2.equalizeHist(gray)

        rects = detect(gray, cascade)
        vis = img.copy()
        if rects:
            interval += 1
        draw_rects(vis, rects, (0, 255, 0))
        for x1, y1, x2, y2 in rects:
            roi = gray[y1:y2, x1:x2]
            vis_roi = vis[y1:y2, x1:x2]
            subrects = detect(roi.copy(), nested)
            draw_rects(vis_roi, subrects, (255, 0, 0))

        cv2.imwrite('./media/face', vis)
        if cv2.waitKey(5) == 27:
            break
    cv2.destroyAllWindows()
    def serveFile(self, fURL, sendData):
        if (sendData):
            fURL, quality = player.GetStreamUrl(unquote(fURL))
            session = Livestreamer()
            if '|' in fURL:
                sp = fURL.split('|')
                fURL = sp[0]
                headers = dict(urlparse.parse_qsl(sp[1]))
                session.set_option("http-headers", headers)
                session.set_option("http-ssl-verify", False)
                session.set_option("hls-segment-threads", 3)
                session.set_option("stream-segment-threads", 3)
            try:
                #streams = session.streams(fURL)
                channel = session.resolve_url(fURL)
                streams = channel.get_streams()
            except Exception as ex:
                traceback.print_exc(file=sys.stdout)
                self.send_response(403)
            self.send_response(200)
            #print "XBMCLocalProxy: Sending headers..."
            self.end_headers()

            #print "XBMCLocalProxy: Sending data..."
            fileout = self.wfile
            try:
                stream = streams[quality]
                try:
                    response = stream.open()
                    buf = 'INIT'
                    while (buf != None and len(buf) > 0):
                        buf = response.read(200 * 1024)
                        fileout.write(buf)
                        fileout.flush()
                    response.close()
                    fileout.close()
                    #print time.asctime(), "Closing connection"
                except socket.error, e:
                    #print time.asctime(), "Client Closed the connection."
                    try:
                        response.close()
                        fileout.close()
                    except Exception, e:
                        return
                except Exception, e:
                    traceback.print_exc(file=sys.stdout)
                    response.close()
                    fileout.close()
    def serveFile(self, fURL, sendData):
        if (sendData):
            fURL, quality = player.GetStreamUrl(unquote(fURL))
            session = Livestreamer()
            if '|' in fURL:
                    sp = fURL.split('|')
                    fURL = sp[0]
                    headers = dict(urlparse.parse_qsl(sp[1]))
                    session.set_option("http-headers", headers)
                    session.set_option("http-ssl-verify",False)
                    session.set_option("hls-segment-threads",3)
                    session.set_option("stream-segment-threads",3)
            try:
                #streams = session.streams(fURL)
                channel = session.resolve_url(fURL)
                streams = channel.get_streams()
            except Exception as ex:
                traceback.print_exc(file=sys.stdout)
                self.send_response(403)
            self.send_response(200)
            #print "XBMCLocalProxy: Sending headers..."
            self.end_headers()

            #print "XBMCLocalProxy: Sending data..."
            fileout = self.wfile
            try:
                stream = streams[quality]
                try:
                    response = stream.open()
                    buf = 'INIT'
                    while (buf != None and len(buf) > 0):
                        buf = response.read(200 * 1024)
                        fileout.write(buf)
                        fileout.flush()
                    response.close()
                    fileout.close()
                    #print time.asctime(), "Closing connection"
                except socket.error, e:
                    #print time.asctime(), "Client Closed the connection."
                    try:
                        response.close()
                        fileout.close()
                    except Exception, e:
                        return
                except Exception, e:
                    traceback.print_exc(file=sys.stdout)
                    response.close()
                    fileout.close()
Exemple #10
0
    def get_streams(self):
        live = Livestreamer()
        print self.url
        live.set_option("http-ssl-verify", False)

        streams = None

        live.load_plugins(os.path.join(os.getcwd(), "plugins"))
        try:
            plugin = live.resolve_url(self.url)
            streams = plugin.get_streams()

            self.play_url = stream_to_url(streams.get("best"))
        except NoPluginError:
            print("No plugin can handle URL")
        except PluginError as err:
            print("{0}", err)
Exemple #11
0
    def get_streams(self):
        live = Livestreamer()
        print self.url
        live.set_option("http-ssl-verify", False)


        streams = None

        live.load_plugins(os.path.join(os.getcwd(), "plugins"))
        try:
            plugin = live.resolve_url(self.url)
            streams = plugin.get_streams()

            self.play_url = stream_to_url(streams.get("best"))
        except NoPluginError:
            print("No plugin can handle URL")
        except PluginError as err:
            print("{0}", err)
def get_stream(stream_url):
    # change to a stream that is actually online
    livestreamer = Livestreamer()
    stream = None
    try:
        plugin = livestreamer.resolve_url("http://www.twitch.tv/" + stream_url)
        plugin.set_option('oauth_token', 'xtlhyl6uapy6znsvuhy4zfk0jbt086')
        streams = plugin.get_streams()
        # It seems best isn't necessarily the best, twitch doesn't seem to consider 60
        # streams, so we should search for those first.
        if '1080p60' in streams:
            stream = streams['1080p60']
        elif '720p60' in streams:
            stream = streams['720p60']
        else:
            stream = streams['best']
    except Exception:
        pass
    return stream
def main():
    if len(sys.argv) < 3:
        exit("Usage: {0} <url> <quality>".format(sys.argv[0]))

    # Collect arguments
    url = sys.argv[1]
    quality = sys.argv[2]

    # Create the Livestreamer session
    livestreamer = Livestreamer()

    # Enable logging
    livestreamer.set_loglevel("info")
    livestreamer.set_logoutput(sys.stdout)

    # Attempt to find a plugin for this URL
    try:
        plugin = livestreamer.resolve_url(url)
    except NoPluginError:
        exit("Livestreamer is unable to handle the URL '{0}'".format(url))

    # Attempt to fetch streams
    try:
        streams = plugin.get_streams()
    except PluginError as err:
        exit("Plugin error: {0}".format(err))

    if len(streams) == 0:
        exit("No streams found on URL '{0}'".format(url))

    # Look for specified stream
    if quality not in streams:
        exit("Unable to find '{0}' stream on URL '{1}'".format(quality, url))

    # We found the stream
    stream = streams[quality]

    # Create the player and start playback
    player = LivestreamerPlayer()

    # Blocks until playback is done
    player.play(stream)
Exemple #14
0
def main():
    if len(sys.argv) < 3:
        exit("Usage: {0} <url> <quality>".format(sys.argv[0]))

    # Collect arguments
    url = sys.argv[1]
    quality = sys.argv[2]

    # Create the Livestreamer session
    livestreamer = Livestreamer()

    # Enable logging
    livestreamer.set_loglevel("info")
    livestreamer.set_logoutput(sys.stdout)

    # Attempt to find a plugin for this URL
    try:
        plugin = livestreamer.resolve_url(url)
    except NoPluginError:
        exit("Livestreamer is unable to handle the URL '{0}'".format(url))

    # Attempt to fetch streams
    try:
        streams = plugin.get_streams()
    except PluginError as err:
        exit("Plugin error: {0}".format(err))

    if len(streams) == 0:
        exit("No streams found on URL '{0}'".format(url))

    # Look for specified stream
    if quality not in streams:
        exit("Unable to find '{0}' stream on URL '{1}'".format(quality, url))

    # We found the stream
    stream = streams[quality]

    # Create the player and start playback
    player = LivestreamerPlayer()

    # Blocks until playback is done
    player.play(stream)
Exemple #15
0
class GreekStreamTVList(Screen):
    skin = '\n \t\t<screen name="GreekStreamTVList" position="center,center" size="800,400" title="GreekStreamTV List (Livestreamer) v3.2">\n\t\t\t<widget name="streamlist" position="0,0" size="800,360" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />\n\t\t\t<widget name="info" position="0,365" zPosition="2" size="800,35" font="Regular;22" foregroundColor="#ffffff" transparent="1" halign="center" valign="center" />\n\t\t</screen>\n           '

    def __init__(self, session, streamFile=None):
        self.session = session
        Screen.__init__(self, session)
        self['info'] = Label('...')
        self['actions'] = ActionMap(
            [
                'OkCancelActions', 'ShortcutActions', 'WizardActions',
                'ColorActions', 'SetupActions', 'NumberActions', 'MenuActions'
            ], {
                'ok': self.keyOK,
                'cancel': self.keyCancel,
                'up': self.keyUp,
                'down': self.keyDown,
                'left': self.keyLeft,
                'right': self.keyRight
            }, -1)
        self.streamBin = '/usr/bin/rtmpdump'
        self.streamPipe = '/tmp/greekstreamtv.avi'
        if not streamFile:
            self.streamFile = resolveFilename(
                SCOPE_PLUGINS, 'Extensions/GreekStreamTV/stream.xml')
        else:
            self.streamFile = streamFile
        self.lvstreamer = Livestreamer()
        self.streamList = []
        self.makeStreamList()
        self.streamMenuList = MenuList([],
                                       enableWrapAround=True,
                                       content=eListboxPythonMultiContent)
        self.streamMenuList.l.setFont(0, gFont('Regular', 22))
        self.streamMenuList.l.setFont(1, gFont('Regular', 18))
        self.streamMenuList.l.setItemHeight(37)
        self['streamlist'] = self.streamMenuList
        self.streamMenuList.setList(map(streamListEntry, self.streamList))
        self.onLayoutFinish.append(self.layoutFinished)
        self.beforeService = None
        self.currentService = None
        self.playerStoped = False
        self.keyLocked = False
        self.pd = None
        self.qsel = None
        return

    def layoutFinished(self):
        os.system('killall -9 rtmpdump')
        self.showName()

    def keyLeft(self):
        if self.keyLocked:
            return
        self['streamlist'].pageUp()
        self.showName()

    def keyRight(self):
        if self.keyLocked:
            return
        self['streamlist'].pageDown()
        self.showName()

    def keyUp(self):
        if self.keyLocked:
            return
        self['streamlist'].up()
        self.showName()

    def keyDown(self):
        if self.keyLocked:
            return
        self['streamlist'].down()
        self.showName()

    def keyCancel(self):
        self.LivestreamerStop()
        if '/usr/lib/enigma2/python/Plugins/Extensions/GreekStreamTV' in path:
            path.remove(
                '/usr/lib/enigma2/python/Plugins/Extensions/GreekStreamTV')
        self.close()

    def showName(self):
        try:
            tmpName = self['streamlist'].getCurrent()[0][1].get('name')
        except:
            tmpName = '...'

        self['info'].setText(tmpName)

    def keyOK(self):
        print '[GreekStreamTVList::keyOK]'
        if self.keyLocked:
            return
        uriName = self['streamlist'].getCurrent()[0][1].get('name')
        self['info'].setText('Starting %s Please Wait...' % uriName)
        self.timer = eTimer()
        self.timer.callback.append(self.StartStream)
        self.timer.start(100, 1)

    def StartStream(self):
        self.timer.stop()
        self.keyLocked = True
        self.beforeService = None
        self.currentService = None
        self.playerStoped = False
        self.pd = None
        streamInfo = self['streamlist'].getCurrent()[0][1]
        uriInfo = streamInfo.get('uri')
        typeInfo = streamInfo.get('type').split(':')
        protocol = typeInfo[0]
        serviceType = typeInfo[1]
        bufferSize = typeInfo[2]
        url = uriInfo.get('URL')
        if protocol == 'rtmp':
            url += ' '
            url += ' '.join([
                '%s=%s' % (key, value) for key, value in uriInfo.items()
                if key != 'URL'
            ])
            url = ' '.join(url.split())
            print '[GreekStreamTVList::keyOK] URL is ', url, ' URI is ', uriInfo
            self.doStreamAction(url, serviceType, bufferSize)
        elif protocol in ('rtsp', 'http'):
            self.doStreamAction(url, serviceType, bufferSize)
        elif protocol == 'livestreamer':
            channel = None
            streams = None
            try:
                url += ' '
                url += ' '.join([
                    '%s=%s' % (key, value) for key, value in uriInfo.items()
                    if key != 'URL'
                ])
                url = ' '.join(url.split())
                print '[GreekStreamTVList::keyOK] URL is ', url, ' URI is ', uriInfo
                channel = self.lvstreamer.resolve_url(url)
                streams = channel.get_streams()
                print '[GreekStreamTVList::keyOK] Streams: ', streams.keys()
                print '[GreekStreamTVList::keyOK] Streams: ', streams.items()
                if len(streams
                       ) == 3 and 'best' in streams and 'worst' in streams:
                    self.streamPreBuffer(streams['best'])
                elif len(streams) == 0:
                    raise Exception('No Streams Found')
                else:
                    self.qsel = self.session.openWithCallback(
                        self.QualitySelClosed, SelectQuality, streams,
                        self.streamPreBuffer)
            except Exception as err:
                print '[GreekStreamTVList::keyOK::Exception] Error: ', err
                tmpMessage = 'An Error Occured: ' + str(err)[:200] + '...'
                self.session.openWithCallback(self.stopPlayer,
                                              MessageBox,
                                              tmpMessage,
                                              type=MessageBox.TYPE_ERROR,
                                              timeout=20)

        else:
            print '[GreekStreamTVList::keyOK] Unknown Protocol: ', protocol
            tmpMessage = 'Unknown Protocol: ' + protocol
            self.session.openWithCallback(self.stopPlayer,
                                          MessageBox,
                                          tmpMessage,
                                          type=MessageBox.TYPE_WARNING,
                                          timeout=20)
        return

    def QualitySelClosed(self, recursive):
        if self.qsel:
            self.qsel.close()
        self.qsel = None
        self.stopPlayer()
        return

    def streamPreBuffer(self, stream):
        fd = None
        try:
            fd = stream.open()
            prebuffer = fd.read(1049088)
            if len(prebuffer) == 0:
                raise Exception('No Data Received From Stream Server')
            start_new_thread(self.streamCopy, (fd, prebuffer))
            sleep(1.5)
            self.doStreamAction(self.streamPipe)
        except Exception as err:
            if fd and hasattr(fd, 'close'):
                fd.close()
            print '[GreekStreamTVList::streamPreBuffer::Exception] Error: ', err
            tmpMessage = 'An Error Occured while buffering: ' + str(
                err)[:200] + '...'
            self.session.openWithCallback(self.stopPlayer,
                                          MessageBox,
                                          tmpMessage,
                                          type=MessageBox.TYPE_ERROR,
                                          timeout=20)

        return

    def streamCopy(self, fd, prebuffer):
        print '[GreekStreamTVList::streamCopy]'
        if os.access(self.streamPipe, os.F_OK):
            os.remove(self.streamPipe)
        os.mkfifo(self.streamPipe)
        self.pd = open(self.streamPipe, 'wb')
        try:
            self.pd.write(prebuffer)
            while self is not None and self.session is not None and not self.playerStoped:
                data = fd.read(8192)
                if len(data) == 0:
                    break
                self.pd.write(data)

            print '[GreekStreamTVList:streamCopy] playerStoped'
            self.pd.close()
            if hasattr(fd, 'close'):
                fd.close()
            fd = None
        except Exception as err:
            print '[GreekStreamTVList::streamCopy] Exception: ', err
        finally:
            self.playerStoped = True
            if fd and hasattr(fd, 'close'):
                fd.close()

        return

    def LivestreamerStop(self):
        print '[GreekStreamTVList::LivestreamStop]'
        self['info'].setText('...')
        self.keyLocked = False
        self.playerStoped = True
        os.system('killall -9 rtmpdump')
        sleep(0.5)
        if self.pd:
            try:
                self.pd.close()
            except:
                sleep(0.5)
                try:
                    self.pd.close()
                except:
                    pass

        if self.qsel is not None:
            self.qsel.close(False)
        self.pd = None
        self.qsel = None
        return

    def doStreamAction(self, url=None, serviceType=4097, bufferSize=None):
        if url is None:
            url = self.streamPipe
            self.streamPlayerTimer.stop()
        try:
            serviceType = int(serviceType)
        except:
            serviceType = 4097

        try:
            bufferSize = int(bufferSize)
        except:
            bufferSize = None

        service = eServiceReference(serviceType, 0, url)
        streamInfo = self['streamlist'].getCurrent()[0][1]
        service.setName(str(streamInfo.get('name')))
        uriInfo = streamInfo.get('uri')
        self.beforeService = self.session.nav.getCurrentlyPlayingServiceReference(
        )
        self.currentService = self.session.openWithCallback(
            self.onStreamFinished,
            GreekStreamTVPlayer,
            service,
            stopPlayer=self.stopPlayer,
            chName=str(streamInfo.get('name')),
            chURL=str(uriInfo.get('URL')),
            chIcon=str(streamInfo.get('icon')))
        return

    def stopPlayer(self, params=None):
        print '[GreekStreamTV::stopPlayer]'
        if params is None or isinstance(params, bool):
            self.playerStoped = True
            self.LivestreamerStop()
            return
        else:
            return

    def onStreamFinished(self):
        print '[GreekStreamTV::onStreamFinished]'
        self.LivestreamerStop()
        self.session.nav.playService(self.beforeService)
        print '[GreekStreamTV::onStreamFinished] player done!!'

    def makeStreamList(self):
        try:
            streamDB = StreamURIParser(self.streamFile).parseStreamList()
        except Exception as err:
            print '[GreekStreamTV::makeStreamList] Error: ', err
            streamDB = []

        self.streamList = [(x.get('name'), x) for x in streamDB]
class Main:
    def __init__(self):    
        self.gchoice = -1
        self.cchoice = -1    
        self.exit_now = False
        self.state = 'none'
        self.keybingings = {
            ord('q'):       self.quit,
            ord('f'):       self.get_favorites,
            ord('s'):       self.get_fav_games,
            ord('g'):       self.get_games,
            ord('n'):       self.get_next,
            ord('r'):       self.refresh,
            ord('p'):       self.get_previous            
        }
        
        self.games = []
        self.favs = []
        self.channels = []        
        self.twitch = Twitch(config.get('settings', 'twitchapiurl'), config.get('settings', 'channel'), config.get('settings', 'game'))
        self.livestreamer = Livestreamer()
        
        try:
            self.run()
        except Exception as e:
            print e.message
        
    def run(self):
        
        while True:            
            self.display_message()                                            
            if self.exit_now:
                return
    
    def quit(self, c):
        self.exit_now = True
        
    def display_message(self):
                               
        if self.state == 'none':
            clear_screen()                      
            self.handle_user_input('Escoge una opcion : Favoritos(F), Juegos(G), Salir(Q)')            
        
        if self.state == 'favs':
            clear_screen()            
            print 'Mostrando transmisiones favoritas en linea :'
            print '-' * 40
            if(len(self.favs) > 0):                            
                self.show_content(self.favs)            
                self.handle_user_input('Escoge un canal por numero (r para refrescar, g para enlistar juegos y q para salir', range(len(self.favs) + 1))
                clear_screen()
            else:
                self.handle_user_input('No hay canales favoritos en linea (r para refrescar, g para enlistar juegos y q para salir', range(len(self.favs) + 1))
                clear_screen()            
                
        if self.state == 'games':
            clear_screen()            
            print 'Mostrando %d juegos destacados:' % config.getint('settings', 'game')
            print '-' * 40
            if(len(self.games) > 0):                            
                self.show_content(self.games)            
                self.gchoice = self.handle_user_input('Escoge un juego por numero (r para refrescar, f para revisar tus canales favoritos y q para salir', range(len(self.games) + 1))
                if self.gchoice != -1:
                    self.state = 'channels'
                    clear_screen()                                                 
                    
        if self.state == 'favgames':
            clear_screen()            
            print 'Mostrando juegos favoritos:'
            print '-' * 40
            if(len(self.games) > 0):                        
                self.show_content(self.games)            
                self.gchoice = self.handle_user_input('Escoge un juego por numero (r para refrescar, f para revisar tus canales favoritos y q para salir', range(len(self.games) + 1))
                if self.gchoice != -1:
                    self.state = 'channels'
                    clear_screen()
        
        if self.state == 'channels':
            clear_screen()            
            print 'Mostrando %d canales destacados para %s:' % (config.getint('settings', 'channel'), self.games[self.gchoice - 1])
            print '-' * 40            
            self.get_channels(self.gchoice)
            if(len(self.channels) > 0):                            
                self.show_content(self.channels)            
                self.cchoice = self.handle_user_input('Escoge un canal por numero (r para refrescar, f para revisar tus canales favoritos, g para enlistar juegos y q para salir', range(len(self.channels) + 1))
                if self.cchoice != -1:
                    self.play_stream(self.channels[self.cchoice - 1])
                    self.state = 'channels'
                    clear_screen()
       
    def play_stream(self, channel):
        clear_screen()
        
        try:
            plugin = self.livestreamer.resolve_url(("twitch.tv/{0}").format(channel))
        except Exception as e:
            print e.message                   
        
        try:
            streams = plugin.get_streams()
        except PluginError as err:
            exit("Plugin error: {0}".format(err))
        
        player = config.get('settings', 'player')
        quality = config.get('settings', 'quality')
        if quality not in streams:
            quality = "best"
            print "No se puede abrirla transmision con la calidad solicitada ({0}), abriendo la de mejor calidad".format(config.get('settings', 'quality'))
                        
        channel = transform_spaces(channel)
        if os.name == 'nt':
            #os.system('livestreamer twitch.tv/%s %s' % (channel, quality))
            os.system('livestreamer -p "%s" twitch.tv/%s %s' % (player, channel, quality))
        else:
            #os.system('livestreamer twitch.tv/%s %s' % (channel, quality))
            os.system('livestreamer -np "%s" twitch.tv/%s %s' % (player, channel, quality))
            
    def show_content(self, content):
        for i in range(len(content)):
            if i < 9:
                print '',
            if i < 99:
                print '',
            print '%d %s' % (i + 1, content[i])
            
    def handle_user_input(self, message, valid = None):
        self.state = 'none'
        validinput = False
        while not validinput:
            input = raw_input('%s\n ' % message)
            input = input.strip().lower()
            
            if input.isdigit():
                input = int(input)
                if input in valid:
                    validinput = True                    
                    return input
            elif len(input) == 1:
                c = ord(input)                
                f = self.keybingings.get(c, None)
                if f:
                    f(c)
                    validinput = True                    
                    return -1
            
        
    def get_favorites(self, c):
        self.state = 'favs'
        del self.favs[:]
        try:
            response = self.twitch.get_favorites_streams_status(config.get('settings', 'favorites'))
            receivedcount = len(response['streams'])
            
            for i in range(receivedcount):
                self.favs.append('%s Reproduciendo: %s' % (response['streams'][i]['channel']['name'], response['streams'][i]['game']))
                
        except Exception as e:
            print 'Error obteniendo transmisiones favoritas!\n'
            print e.message
            return 0
        
    def get_games(self, c):        
        self.state = 'games'
        del self.games[:]
        try:
            response = self.twitch.get_game_list()
            receivedcount = len(response['top'])
            
            for i in range(receivedcount):
                self.games.append(response['top'][i]['game']['name'])
                
        except Exception as e:
            print 'Error obteniendo juegos !\n'
            print e.message
            return 0
        
    def get_fav_games(self, c):
        self.state = 'favgames'
        del self.games[:]
        
        favgames = config.get('settings', 'favgames')
        if len(favgames) > 0:
            self.games.extend(favgames.split(', '))                        
        
    def get_channels(self, choice):
        self.state = 'channels'
        del self.channels[:]
        try:
            response = self.twitch.get_channel_for_game(transform_spaces(self.games[self.gchoice - 1]))
            receivedcount = len(response['streams'])
            
            for i in range(receivedcount):
                self.channels.append('%s (%s)' % (response['streams'][i]['channel']['name'], response['streams'][i]['viewers']))
                
        except Exception as e:
            print 'Error obteniendo canales !\n'
            print e.message
            return 0        
        
    def refresh(self, c):
        print 'tmp'
        
    def get_next(self, c):
        print 'tmp'
        
    def get_previous(self, c):
        print 'tmp'
class StreamAnalysis( Thread ):

  def __init__( self, timeList, eventList, worldmap ):
    Thread.__init__( self )
    self._timeList = timeList
    self._eventList = eventList

    self._timeZero = 1392254560

    # set up templates as private variables for this class
    self._templatesTime = pickle.load( open('timeValues.data', 'rb') )
    self._templatesRed = pickle.load( open('redTemplates.data', 'rb') )
    self._templatesEvent = pickle.load( open('eventTemplates.data', 'rb') )

    self._worldmap = cv2.cvtColor(worldmap.copy(), cv2.COLOR_BGR2GRAY)


  def initStream( self ):
    self._livestreamer = Livestreamer()
    self._plugin = self._livestreamer.resolve_url('http://twitch.tv/twitchplayspokemon')

  def fetchStream( self ):
    streams = self._plugin.get_streams()
    if 'source' in streams:
      return streams.get('source')

    return False

  def run( self ):
    
    self.initStream()
    
    stream = self.fetchStream()
    while stream == False:
      print 'STREAM'
      time.sleep(60)
      print 'rechecking if stream is available'
      stream = self.fetchStream()

    #cap = cv2.VideoCapture( 'http://store22.media22.justin.tv/archives/2014-2-17/live_user_twitchplayspokemon_1392633446.flv' )
    cap = cv2.VideoCapture( stream.url )

    tmpTimeValues = []
    last_position = (-1, -1)

    while True:

      if not overridePosition == (-1, -1) and last_position == (-1, -1):
        last_position = overridePosition

      flag, frame = cap.read()
      
      if not flag:
        stream = self.fetchStream()
        cap = cv2.VideoCapture( stream.url )
        flag, frame = cap.read()

        if not flag:
          break

      gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
      timeValues = self.getTimeValues( gray[81:119, 526:830] )

      if timeValues == tmpTimeValues:
        continue

      tmpTimeValues = timeValues
      date = self.getDateFromTime( timeValues )
      if not 'day' in date or not 'hour' in date or not 'minute' in date or not 'second' in date:
        print 'error parsing date'
        continue

      timeStamp = self._timeZero + int(date['day']) * 24 * 60 * 60 + int(date['hour']) * 60 * 60 + int(date['minute']) * 60 + int(date['second'])

      # crop to gameboy area
      crop = gray[24:457, 24:504]

      # find red (if not found with enough confidence it's "undefined")
      currentDirection = self.getRedDirection( crop[182:230, 194:233] )
      if currentDirection == 'undefined':
        #self.newEntry(timeStamp, date, last_position)
        continue

      # check if there is currently an event open
      events = self.detectEvents( crop )
      if len(events) > 0 and not last_position == (-1, -1):
        #self.newEntry(timeStamp, date, last_position)
        self._eventList.append(events[0])
        continue

      # detect position on map

      # scale to world-map ratio
      # 480px -> 160px
      crop = cv2.resize(crop, (160, 144))

      # crop the worldmap image to a reasonable size, so we do not have to search so excessively
      # we can only do this if we have a starting position
      validationImage = self._worldmap
      left_corner = (0, 0)
      
      #cv2.imshow('crop', crop)
      #cv2.imshow('img', validationImage)
      #cv2.waitKey(0)

      if not last_position == (-1, -1):
        size = (500, 500)
        left_corner = (last_position[0] - size[0] / 2, last_position[1] - size[1] / 2)
        validationImage = self._worldmap[left_corner[1]:left_corner[1] + size[1], left_corner[0]:left_corner[0] + size[0]]

        #cv2.imshow('crop', crop)
        #cv2.imshow('img', validationImage)
        #cv2.waitKey(0)


      # this should generally not happen, but if it does, we do not know where we are
      # so we're defaulting to the whole worldmap
      # TODO: THIS SHOULD BE REPLACED WITH -> DEFAULTING TO INDOOR MAPS!
      if validationImage.shape < crop.shape:
        validationImage = self._worldmap
        left_corner = (0, 0)

      res = cv2.matchTemplate(validationImage, crop, cv2.TM_CCOEFF_NORMED)
      w, h = crop.shape[::-1]
      min_val, max_val, min_loc, max_loc = cv2.minMaxLoc( res )

      # if we don't find something we're confident in, use the last position
      #if max_val < 0.5 and not last_position == (-1, -1):
      #  self.newEntry(timeStamp, date, last_position)
      #  continue

      # retry until we find a good first match
      if max_val < 0.8:
        validationImage = self._worldmap
        left_corner = (0, 0)

        res = cv2.matchTemplate(validationImage, crop, cv2.TM_CCOEFF_NORMED)
        w, h = crop.shape[::-1]
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc( res )
        
        print max_val
        if max_val < 0.7:
          print 'hit low'
          continue

      top_left = max_loc
      top_left = (top_left[0] + left_corner[0], top_left[1] + left_corner[1])

      center = (top_left[0] + w / 2, top_left[1] + h / 2)
      bottom_right = (top_left[0] + w, top_left[1] + h)

      last_position = center
      self.newEntry(timeStamp, date, last_position)
      
      if len(self._timeList) > 20:
        self._timeList = []

  def getTimeValues( self, timeCrop ):
    timeValues = []

    for key in self._templatesTime:
      template = self._templatesTime[key]
      w, h = template.shape[::-1]

      res = cv2.matchTemplate(timeCrop, template, cv2.TM_CCOEFF_NORMED)
      threshold = 0.9

      loc = numpy.where( res >= threshold )
      for pt in zip(*loc[::-1]):
        timeValues.append((pt[0], pt[1], key))

    timeValues.sort()
    return timeValues

  def getDateFromTime( self, timeValues ):
    date = {}
    tmp = ''

    for timeValue in timeValues:
      key = timeValue[2]

      if key == 'd':
        date['day'] = tmp.zfill(2)
        tmp = ''

      elif key == 'h':
        date['hour'] = tmp.zfill(2)
        tmp = ''

      elif key == 'm':
        date['minute'] = tmp.zfill(2)
        tmp = ''

      elif key == 's':
        date['second'] = tmp.zfill(2)
        tmp = ''

      else:
        tmp = '{}{}'.format(tmp, key)

    return date

  def getRedDirection( self, redCrop ):
    currentDirection = 'undefined'
    redCrop = cv2.resize(redCrop, (10, 10))
    
    for direction in self._templatesRed:
      template = self._templatesRed[direction]
      template = cv2.resize(template, (10, 10))

      res = cv2.matchTemplate(redCrop, template, cv2.TM_CCOEFF_NORMED)
      min_val, max_val, min_loc, max_loc = cv2.minMaxLoc( res )

      if max_val > 0.55:
        currentDirection = direction
        break

    return currentDirection

  def detectEvents( self, crop ):
    eventValues = []

    detectionAreas = {}
    detectionAreas['moonstone'] = crop.copy() # moonstone
    detectionAreas['dialogue'] = crop[293:435, 0:480] # dialogue
    detectionAreas['optionsMenu'] = crop[3:388, 240:480] # optionsMenu
    detectionAreas['naming'] = crop[98:360, 0:480] # naming

    for key in self._templatesEvent:
      template = self._templatesEvent[key]
      area = detectionAreas[key]

      w, h = template.shape[::-1]
      if area.shape < template.shape:
        break

      res = cv2.matchTemplate(area, template, cv2.TM_CCOEFF_NORMED)
      threshold = 0.95

      loc = numpy.where( res >= threshold )
      for pt in zip(*loc[::-1]):
        _tuple = (pt[0], pt[1], key)
        if not _tuple in eventValues:
          eventValues.append(_tuple)

      # currently there can only be one event at any given timespace
      if len(eventValues) > 0:
        break

    return eventValues

  def newEntry( self, timeStamp, date, position ):
    _tuple = (timeStamp, date, position)

    # we are in a room without outsideworld reference
    # this could only happen, if we start recording inside a building right now
    if position == (-1, -1):
      print 'WHERE ARE WE?\r'
      return

    if not _tuple in self._timeList:
      self._timeList.append(_tuple)
      print '{}\t{},{}\r'.format(str(timeStamp), position[0], position[1]),

      with open('positionData.csv', 'a') as entryFile:
        line = '{};{};{};{};{};{};{}\n'.format(timeStamp, \
                                      date['day'], date['hour'], date['minute'], date['second'], \
                                      position[0], position[1])
        entryFile.write(line)

      with open( 'www/currentPosition', 'w' ) as _file:
        _file.write('{} {}'.format(position[0], position[1]))

      with open( 'www/currentTime', 'w' ) as _file:
        _file.write('{} {} {} {}'.format(date['day'], date['hour'], date['minute'], date['second']))
Exemple #18
0
Test Livestreamer Script for enigma2

Test commands:
cd /usr/lib/enigma2/python/Plugins/Extensions/GreekStreamTV
python testme.py

"""
import sys
sys.path.append('/usr/lib/enigma2/python/Plugins/Extensions/GreekStreamTV')
import os
import requests
from livestreamer import Livestreamer
url = 'http://www.dailymotion.com/video/xqjey2'
livestreamer = Livestreamer()
livestreamer.set_loglevel('debug')
channel = livestreamer.resolve_url(url)
streams = channel.get_streams()
print 'Streams:', streams.keys()
stream = streams['best']
print stream
fd = stream.open()
while True:
    data = fd.read(1024)
    if len(data) == 0:
        break
    else:
        print 'Got Data! Livestreamer Works!'
        break

if hasattr(fd, 'close'):
    fd.close()
class TestPluginStream(unittest.TestCase):
    def setUp(self):
        self.session = Livestreamer()

    def assertDictHas(self, a, b):
        for key, value in a.items():
            self.assertEqual(b[key], value)

    def _test_akamaihd(self, surl, url):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, AkamaiHDStream))
        self.assertEqual(stream.url, url)

    def _test_hls(self, surl, url):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, HLSStream))
        self.assertEqual(stream.url, url)

    def _test_rtmp(self, surl, url, params):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, RTMPStream))
        self.assertEqual(stream.params["rtmp"], url)
        self.assertDictHas(params, stream.params)

    def _test_http(self, surl, url, params):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, HTTPStream))
        self.assertEqual(stream.url, url)
        self.assertDictHas(params, stream.args)

    def test_plugin(self):
        self._test_rtmp("rtmp://hostname.se/stream",
                        "rtmp://hostname.se/stream", dict())

        self._test_rtmp("rtmp://hostname.se/stream live=1 num=47",
                        "rtmp://hostname.se/stream", dict(live=True, num=47))

        self._test_rtmp(
            "rtmp://hostname.se/stream live=1 qarg='a \\'string' noq=test",
            "rtmp://hostname.se/stream",
            dict(live=True, qarg='a \'string', noq="test"))

        self._test_hls("hls://https://hostname.se/playlist.m3u8",
                       "https://hostname.se/playlist.m3u8")

        self._test_hls("hls://hostname.se/playlist.m3u8",
                       "http://hostname.se/playlist.m3u8")

        self._test_akamaihd("akamaihd://http://hostname.se/stream",
                            "http://hostname.se/stream")

        self._test_akamaihd("akamaihd://hostname.se/stream",
                            "http://hostname.se/stream")

        self._test_http(
            "httpstream://http://hostname.se/auth.php auth=('test','test2')",
            "http://hostname.se/auth.php", dict(auth=("test", "test2")))

        self._test_http(
            "httpstream://hostname.se/auth.php auth=('test','test2')",
            "http://hostname.se/auth.php", dict(auth=("test", "test2")))

        self._test_http(
            "httpstream://https://hostname.se/auth.php verify=False params={'key': 'a value'}",
            "https://hostname.se/auth.php?key=a+value",
            dict(verify=False, params=dict(key='a value')))
Exemple #20
0
class Main:
    def __init__(self):
        self.gchoice = -1
        self.cchoice = -1
        self.exit_now = False
        self.state = 'none'
        self.keybingings = {
            ord('q'): self.quit,
            ord('f'): self.get_favorites,
            ord('s'): self.get_fav_games,
            ord('g'): self.get_games,
            ord('n'): self.get_next,
            ord('r'): self.refresh,
            ord('p'): self.get_previous
        }

        self.games = []
        self.favs = []
        self.channels = []
        self.twitch = Twitch(config.get('settings', 'twitchapiurl'),
                             config.get('settings', 'channel'),
                             config.get('settings', 'game'))
        self.livestreamer = Livestreamer()

        try:
            self.run()
        except Exception as e:
            print e.message

    def run(self):

        while True:
            self.display_message()
            if self.exit_now:
                return

    def quit(self, c):
        self.exit_now = True

    def display_message(self):

        if self.state == 'none':
            clear_screen()
            self.handle_user_input(
                'Escoge una opcion : Favoritos(F), Juegos(G), Salir(Q)')

        if self.state == 'favs':
            clear_screen()
            print 'Mostrando transmisiones favoritas en linea :'
            print '-' * 40
            if (len(self.favs) > 0):
                self.show_content(self.favs)
                self.handle_user_input(
                    'Escoge un canal por numero (r para refrescar, g para enlistar juegos y q para salir',
                    range(len(self.favs) + 1))
                clear_screen()
            else:
                self.handle_user_input(
                    'No hay canales favoritos en linea (r para refrescar, g para enlistar juegos y q para salir',
                    range(len(self.favs) + 1))
                clear_screen()

        if self.state == 'games':
            clear_screen()
            print 'Mostrando %d juegos destacados:' % config.getint(
                'settings', 'game')
            print '-' * 40
            if (len(self.games) > 0):
                self.show_content(self.games)
                self.gchoice = self.handle_user_input(
                    'Escoge un juego por numero (r para refrescar, f para revisar tus canales favoritos y q para salir',
                    range(len(self.games) + 1))
                if self.gchoice != -1:
                    self.state = 'channels'
                    clear_screen()

        if self.state == 'favgames':
            clear_screen()
            print 'Mostrando juegos favoritos:'
            print '-' * 40
            if (len(self.games) > 0):
                self.show_content(self.games)
                self.gchoice = self.handle_user_input(
                    'Escoge un juego por numero (r para refrescar, f para revisar tus canales favoritos y q para salir',
                    range(len(self.games) + 1))
                if self.gchoice != -1:
                    self.state = 'channels'
                    clear_screen()

        if self.state == 'channels':
            clear_screen()
            print 'Mostrando %d canales destacados para %s:' % (config.getint(
                'settings', 'channel'), self.games[self.gchoice - 1])
            print '-' * 40
            self.get_channels(self.gchoice)
            if (len(self.channels) > 0):
                self.show_content(self.channels)
                self.cchoice = self.handle_user_input(
                    'Escoge un canal por numero (r para refrescar, f para revisar tus canales favoritos, g para enlistar juegos y q para salir',
                    range(len(self.channels) + 1))
                if self.cchoice != -1:
                    self.play_stream(self.channels[self.cchoice - 1])
                    self.state = 'channels'
                    clear_screen()

    def play_stream(self, channel):
        clear_screen()

        try:
            plugin = self.livestreamer.resolve_url(
                ("twitch.tv/{0}").format(channel))
        except Exception as e:
            print e.message

        try:
            streams = plugin.get_streams()
        except PluginError as err:
            exit("Plugin error: {0}".format(err))

        player = config.get('settings', 'player')
        quality = config.get('settings', 'quality')
        if quality not in streams:
            quality = "best"
            print "No se puede abrirla transmision con la calidad solicitada ({0}), abriendo la de mejor calidad".format(
                config.get('settings', 'quality'))

        channel = transform_spaces(channel)
        if os.name == 'nt':
            #os.system('livestreamer twitch.tv/%s %s' % (channel, quality))
            os.system('livestreamer -p "%s" twitch.tv/%s %s' %
                      (player, channel, quality))
        else:
            #os.system('livestreamer twitch.tv/%s %s' % (channel, quality))
            os.system('livestreamer -np "%s" twitch.tv/%s %s' %
                      (player, channel, quality))

    def show_content(self, content):
        for i in range(len(content)):
            if i < 9:
                print '',
            if i < 99:
                print '',
            print '%d %s' % (i + 1, content[i])

    def handle_user_input(self, message, valid=None):
        self.state = 'none'
        validinput = False
        while not validinput:
            input = raw_input('%s\n ' % message)
            input = input.strip().lower()

            if input.isdigit():
                input = int(input)
                if input in valid:
                    validinput = True
                    return input
            elif len(input) == 1:
                c = ord(input)
                f = self.keybingings.get(c, None)
                if f:
                    f(c)
                    validinput = True
                    return -1

    def get_favorites(self, c):
        self.state = 'favs'
        del self.favs[:]
        try:
            response = self.twitch.get_favorites_streams_status(
                config.get('settings', 'favorites'))
            receivedcount = len(response['streams'])

            for i in range(receivedcount):
                self.favs.append('%s Reproduciendo: %s' %
                                 (response['streams'][i]['channel']['name'],
                                  response['streams'][i]['game']))

        except Exception as e:
            print 'Error obteniendo transmisiones favoritas!\n'
            print e.message
            return 0

    def get_games(self, c):
        self.state = 'games'
        del self.games[:]
        try:
            response = self.twitch.get_game_list()
            receivedcount = len(response['top'])

            for i in range(receivedcount):
                self.games.append(response['top'][i]['game']['name'])

        except Exception as e:
            print 'Error obteniendo juegos !\n'
            print e.message
            return 0

    def get_fav_games(self, c):
        self.state = 'favgames'
        del self.games[:]

        favgames = config.get('settings', 'favgames')
        if len(favgames) > 0:
            self.games.extend(favgames.split(', '))

    def get_channels(self, choice):
        self.state = 'channels'
        del self.channels[:]
        try:
            response = self.twitch.get_channel_for_game(
                transform_spaces(self.games[self.gchoice - 1]))
            receivedcount = len(response['streams'])

            for i in range(receivedcount):
                self.channels.append(
                    '%s (%s)' % (response['streams'][i]['channel']['name'],
                                 response['streams'][i]['viewers']))

        except Exception as e:
            print 'Error obteniendo canales !\n'
            print e.message
            return 0

    def refresh(self, c):
        print 'tmp'

    def get_next(self, c):
        print 'tmp'

    def get_previous(self, c):
        print 'tmp'
Exemple #21
0
            add, delete = previous[j]+1, current[j-1]+1
            change = previous[j-1]
            if a[j-1] != b[i-1]:
                change = change + 1
            current[j] = min(add, delete, change)
            
    return current[n]


start_time = time.time()

conn = pg8000.connect(user='******', password='******', database='twitchplayspokemonbot')
# change to a stream that is actually online

livestreamer = Livestreamer()
plugin = livestreamer.resolve_url("http://www.twitch.tv/twitchplayspokemon")
streams = plugin.get_streams()
stream = streams['high']

# download enough data to make sure the first frame is there
fd = stream.open()
data = ''
while len(data) < 3e5:
    data += fd.read(10245)
    time.sleep(0.1)
fd.close()

fname = 'C:\\Users\\derp\\workspace\\TPPBot\\images\\stream.bin'
fileHandle = open(fname, 'wb')
fileHandle.write(data)
fileHandle.close()
Exemple #22
0
from livestreamer import Livestreamer
import cv2
import subprocess as sp
FFMPEG_BIN = 'C:/ffmpeg/bin/ffmpeg.exe'
import numpy

livestreamer = Livestreamer()
plugin = livestreamer.resolve_url("http://www.ustream.tv/channel/jamthehype")
streams = plugin.get_streams()
print streams
stream = streams.get("best")
cv2.namedWindow("GoPro",cv2.CV_WINDOW_AUTOSIZE)
VIDEO_URL = stream.url
print VIDEO_URL
pipe = sp.Popen([FFMPEG_BIN, "-i", VIDEO_URL,
           "-loglevel", "quiet", # no text output
           "-an",   # disable audio
           "-f", "image2pipe",
           "-pix_fmt", "bgr24",
           "-vcodec", "rawvideo", "-"],
           stdin = sp.PIPE, stdout = sp.PIPE)
while True:
    raw_image = pipe.stdout.read(426*240*3) # read 432*240*3 bytes (= 1 frame)
    image =  numpy.fromstring(raw_image, dtype='uint8').reshape((240,426,3))
    cv2.imshow("GoPro",image)
    if cv2.waitKey(5) == 27:
        break
cv2.destroyAllWindows()
Exemple #23
0
    print help_message
    
    args, video_src = getopt.getopt(sys.argv[1:], '', ['cascade=', 'nested-cascade='])
    try: video_src = video_src[0]
    except: video_src = 0
    args = dict(args)
    cascade_fn = args.get('--cascade', "haarcascade_frontalface_alt.xml")
    nested_fn  = args.get('--nested-cascade', "haarcascade_eye.xml")

    cascade = cv2.CascadeClassifier(cascade_fn)
    nested = cv2.CascadeClassifier(nested_fn)

    FFMPEG_BIN = 'C:/ffmpeg/bin/ffmpeg.exe'

    livestreamer = Livestreamer()
    plugin = livestreamer.resolve_url("http://www.ustream.tv/channel/personal-cam1")
    streams = plugin.get_streams()
    stream = streams.get("best")
    VIDEO_URL = stream.url
    print VIDEO_URL
    pipe = sp.Popen([FFMPEG_BIN, "-i", VIDEO_URL,
           "-loglevel", "quiet", # no text output
           "-an",   # disable audio
           "-f", "image2pipe",
           "-pix_fmt", "bgr24",
           "-vcodec", "rawvideo", "-"],
           stdin = sp.PIPE, stdout = sp.PIPE)

    while True:
        raw_image = pipe.stdout.read(426*240*3) # read 432*240*3 bytes (= 1 frame)
        img = np.fromstring(raw_image, dtype='uint8').reshape((240,426,3))
Exemple #24
0
class StreamList(object):

    def __init__(self, filename, rc_module):
        """ Init and try to load a stream list, nothing about curses yet """

        self.db_was_read = False

        # Open the storage (create it if necessary
        try:
            f = shelve.open(filename, 'c')
        except Exception:
            raise ShelveError(
                'Database could not be opened, another livestreamer-curses instance might be already running. '
                'Please note that a database created with Python 2.x cannot be used with Python 3.x and vice versa.'
            )
        self.max_id = 0

        # Sort streams by view count
        try:
            self.streams = sorted(f['streams'], key=lambda s:s['seen'], reverse=True)
            for s in self.streams:
                # Max id, needed when adding a new stream
                self.max_id = max(self.max_id, s['id'])
                s['online'] = 2
        except:
            self.streams = []
        self.db_was_read = True
        self.filtered_streams = list(self.streams)
        self.filter = ''
        self.all_streams_offline = None
        self.show_offline_streams = False
        self.rc_module = rc_module

        if 'LIVESTREAMER_COMMANDS' in dir(self.rc_module):
            self.cmd_list = list(map(shlex.split, self.rc_module.LIVESTREAMER_COMMANDS))
        else:
            self.cmd_list = [['livestreamer']]
        self.cmd_index = 0
        self.cmd = self.cmd_list[self.cmd_index]

        if 'DEFAULT_RESOLUTION' in dir(self.rc_module):
            self.default_res = self.rc_module.DEFAULT_RESOLUTION
        else:
            self.default_res = DEFAULT_RESOLUTION_HARD

        self.store = f
        self.store.sync()

        self.no_streams = self.streams == []
        self.no_stream_shown = self.no_streams
        self.q = ProcessList(StreamPlayer().play)

        self.livestreamer = Livestreamer()

    def __del__(self):
        """ Stop playing streams and sync storage """
        try:
            self.q.terminate()
            if self.db_was_read:
                self.store['cmd'] = self.cmd
                self.store['streams'] = self.streams
                self.store.close()
        except:
            pass

    def __call__(self, s):
        # Terminal initialization
        self.init(s)
        # Main event loop
        self.run()

    def init(self, s):
        """ Initialize the text interface """

        # Hide cursor
        curses.curs_set(0)

        self.s = s
        self.s.keypad(1)

        self.set_screen_size()

        self.pads = {}
        self.offsets = {}

        self.init_help()
        self.init_streams_pad()
        self.current_pad = 'streams'

        self.set_title(TITLE_STRING)

        self.got_g = False

        signal.signal(28, self.resize)

        if 'CHECK_ONLINE_ON_START' in dir(self.rc_module) and self.rc_module.CHECK_ONLINE_ON_START:
            self.check_online_streams()

        self.set_status('Ready')

    def getheightwidth(self):
        """ getwidth() -> (int, int)

        Return the height and width of the console in characters
        https://groups.google.com/forum/#!msg/comp.lang.python/CpUszNNXUQM/QADpl11Z-nAJ"""
        try:
            return int(os.environ["LINES"]), int(os.environ["COLUMNS"])
        except KeyError:
            height, width = struct.unpack(
                "hhhh", ioctl(0, termios.TIOCGWINSZ ,"\000"*8))[0:2]
            if not height:
                return 25, 80
            return height, width

    def resize(self, signum, obj):
        """ handler for SIGWINCH """
        self.s.clear()
        stream_cursor = self.pads['streams'].getyx()[0]
        for pad in self.pads.values():
            pad.clear()
        self.s.refresh()
        self.set_screen_size()
        self.set_title(TITLE_STRING)
        self.init_help()
        self.init_streams_pad()
        self.move(stream_cursor, absolute=True, pad_name='streams', refresh=False)
        self.s.refresh()
        self.show()

    def run(self):
        """ Main event loop """

        # Show stream list
        self.show_streams()

        while True:
            self.s.refresh()

            # See if any stream has ended
            self.check_stopped_streams()

            # Wait on stdin or on the streams output
            souts = self.q.get_stdouts()
            souts.append(sys.stdin)
            try:
                (r, w, x) = select.select(souts, [], [], 1)
            except select.error:
                continue
            for fd in r:
                if fd != sys.stdin:
                    # Set the new status line only if non-empty
                    msg = fd.readline()
                    if msg:
                        self.set_status(msg[:-1])
                else:
                    # Main event loop
                    c = self.pads[self.current_pad].getch()
                    if c == curses.KEY_UP or c == ord('k'):
                        self.move(-1)
                    elif c == curses.KEY_DOWN or c == ord('j'):
                        self.move(1)
                    elif c == ord('f'):
                        if self.current_pad == 'streams':
                            self.filter_streams()
                    elif c == ord('F'):
                        if self.current_pad == 'streams':
                            self.clear_filter()
                    elif c == ord('g'):
                        if self.got_g:
                            self.move(0, absolute=True)
                            self.got_g = False
                            continue
                        self.got_g = True
                    elif c == ord('G'):
                        self.move(len(self.filtered_streams)-1, absolute=True)
                    elif c == ord('q'):
                        if self.current_pad == 'streams':
                            self.q.terminate()
                            return
                        else:
                            self.show_streams()
                    elif c == 27: # ESC
                        if self.current_pad != 'streams':
                            self.show_streams()
                    if self.current_pad == 'help':
                        continue
                    elif c == 10:
                        self.play_stream()
                    elif c == ord('s'):
                        self.stop_stream()
                    elif c == ord('c'):
                        self.reset_stream()
                    elif c == ord('n'):
                        self.edit_stream('name')
                    elif c == ord('r'):
                        self.edit_stream('res')
                    elif c == ord('u'):
                        self.edit_stream('url')
                    elif c == ord('l'):
                        self.show_commandline()
                    elif c == ord('L'):
                        self.shift_commandline()
                    elif c == ord('a'):
                        self.prompt_new_stream()
                    elif c == ord('d'):
                        self.delete_stream()
                    elif c == ord('o'):
                        self.show_offline_streams ^= True
                        self.refilter_streams()
                    elif c == ord('O'):
                        self.check_online_streams()
                    elif c == ord('h') or c == ord('?'):
                        self.show_help()

    def set_screen_size(self):
        """ Setup screen size and padding

        We have need 2 free lines at the top and 2 free lines at the bottom

        """
        height, width = self.getheightwidth()
        curses.resizeterm(height, width)
        self.pad_x = 0
        self.max_y, self.max_x = (height-1, width-1)
        self.pad_h = height-3
        self.pad_w = width-2*self.pad_x

    def overwrite_line(self, msg, attr=curses.A_NORMAL):
        self.s.clrtoeol()
        self.s.addstr(msg, attr)
        self.s.chgat(attr)

    def set_title(self, msg):
        """ Set first header line text """
        self.s.move(0, 0)
        self.overwrite_line(msg, curses.A_REVERSE)

    def set_header(self, msg):
        """ Set second head line text """
        self.s.move(1, 0)
        self.overwrite_line(msg, attr=curses.A_NORMAL)

    def set_footer(self, msg, reverse=True):
        """ Set first footer line text """
        self.s.move(self.max_y-1, 0)
        if reverse:
            self.overwrite_line(msg, attr=curses.A_REVERSE)
        else:
            self.overwrite_line(msg, attr=curses.A_NORMAL)

    def clear_footer(self):
        self.s.move(self.max_y-1, 0)
        self.overwrite_line('')

    def init_help(self):
        help_pad_length = 27    # there should be a neater way to do this
        h = curses.newpad(help_pad_length, self.pad_w)
        h.keypad(1)

        h.addstr( 0, 0, 'STREAM MANAGEMENT', curses.A_BOLD)
        h.addstr( 2, 0, '  Enter : start stream')
        h.addstr( 3, 0, '  s     : stop stream')
        h.addstr( 4, 0, '  r     : change stream resolution')
        h.addstr( 5, 0, '  n     : change stream name')
        h.addstr( 6, 0, '  u     : change stream URL')
        h.addstr( 7, 0, '  c     : reset stream view count')
        h.addstr( 8, 0, '  a     : add stream')
        h.addstr( 9, 0, '  d     : delete stream')

        h.addstr(11, 0, '  l     : show command line')
        h.addstr(12, 0, '  L     : cycle command line')

        h.addstr(15, 0, 'NAVIGATION', curses.A_BOLD)
        h.addstr(17, 0, '  j/up  : up one line')
        h.addstr(18, 0, '  k/down: down one line')
        h.addstr(19, 0, '  f     : filter streams')
        h.addstr(20, 0, '  F     : clear filter')
        h.addstr(21, 0, '  o     : toggle offline streams')
        h.addstr(22, 0, '  O     : check for online streams')
        h.addstr(23, 0, '  gg    : go to top')
        h.addstr(24, 0, '  G     : go to bottom')
        h.addstr(25, 0, '  h/?   : show this help')
        h.addstr(26, 0, '  q     : quit')

        self.pads['help'] = h
        self.offsets['help'] = 0

    def show(self):
        funcs = {
            'streams' : self.show_streams,
            'help'    : self.show_help
        }
        funcs[self.current_pad]()

    def show_help(self):
        """ Redraw Help screen and wait for any input to leave """
        self.s.move(1,0)
        self.s.clrtobot()
        self.set_header('Help'.center(self.pad_w))
        self.set_footer(' ESC or \'q\' to return to main menu')
        self.s.refresh()
        self.current_pad = 'help'
        self.refresh_current_pad()

    def init_streams_pad(self, start_row=0):
        """ Create a curses pad and populate it with a line by stream """
        y = 0
        pad = curses.newpad(max(1,len(self.filtered_streams)), self.pad_w)
        pad.keypad(1)
        for s in self.filtered_streams:
            pad.addstr(y, 0, self.format_stream_line(s))
            y+=1
        self.offsets['streams'] = 0
        pad.move(start_row, 0)
        if not self.no_stream_shown:
            pad.chgat(curses.A_REVERSE)
        self.pads['streams'] = pad

    def show_streams(self):
        self.s.move(1,0)
        self.s.clrtobot()
        self.current_pad = 'streams'
        if self.no_stream_shown:
            self.hide_streams_pad()
            if self.no_streams:
                self.s.addstr(5, 5, 'It seems you don\'t have any stream yet')
                self.s.addstr(6, 5, 'Hit \'a\' to add a new one')
                self.s.addstr(8, 5, 'Hit \'?\' for help')
            elif self.all_streams_offline and not self.show_offline_streams:
                self.s.addstr(5, 5, 'All streams are currently offline')
                self.s.addstr(6, 5, 'Hit \'o\' to show offline streams')
                self.s.addstr(7, 5, 'Hit \'O\' to refresh')
                self.s.addstr(9, 5, 'Hit \'?\' for help')
            else:
                self.s.addstr(5, 5, 'No stream matches your filter')
                self.s.addstr(6, 5, 'Hit \'f\' to change filter')
                self.s.addstr(7, 5, 'Hit \'F\' to clear')
                self.s.addstr(8, 5, 'Hit \'o\' to show offline streams')
                self.s.addstr(10, 5, 'Hit \'?\' for help')
        else:
            idf = 'ID'.center(ID_FIELD_WIDTH)
            name = 'Name'.center(NAME_FIELD_WIDTH)
            res = 'Resolution'.center(RES_FIELD_WIDTH)
            views = 'Views'.center(VIEWS_FIELD_WIDTH)
            self.set_header('{0} {1} {2} {3}  Status'.format(idf, name, res, views))
            self.redraw_stream_footer()
            self.redraw_status()
        self.s.refresh()
        if not self.no_stream_shown:
            self.refresh_current_pad()

    def hide_streams_pad(self):
        pad = self.pads.get('streams')
        if pad:
            pad.refresh(0, 0, 2, 0, 2, 0)

    def refresh_current_pad(self):
        pad = self.pads[self.current_pad]
        pad.refresh(self.offsets[self.current_pad], 0, 2, self.pad_x, self.pad_h, self.pad_w)

    def move(self, direction, absolute=False, pad_name=None, refresh=True):
        """ Scroll the current pad

        direction : (int)  move by one in the given direction
                           -1 is up, 1 is down. If absolute is True,
                           go to position direction.
                           Behaviour is affected by cursor_line and scroll_only below
        absolute  : (bool)
        """

        # pad in this lists have the current line highlighted
        cursor_line = [ 'streams' ]

        # pads in this list will be moved screen-wise as opposed to line-wise
        # if absolute is set, will go all the way top or all the way down depending
        # on direction
        scroll_only = [ 'help' ]

        if not pad_name:
            pad_name = self.current_pad
        pad = self.pads[pad_name]
        if pad_name == 'streams' and self.no_streams:
            return
        (row, col) = pad.getyx()
        new_row    = row
        offset = self.offsets[pad_name]
        new_offset = offset
        if pad_name in scroll_only:
            if absolute:
                if direction > 0:
                    new_offset = pad.getmaxyx()[0] - self.pad_h + 1
                else:
                    new_offset = 0
            else:
                if direction > 0:
                    new_offset = min(pad.getmaxyx()[0] - self.pad_h + 1, offset + self.pad_h)
                elif offset > 0:
                    new_offset = max(0, offset - self.pad_h)
        else:
            if absolute and direction >= 0 and direction < pad.getmaxyx()[0]:
                if direction < offset:
                    new_offset = direction
                elif direction > offset + self.pad_h - 2:
                    new_offset = direction - self.pad_h + 2
                new_row = direction
            else:
                if direction == -1 and row > 0:
                    if row == offset:
                        new_offset -= 1
                    new_row = row-1
                elif direction == 1 and row < len(self.filtered_streams)-1:
                    if row == offset + self.pad_h - 2:
                        new_offset += 1
                    new_row = row+1
        if pad_name in cursor_line:
            pad.move(row, 0)
            pad.chgat(curses.A_NORMAL)
        self.offsets[pad_name] = new_offset
        pad.move(new_row, 0)
        if pad_name in cursor_line:
            pad.chgat(curses.A_REVERSE)
        if pad_name == 'streams':
            self.redraw_stream_footer()
        if refresh:
            self.refresh_current_pad()

    def format_stream_line(self, stream):
        idf = '{0} '.format(stream['id']).rjust(ID_FIELD_WIDTH)
        name = ' {0}'.format(stream['name'][:NAME_FIELD_WIDTH-2]).ljust(NAME_FIELD_WIDTH)
        res  = ' {0}'.format(stream['res'][:RES_FIELD_WIDTH-2]).ljust(RES_FIELD_WIDTH)
        views  = '{0} '.format(stream['seen']).rjust(VIEWS_FIELD_WIDTH)
        p = self.q.get_process(stream['id']) != None
        if p:
            indicator = '[>>>]'
        else:
            indicator = INDICATORS[stream['online']]
        return '{0} {1} {2} {3}   {4}'.format(idf, name, res, views, indicator)

    def redraw_current_line(self):
        """ Redraw the highlighted line """
        if self.no_streams:
            return
        row = self.pads[self.current_pad].getyx()[0]
        s = self.filtered_streams[row]
        pad = self.pads['streams']
        pad.move(row, 0)
        pad.clrtoeol()
        pad.addstr(row, 0, self.format_stream_line(s), curses.A_REVERSE)
        pad.chgat(curses.A_REVERSE)
        pad.move(row, 0)
        self.refresh_current_pad()

    def set_status(self, status):
        self.status = status
        self.redraw_status()

    def redraw_status(self):
        self.s.move(self.max_y, 0)
        self.overwrite_line(self.status[:self.max_x], curses.A_NORMAL)
        self.s.refresh()

    def redraw_stream_footer(self):
        if not self.no_stream_shown:
            row = self.pads[self.current_pad].getyx()[0]
            s = self.filtered_streams[row]
            self.set_footer('{0}/{1} {2} {3}'.format(row+1, len(self.filtered_streams), s['url'], s['res']))
            self.s.refresh()

    def check_stopped_streams(self):
        finished = self.q.get_finished()
        for f in finished:
            for s in self.streams:
                try:
                    i = self.filtered_streams.index(s)
                except ValueError:
                    continue
                if f == s['id']:
                    self.set_footer('Stream {0} has stopped'.format(s['name']))
                    if i == self.pads[self.current_pad].getyx()[0]:
                        attr = curses.A_REVERSE
                    else:
                        attr = curses.A_NORMAL
                    self.pads['streams'].addstr(i, PLAYING_FIELD_OFFSET,
                                                INDICATORS[s['online']], attr)
                    self.refresh_current_pad()

    def _check_stream(self, url):
        try:
            plugin = self.livestreamer.resolve_url(url)
            avail_streams = plugin.get_streams()
            if avail_streams:
                return 1
            return 0
        except:
            return 3

    def check_online_streams(self):
        self.all_streams_offline = True
        self.set_status(' Checking online streams...')

        done_queue   = queue.Queue()

        def check_stream_managed(args):
            url, queue = args
            status = self._check_stream(url)
            done_queue.put(url)
            return status

        pool = Pool(CHECK_ONLINE_THREADS)
        args = [(s['url'], done_queue) for s in self.streams]
        statuses = pool.map_async(check_stream_managed, args)
        n_streams = len(self.streams)

        while not statuses.ready():
            sleep(0.1)
            self.set_status(' Checked {0}/{1} streams...'.format(done_queue.qsize(), n_streams))
            self.s.refresh()

        statuses = statuses.get()
        for i, s in enumerate(self.streams):
            s['online'] = statuses[i]
            if s['online']:
                self.all_streams_offline = False

        self.refilter_streams()

    def prompt_input(self, prompt=''):
        self.s.move(self.max_y, 0)
        self.s.clrtoeol()
        self.s.addstr(prompt)
        curses.curs_set(1)
        curses.echo()
        r = self.s.getstr().decode()
        curses.noecho()
        curses.curs_set(0)
        self.s.move(self.max_y, 0)
        self.s.clrtoeol()
        return r

    def prompt_confirmation(self, prompt='', def_yes=False):
        self.s.move(self.max_y-1, 0)
        self.s.clrtoeol()
        if def_yes:
            hint = '[y]/n'
        else:
            hint = 'y/[n]'
        self.s.addstr('{0} {1} '.format(prompt, hint))
        curses.curs_set(1)
        curses.echo()
        r = self.s.getch()
        curses.noecho()
        curses.curs_set(0)
        self.s.move(self.max_y-1, 0)
        self.s.clrtoeol()
        if r == ord('y'):
            return True
        elif r == ord('n'):
            return False
        else:
            return def_yes

    def sync_store(self):
        self.store['streams'] = self.streams
        self.store.sync()

    def bump_stream(self, stream, throttle=False):
        t = int(time())

        # only bump if stream was last started some time ago
        if throttle and  t - stream['last_seen'] < 60*1:
            return
        stream['seen'] += 1
        stream['last_seen'] = t
        self.sync_store()

    def find_stream(self, sel, key='id'):
        for s in self.streams:
            if s[key] == sel:
                return s
        return None

    def clear_filter(self):
        self.filter = ''
        self.refilter_streams()

    def filter_streams(self):
        self.filter = self.prompt_input('Filter: ').lower()
        self.refilter_streams()

    def refilter_streams(self, quiet=False):
        self.filtered_streams = []
        for s in self.streams:
            if ((self.show_offline_streams or s['online'] in [1,2])
                and (self.filter in s['name'].lower() or self.filter in s['url'].lower())):
                self.filtered_streams.append(s)
        self.filtered_streams.sort(key=lambda s:s['seen'], reverse=True)
        self.no_stream_shown = len(self.filtered_streams) == 0
        if not quiet:
            self.status = ' Filter: {0} ({1}/{2} matches, {3} showing offline streams)'.format(
                    self.filter or '<empty>', len(self.filtered_streams), len(self.streams),
                    '' if self.show_offline_streams else 'NOT')
        self.init_streams_pad()
        self.redraw_stream_footer()
        self.show_streams()
        self.redraw_status()

    def add_stream(self, name, url, res=None, bump=False):
        ex_stream = self.find_stream(url, key='url')
        if ex_stream:
            if bump:
                self.bump_stream(ex_stream)
        else:
            if bump:
                seen = 1
                last_seen = int(time())
            else:
                seen = last_seen = 0
            if not self.streams:
                idf = 1
            else:
                self.max_id += 1
                idf = self.max_id

            s_res = res or self.default_res

            if type(s_res) == str:
                actual_res = s_res
            elif type(s_res) == dict:
                actual_res = DEFAULT_RESOLUTION_HARD
                for k,v in s_res.items():
                    if k in url:
                        actual_res = v
                        break
            elif callable(s_res):
                actual_res = s_res(url) or DEFAULT_RESOLUTION_HARD
            else:
                actual_res = DEFAULT_RESOLUTION_HARD

            self.set_status(' Checking if new stream is online...')
            self.s.refresh()
            online = self._check_stream(url)

            new_stream = {
                    'id'        : idf,
                    'name'      : name,
                    'seen'      : seen,
                    'last_seen' : last_seen,
                    'res'       : actual_res,
                    'url'       : url,
                    'online'    : online
                }
            self.streams.append(new_stream)
            self.no_streams = False
            self.refilter_streams()
            self.sync_store()

    def delete_stream(self):
        if self.no_streams:
            return
        pad = self.pads[self.current_pad]
        s = self.filtered_streams[pad.getyx()[0]]
        if not self.prompt_confirmation('Delete stream {0}?'.format(s['name'])):
            return
        self.filtered_streams.remove(s)
        self.streams.remove(s)
        pad.deleteln()
        self.sync_store()
        if not self.streams:
            self.no_streams = True
        if not self.filtered_streams:
            self.no_stream_shown = True
        if pad.getyx()[0] == len(self.filtered_streams) and not self.no_stream_shown:
            self.move(-1, refresh=False)
            pad.chgat(curses.A_REVERSE)
        self.redraw_current_line()
        self.show_streams()

    def reset_stream(self):
        if self.no_stream_shown:
            return
        pad = self.pads[self.current_pad]
        s = self.filtered_streams[pad.getyx()[0]]
        if not self.prompt_confirmation('Reset stream {0}?'.format(s['name'])):
            return
        s['seen']      = 0
        s['last_seen'] = 0
        self.redraw_current_line()
        self.sync_store()

    def edit_stream(self, attr):
        prompt_info = {
                'name'      : 'Name',
                'url'       : 'URL',
                'res'       : 'Resolution'
                }
        if self.no_streams:
            return
        pad = self.pads[self.current_pad]
        s = self.filtered_streams[pad.getyx()[0]]
        new_val = self.prompt_input('{0} (empty to cancel): '.format(prompt_info[attr]))
        if new_val != '':
            s[attr] = new_val
            self.redraw_current_line()
        self.redraw_status()
        self.redraw_stream_footer()

    def show_commandline(self):
        self.set_footer('{0}/{1} {2}'.format(self.cmd_index+1, len(self.cmd_list), ' '.join(self.cmd)))

    def shift_commandline(self):
        self.cmd_index += 1
        if self.cmd_index == len(self.cmd_list):
            self.cmd_index = 0
        self.cmd = self.cmd_list[self.cmd_index]
        self.show_commandline()

    def prompt_new_stream(self):
        url = self.prompt_input('New stream URL (empty to cancel): ')
        name = url.split('/')[-1]
        if name:
            self.add_stream(name, url)
            self.move(len(self.filtered_streams)-1, absolute=True, refresh=False)
            self.show_streams()

    def play_stream(self):
        if self.no_stream_shown:
            return
        pad = self.pads[self.current_pad]
        s = self.filtered_streams[pad.getyx()[0]]
        try:
            self.q.put(s['id'], s['url'], s['res'], self.cmd)
            self.bump_stream(s, throttle=True)
            self.redraw_current_line()
            self.refresh_current_pad()
        except Exception as e:
            if type(e) == QueueDuplicate:
                self.set_footer('This stream is already playing')
            elif type(e) == OSError:
                self.set_footer('/!\ Faulty command line: {0}'.format(e.strerror))
            else:
                raise e

    def stop_stream(self):
        if self.no_stream_shown:
            return
        pad = self.pads[self.current_pad]
        s = self.filtered_streams[pad.getyx()[0]]
        p = self.q.terminate_process(s['id'])
        if p:
            self.redraw_current_line()
            self.redraw_stream_footer()
            self.redraw_status()
class TestPluginStream(unittest.TestCase):
    def setUp(self):
        self.session = Livestreamer()

    def assertDictHas(self, a, b):
        for key, value in a.items():
            self.assertEqual(b[key], value)

    def _test_akamaihd(self, surl, url):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, AkamaiHDStream))
        self.assertEqual(stream.url, url)

    def _test_hls(self, surl, url):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, HLSStream))
        self.assertEqual(stream.url, url)

    def _test_rtmp(self, surl, url, params):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, RTMPStream))
        self.assertEqual(stream.params["rtmp"], url)
        self.assertDictHas(params, stream.params)

    def _test_http(self, surl, url, params):
        channel = self.session.resolve_url(surl)
        streams = channel.get_streams()

        self.assertTrue("live" in streams)

        stream = streams["live"]
        self.assertTrue(isinstance(stream, HTTPStream))
        self.assertEqual(stream.url, url)
        self.assertDictHas(params, stream.args)

    def test_plugin(self):
        self._test_rtmp("rtmp://hostname.se/stream",
                         "rtmp://hostname.se/stream", dict())

        self._test_rtmp("rtmp://hostname.se/stream live=1 num=47",
                        "rtmp://hostname.se/stream", dict(live=True, num=47))

        self._test_rtmp("rtmp://hostname.se/stream live=1 qarg='a \\'string' noq=test",
                        "rtmp://hostname.se/stream", dict(live=True, qarg='a \'string', noq="test"))

        self._test_hls("hls://https://hostname.se/playlist.m3u8",
                       "https://hostname.se/playlist.m3u8")

        self._test_hls("hls://hostname.se/playlist.m3u8",
                       "http://hostname.se/playlist.m3u8")

        self._test_akamaihd("akamaihd://http://hostname.se/stream",
                            "http://hostname.se/stream")

        self._test_akamaihd("akamaihd://hostname.se/stream",
                            "http://hostname.se/stream")

        self._test_http("httpstream://http://hostname.se/auth.php auth=('test','test2')",
                        "http://hostname.se/auth.php", dict(auth=("test", "test2")))

        self._test_http("httpstream://hostname.se/auth.php auth=('test','test2')",
                        "http://hostname.se/auth.php", dict(auth=("test", "test2")))

        self._test_http("httpstream://https://hostname.se/auth.php verify=False params={'key': 'a value'}",
                       "https://hostname.se/auth.php?key=a+value", dict(verify=False, params=dict(key='a value')))
Exemple #26
0
class GreekStreamTVList(Screen):
    skin = '\n \t\t<screen name="GreekStreamTVList" position="center,center" size="800,400" title="GreekStreamTV List (Livestreamer) v3.2">\n\t\t\t<widget name="streamlist" position="0,0" size="800,360" backgroundColor="#000000" zPosition="10" scrollbarMode="showOnDemand" />\n\t\t\t<widget name="info" position="0,365" zPosition="2" size="800,35" font="Regular;22" foregroundColor="#ffffff" transparent="1" halign="center" valign="center" />\n\t\t</screen>\n           '

    def __init__(self, session, streamFile = None):
        self.session = session
        Screen.__init__(self, session)
        self['info'] = Label('...')
        self['actions'] = ActionMap(['OkCancelActions',
         'ShortcutActions',
         'WizardActions',
         'ColorActions',
         'SetupActions',
         'NumberActions',
         'MenuActions'], {'ok': self.keyOK,
         'cancel': self.keyCancel,
         'up': self.keyUp,
         'down': self.keyDown,
         'left': self.keyLeft,
         'right': self.keyRight}, -1)
        self.streamBin = '/usr/bin/rtmpdump'
        self.streamPipe = '/tmp/greekstreamtv.avi'
        if not streamFile:
            self.streamFile = resolveFilename(SCOPE_PLUGINS, 'Extensions/GreekStreamTV/stream.xml')
        else:
            self.streamFile = streamFile
        self.lvstreamer = Livestreamer()
        self.streamList = []
        self.makeStreamList()
        self.streamMenuList = MenuList([], enableWrapAround=True, content=eListboxPythonMultiContent)
        self.streamMenuList.l.setFont(0, gFont('Regular', 22))
        self.streamMenuList.l.setFont(1, gFont('Regular', 18))
        self.streamMenuList.l.setItemHeight(37)
        self['streamlist'] = self.streamMenuList
        self.streamMenuList.setList(map(streamListEntry, self.streamList))
        self.onLayoutFinish.append(self.layoutFinished)
        self.beforeService = None
        self.currentService = None
        self.playerStoped = False
        self.keyLocked = False
        self.pd = None
        self.qsel = None
        return

    def layoutFinished(self):
        os.system('killall -9 rtmpdump')
        self.showName()

    def keyLeft(self):
        if self.keyLocked:
            return
        self['streamlist'].pageUp()
        self.showName()

    def keyRight(self):
        if self.keyLocked:
            return
        self['streamlist'].pageDown()
        self.showName()

    def keyUp(self):
        if self.keyLocked:
            return
        self['streamlist'].up()
        self.showName()

    def keyDown(self):
        if self.keyLocked:
            return
        self['streamlist'].down()
        self.showName()

    def keyCancel(self):
        self.LivestreamerStop()
        if '/usr/lib/enigma2/python/Plugins/Extensions/GreekStreamTV' in path:
            path.remove('/usr/lib/enigma2/python/Plugins/Extensions/GreekStreamTV')
        self.close()

    def showName(self):
        try:
            tmpName = self['streamlist'].getCurrent()[0][1].get('name')
        except:
            tmpName = '...'

        self['info'].setText(tmpName)

    def keyOK(self):
        print '[GreekStreamTVList::keyOK]'
        if self.keyLocked:
            return
        uriName = self['streamlist'].getCurrent()[0][1].get('name')
        self['info'].setText('Starting %s Please Wait...' % uriName)
        self.timer = eTimer()
        self.timer.callback.append(self.StartStream)
        self.timer.start(100, 1)

    def StartStream(self):
        self.timer.stop()
        self.keyLocked = True
        self.beforeService = None
        self.currentService = None
        self.playerStoped = False
        self.pd = None
        streamInfo = self['streamlist'].getCurrent()[0][1]
        uriInfo = streamInfo.get('uri')
        typeInfo = streamInfo.get('type').split(':')
        protocol = typeInfo[0]
        serviceType = typeInfo[1]
        bufferSize = typeInfo[2]
        url = uriInfo.get('URL')
        if protocol == 'rtmp':
            url += ' '
            url += ' '.join([ '%s=%s' % (key, value) for key, value in uriInfo.items() if key != 'URL' ])
            url = ' '.join(url.split())
            print '[GreekStreamTVList::keyOK] URL is ', url, ' URI is ', uriInfo
            self.doStreamAction(url, serviceType, bufferSize)
        elif protocol in ('rtsp', 'http'):
            self.doStreamAction(url, serviceType, bufferSize)
        elif protocol == 'livestreamer':
            channel = None
            streams = None
            try:
                url += ' '
                url += ' '.join([ '%s=%s' % (key, value) for key, value in uriInfo.items() if key != 'URL' ])
                url = ' '.join(url.split())
                print '[GreekStreamTVList::keyOK] URL is ', url, ' URI is ', uriInfo
                channel = self.lvstreamer.resolve_url(url)
                streams = channel.get_streams()
                print '[GreekStreamTVList::keyOK] Streams: ', streams.keys()
                print '[GreekStreamTVList::keyOK] Streams: ', streams.items()
                if len(streams) == 3 and 'best' in streams and 'worst' in streams:
                    self.streamPreBuffer(streams['best'])
                elif len(streams) == 0:
                    raise Exception('No Streams Found')
                else:
                    self.qsel = self.session.openWithCallback(self.QualitySelClosed, SelectQuality, streams, self.streamPreBuffer)
            except Exception as err:
                print '[GreekStreamTVList::keyOK::Exception] Error: ', err
                tmpMessage = 'An Error Occured: ' + str(err)[:200] + '...'
                self.session.openWithCallback(self.stopPlayer, MessageBox, tmpMessage, type=MessageBox.TYPE_ERROR, timeout=20)

        else:
            print '[GreekStreamTVList::keyOK] Unknown Protocol: ', protocol
            tmpMessage = 'Unknown Protocol: ' + protocol
            self.session.openWithCallback(self.stopPlayer, MessageBox, tmpMessage, type=MessageBox.TYPE_WARNING, timeout=20)
        return

    def QualitySelClosed(self, recursive):
        if self.qsel:
            self.qsel.close()
        self.qsel = None
        self.stopPlayer()
        return

    def streamPreBuffer(self, stream):
        fd = None
        try:
            fd = stream.open()
            prebuffer = fd.read(1049088)
            if len(prebuffer) == 0:
                raise Exception('No Data Received From Stream Server')
            start_new_thread(self.streamCopy, (fd, prebuffer))
            sleep(1.5)
            self.doStreamAction(self.streamPipe)
        except Exception as err:
            if fd and hasattr(fd, 'close'):
                fd.close()
            print '[GreekStreamTVList::streamPreBuffer::Exception] Error: ', err
            tmpMessage = 'An Error Occured while buffering: ' + str(err)[:200] + '...'
            self.session.openWithCallback(self.stopPlayer, MessageBox, tmpMessage, type=MessageBox.TYPE_ERROR, timeout=20)

        return

    def streamCopy(self, fd, prebuffer):
        print '[GreekStreamTVList::streamCopy]'
        if os.access(self.streamPipe, os.F_OK):
            os.remove(self.streamPipe)
        os.mkfifo(self.streamPipe)
        self.pd = open(self.streamPipe, 'wb')
        try:
            self.pd.write(prebuffer)
            while self is not None and self.session is not None and not self.playerStoped:
                data = fd.read(8192)
                if len(data) == 0:
                    break
                self.pd.write(data)

            print '[GreekStreamTVList:streamCopy] playerStoped'
            self.pd.close()
            if hasattr(fd, 'close'):
                fd.close()
            fd = None
        except Exception as err:
            print '[GreekStreamTVList::streamCopy] Exception: ', err
        finally:
            self.playerStoped = True
            if fd and hasattr(fd, 'close'):
                fd.close()

        return

    def LivestreamerStop(self):
        print '[GreekStreamTVList::LivestreamStop]'
        self['info'].setText('...')
        self.keyLocked = False
        self.playerStoped = True
        os.system('killall -9 rtmpdump')
        sleep(0.5)
        if self.pd:
            try:
                self.pd.close()
            except:
                sleep(0.5)
                try:
                    self.pd.close()
                except:
                    pass

        if self.qsel is not None:
            self.qsel.close(False)
        self.pd = None
        self.qsel = None
        return

    def doStreamAction(self, url = None, serviceType = 4097, bufferSize = None):
        if url is None:
            url = self.streamPipe
            self.streamPlayerTimer.stop()
        try:
            serviceType = int(serviceType)
        except:
            serviceType = 4097

        try:
            bufferSize = int(bufferSize)
        except:
            bufferSize = None

        service = eServiceReference(serviceType, 0, url)
        streamInfo = self['streamlist'].getCurrent()[0][1]
        service.setName(str(streamInfo.get('name')))
        uriInfo = streamInfo.get('uri')
        self.beforeService = self.session.nav.getCurrentlyPlayingServiceReference()
        self.currentService = self.session.openWithCallback(self.onStreamFinished, GreekStreamTVPlayer, service, stopPlayer=self.stopPlayer, chName=str(streamInfo.get('name')), chURL=str(uriInfo.get('URL')), chIcon=str(streamInfo.get('icon')))
        return

    def stopPlayer(self, params = None):
        print '[GreekStreamTV::stopPlayer]'
        if params is None or isinstance(params, bool):
            self.playerStoped = True
            self.LivestreamerStop()
            return
        else:
            return

    def onStreamFinished(self):
        print '[GreekStreamTV::onStreamFinished]'
        self.LivestreamerStop()
        self.session.nav.playService(self.beforeService)
        print '[GreekStreamTV::onStreamFinished] player done!!'

    def makeStreamList(self):
        try:
            streamDB = StreamURIParser(self.streamFile).parseStreamList()
        except Exception as err:
            print '[GreekStreamTV::makeStreamList] Error: ', err
            streamDB = []

        self.streamList = [ (x.get('name'), x) for x in streamDB ]
class TestSession(unittest.TestCase):
    PluginPath = os.path.join(os.path.dirname(__file__), "plugins")

    def setUp(self):
        self.session = Livestreamer()
        self.session.load_plugins(self.PluginPath)

    def test_exceptions(self):
        try:
            self.session.resolve_url("invalid url")
            self.assertTrue(False)
        except NoPluginError:
            self.assertTrue(True)

    def test_load_plugins(self):
        plugins = self.session.get_plugins()
        self.assertTrue(plugins["testplugin"])

    def test_builtin_plugins(self):
        plugins = self.session.get_plugins()
        self.assertTrue("twitch" in plugins)

    def test_resolve_url(self):
        plugins = self.session.get_plugins()
        channel = self.session.resolve_url("http://test.se/channel")
        self.assertTrue(isinstance(channel, Plugin))
        self.assertTrue(isinstance(channel, plugins["testplugin"]))

    def test_options(self):
        self.session.set_option("test_option", "option")
        self.assertEqual(self.session.get_option("test_option"), "option")
        self.assertEqual(self.session.get_option("non_existing"), None)

        self.assertEqual(self.session.get_plugin_option("testplugin", "a_option"), "default")
        self.session.set_plugin_option("testplugin", "another_option", "test")
        self.assertEqual(self.session.get_plugin_option("testplugin", "another_option"), "test")
        self.assertEqual(self.session.get_plugin_option("non_existing", "non_existing"), None)
        self.assertEqual(self.session.get_plugin_option("testplugin", "non_existing"), None)

    def test_plugin(self):
        channel = self.session.resolve_url("http://test.se/channel")
        streams = channel.get_streams()

        self.assertTrue("best" in streams)
        self.assertTrue("worst" in streams)
        self.assertTrue(streams["best"] is streams["1080p"])
        self.assertTrue(streams["worst"] is streams["350k"])
        self.assertTrue(isinstance(streams["rtmp"], RTMPStream))
        self.assertTrue(isinstance(streams["http"], HTTPStream))
        self.assertTrue(isinstance(streams["hls"], HLSStream))
        self.assertTrue(isinstance(streams["akamaihd"], AkamaiHDStream))

    def test_plugin_stream_types(self):
        channel = self.session.resolve_url("http://test.se/channel")
        streams = channel.get_streams(stream_types=["http", "rtmp"])

        self.assertTrue(isinstance(streams["480p"], HTTPStream))
        self.assertTrue(isinstance(streams["480p_rtmp"], RTMPStream))

        streams = channel.get_streams(stream_types=["rtmp", "http"])

        self.assertTrue(isinstance(streams["480p"], RTMPStream))
        self.assertTrue(isinstance(streams["480p_http"], HTTPStream))

    def test_plugin_stream_sorted_excludes(self):
        channel = self.session.resolve_url("http://test.se/channel")
        streams = channel.get_streams(sorting_excludes=["1080p", "3000k"])

        self.assertTrue("best" in streams)
        self.assertTrue("worst" in streams)
        self.assertTrue(streams["best"] is streams["1500k"])

        streams = channel.get_streams(sorting_excludes=[">=1080p", ">1500k"])
        self.assertTrue(streams["best"] is streams["1500k"])

        streams = channel.get_streams(sorting_excludes=lambda q: not q.endswith("p"))
        self.assertTrue(streams["best"] is streams["3000k"])

    def test_plugin_support(self):
        channel = self.session.resolve_url("http://test.se/channel")
        streams = channel.get_streams()

        self.assertTrue("support" in streams)
        self.assertTrue(isinstance(streams["support"], HTTPStream))
Exemple #28
0
class GreekStreamTVList(Screen):
    skin = """
         <screen name="GreekStreamTVList" position="center,center" size="560,430" title="GreekStreamTV list">
            <ePixmap pixmap="buttons/red.png" position="0,0" size="140,40" alphatest="on"/>
            <ePixmap pixmap="buttons/green.png" position="140,0" size="140,40" alphatest="on"/>
            <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1"/>
            <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1"/>
            <widget name="streamlist" position="10,50" size="540,320" zPosition="10" scrollbarMode="showOnDemand"/>
            <widget name="info" position="10,380" zPosition="2" size="540,35" font="Regular;22" transparent="1" halign="center" valign="center"/>
        </screen>"""

    def __init__(self, session, streamFile=None):
        Screen.__init__(self, session)
        self.setTitle(_("GreekStreamTV list"))
        self["info"] = Label("...")
        self["key_red"] = StaticText(_("Cancel"))
        self["key_green"] = StaticText(_("Play"))

        self["actions"] = ActionMap(["OkCancelActions", "WizardActions", "ColorActions"],
        {
            "ok"    : self.keyOK,
            "green" : self.keyOK,
            "cancel": self.keyCancel,
            "red"   : self.keyCancel,
            "up"    : self.keyUp,
            "down"  : self.keyDown,
            "left"  : self.keyLeft,
            "right" : self.keyRight,
        }, -1)

        self.streamBin  = "/usr/bin/rtmpdump"
        self.streamPipe = "/tmp/greekstreamtv.avi"

        if not streamFile:
            self.streamFile = resolveFilename(SCOPE_PLUGINS, "Extensions/GreekStreamTV/stream.xml")
        else:
            self.streamFile = streamFile

        self.lvstreamer = Livestreamer()

        self.streamList = []
        self.makeStreamList()
        self["streamlist"] = StreamList(self.streamList)

        self.onLayoutFinish.append(self.layoutFinished)

        self.beforeService  = None
        self.currentService = None
        self.playerStoped   = False
        self.keyLocked = False
        self.pd = None
        self.qsel = None

    def layoutFinished(self):
        os.system("killall -9 rtmpdump")
        self.showName()

    def keyLeft(self):
        if self.keyLocked:
            return
        self["streamlist"].pageUp()
        self.showName()

    def keyRight(self):
        if self.keyLocked:
            return
        self["streamlist"].pageDown()
        self.showName()

    def keyUp(self):
        if self.keyLocked:
            return
        self["streamlist"].up()
        self.showName()

    def keyDown(self):
        if self.keyLocked:
            return
        self["streamlist"].down()
        self.showName()

    def keyCancel(self):
        self.LivestreamerStop()
        if "/usr/lib/enigma2/python/Plugins/Extensions/GreekStreamTV" in path:
            path.remove("/usr/lib/enigma2/python/Plugins/Extensions/GreekStreamTV")
        self.close()

    def showName(self):
        try:
            tmpName = self["streamlist"].getCurrent()[1].get("name")
        except:
            tmpName = "..."
        self["info"].setText(tmpName)

    def keyOK(self):
        print "[GreekStreamTVList::keyOK]"
        if self.keyLocked:
            return

        uriName = self["streamlist"].getCurrent()[1].get("name")
        self["info"].setText(_("Starting %s\n\nPlease wait...") % uriName)
        self.timer = eTimer()
        self.timer.callback.append(self.StartStream)
        self.timer.start(100, 1)

    def StartStream(self):
        self.timer.stop()
        self.keyLocked      = True
        self.beforeService  = None
        self.currentService = None
        self.playerStoped   = False
        self.pd             = None

        streamInfo  = self["streamlist"].getCurrent()[1]
        uriInfo     = streamInfo.get("uri")
        typeInfo    = streamInfo.get("type").split(":")
        protocol    = typeInfo[0]
        serviceType = typeInfo[1]
        bufferSize  = typeInfo[2]
        url         = uriInfo.get("URL")

        if protocol == "rtmp":
            url += " "
            url += " ".join(["%s=%s" % (key, value) for (key, value) in uriInfo.items() if key != "URL"])
            url = " ".join(url.split())
            print "[GreekStreamTVList::keyOK] URL is ", url, " URI is ", uriInfo
            self.doStreamAction(url, serviceType, bufferSize)
        elif protocol in ("rtsp", "http"):
            self.doStreamAction(url, serviceType, bufferSize)
        elif protocol == "livestreamer":
            channel = None
            streams = None
            try:
                url += " "
                url += " ".join(["%s=%s" % (key, value) for (key, value) in uriInfo.items() if key != "URL"])
                url = " ".join(url.split())
                print "[GreekStreamTVList::keyOK] URL is ", url, " URI is ", uriInfo
                channel = self.lvstreamer.resolve_url(url)
                streams = channel.get_streams()
                print "[GreekStreamTVList::keyOK] Streams: ", streams.keys()
                print "[GreekStreamTVList::keyOK] Streams: ", streams.items()
                if len(streams) == 3 and "best" in streams and "worst" in streams:
                    self.streamPreBuffer(streams["best"])
                elif len(streams) == 0:
                    raise Exception("No Streams Found")
                else:
                    self.qsel = self.session.openWithCallback(self.QualitySelClosed, SelectQuality, streams, self.streamPreBuffer)
            except Exception as err:
                print "[GreekStreamTVList::keyOK::Exception] Error: ", err
                tmpMessage = _("An error occured: ") + str(err)[:200] + "..."
                self.session.openWithCallback(self.stopPlayer, MessageBox, tmpMessage, type=MessageBox.TYPE_ERROR, timeout=10)
        else:
            print "[GreekStreamTVList::keyOK] Unknown Protocol: ", protocol
            tmpMessage = _("Unknown protocol: ") + protocol
            self.session.openWithCallback(self.stopPlayer, MessageBox, tmpMessage, type=MessageBox.TYPE_WARNING, timeout=10)

    def QualitySelClosed(self, recursive):
        if self.qsel:
            self.qsel.close()
        self.qsel = None
        self.stopPlayer()

    def streamPreBuffer(self, stream):
        fd = None
        try:
            fd = stream.open()
            prebuffer = fd.read(8196 * 128) #PREBUFFER
            if len(prebuffer) == 0:
               raise Exception("No Data Received From Stream Server")
            start_new_thread(self.streamCopy, (fd,prebuffer))
            sleep(1.5)
            self.doStreamAction(self.streamPipe)
        except Exception as err:
            if fd and hasattr(fd, "close"):
                fd.close()
            print "[GreekStreamTVList::streamPreBuffer::Exception] Error: ", err
            tmpMessage = _("An error occured while buffering: ") + str(err)[:200] + "..."
            self.session.openWithCallback(self.stopPlayer, MessageBox, tmpMessage, type=MessageBox.TYPE_ERROR, timeout=10)

    def streamCopy(self, fd, prebuffer):
        print "[GreekStreamTVList::streamCopy]"
        if os.access(self.streamPipe, os.F_OK):
            os.remove(self.streamPipe)
        os.mkfifo(self.streamPipe)
        self.pd = open(self.streamPipe, "wb")
        try:
            self.pd.write(prebuffer)
            while self is not None and self.session is not None and not self.playerStoped:
                data = fd.read(8192)
                if len(data) == 0:
                    break
                self.pd.write(data)
            print "[GreekStreamTVList:streamCopy] playerStoped"
            self.pd.close()
            if hasattr(fd, "close"):
                fd.close()
            fd = None
        except Exception as err:
            print "[GreekStreamTVList::streamCopy] Exception: ", err
        finally:
            self.playerStoped = True
            if fd and hasattr(fd, "close"):
                fd.close()

    def LivestreamerStop(self):
        print "[GreekStreamTVList::LivestreamStop]"
        self.showName()
        self.keyLocked = False
        self.playerStoped = True
        os.system("killall -9 rtmpdump")
        sleep(0.5)
        if self.pd:
            try: self.pd.close()
            except:
                sleep(0.5)
                try: self.pd.close()
                except: pass
        if self.qsel is not None:
            self.qsel.close(False)
        self.pd   = None
        self.qsel = None

    def doStreamAction(self, url=None, serviceType=4097, bufferSize=None):
        if url is None:
            url=self.streamPipe
            self.streamPlayerTimer.stop()

        try: serviceType = int(serviceType)
        except: serviceType = 4097
        try: bufferSize = int(bufferSize)
        except: bufferSize = None

        service = eServiceReference(serviceType, 0, url)

        #if bufferSize is not None:
        #    service.setData(2, bufferSize*1024)

        streamInfo = self["streamlist"].getCurrent()[1]
        service.setName(str(streamInfo.get("name")))
        uriInfo    = streamInfo.get("uri")

        self.beforeService  = self.session.nav.getCurrentlyPlayingServiceReference()
        self.currentService = self.session.openWithCallback(self.onStreamFinished,
                                    GreekStreamTVPlayer,
                                    service,
                                    stopPlayer=self.stopPlayer,
                                    chName=str(streamInfo.get("name")),
                                    chURL =str(uriInfo.get("URL")),
                                    chIcon=str(streamInfo.get("icon")))

    def stopPlayer(self, params=None):
        print "[GreekStreamTV::stopPlayer]"
        if params is None or isinstance(params, bool):
            self.playerStoped = True
            self.LivestreamerStop()
            return

    def onStreamFinished(self):
        print "[GreekStreamTV::onStreamFinished]"
        self.LivestreamerStop()
        self.session.nav.playService(self.beforeService)
        print "[GreekStreamTV::onStreamFinished] player done!!"

    def makeStreamList(self):
        try: streamDB = StreamURIParser(self.streamFile).parseStreamList()
        except Exception as err:
            print "[GreekStreamTV::makeStreamList] Error: ", err
            streamDB = []
        self.streamList = [ (x.get("name"), x) for x in streamDB ]
Exemple #29
0
class StreamAnalysis(Thread):
    def __init__(self, timeList, eventList, worldmap):
        Thread.__init__(self)
        self._timeList = timeList
        self._eventList = eventList

        self._timeZero = 1392254560

        # set up templates as private variables for this class
        self._templatesTime = pickle.load(open('timeValues.data', 'rb'))
        self._templatesRed = pickle.load(open('redTemplates.data', 'rb'))
        self._templatesEvent = pickle.load(open('eventTemplates.data', 'rb'))

        self._worldmap = cv2.cvtColor(worldmap.copy(), cv2.COLOR_BGR2GRAY)

    def initStream(self):
        self._livestreamer = Livestreamer()
        self._plugin = self._livestreamer.resolve_url(
            'http://twitch.tv/twitchplayspokemon')

    def fetchStream(self):
        streams = self._plugin.get_streams()
        if 'source' in streams:
            return streams.get('source')

        return False

    def run(self):

        self.initStream()

        stream = self.fetchStream()
        while stream == False:
            print 'STREAM'
            time.sleep(60)
            print 'rechecking if stream is available'
            stream = self.fetchStream()

        #cap = cv2.VideoCapture( 'http://store22.media22.justin.tv/archives/2014-2-17/live_user_twitchplayspokemon_1392633446.flv' )
        cap = cv2.VideoCapture(stream.url)

        tmpTimeValues = []
        last_position = (-1, -1)

        while True:

            if not overridePosition == (-1, -1) and last_position == (-1, -1):
                last_position = overridePosition

            flag, frame = cap.read()

            if not flag:
                stream = self.fetchStream()
                cap = cv2.VideoCapture(stream.url)
                flag, frame = cap.read()

                if not flag:
                    break

            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            timeValues = self.getTimeValues(gray[81:119, 526:830])

            if timeValues == tmpTimeValues:
                continue

            tmpTimeValues = timeValues
            date = self.getDateFromTime(timeValues)
            if not 'day' in date or not 'hour' in date or not 'minute' in date or not 'second' in date:
                print 'error parsing date'
                continue

            timeStamp = self._timeZero + int(date['day']) * 24 * 60 * 60 + int(
                date['hour']) * 60 * 60 + int(date['minute']) * 60 + int(
                    date['second'])

            # crop to gameboy area
            crop = gray[24:457, 24:504]

            # find red (if not found with enough confidence it's "undefined")
            currentDirection = self.getRedDirection(crop[182:230, 194:233])
            if currentDirection == 'undefined':
                #self.newEntry(timeStamp, date, last_position)
                continue

            # check if there is currently an event open
            events = self.detectEvents(crop)
            if len(events) > 0 and not last_position == (-1, -1):
                #self.newEntry(timeStamp, date, last_position)
                self._eventList.append(events[0])
                continue

            # detect position on map

            # scale to world-map ratio
            # 480px -> 160px
            crop = cv2.resize(crop, (160, 144))

            # crop the worldmap image to a reasonable size, so we do not have to search so excessively
            # we can only do this if we have a starting position
            validationImage = self._worldmap
            left_corner = (0, 0)

            #cv2.imshow('crop', crop)
            #cv2.imshow('img', validationImage)
            #cv2.waitKey(0)

            if not last_position == (-1, -1):
                size = (500, 500)
                left_corner = (last_position[0] - size[0] / 2,
                               last_position[1] - size[1] / 2)
                validationImage = self._worldmap[
                    left_corner[1]:left_corner[1] + size[1],
                    left_corner[0]:left_corner[0] + size[0]]

                #cv2.imshow('crop', crop)
                #cv2.imshow('img', validationImage)
                #cv2.waitKey(0)

            # this should generally not happen, but if it does, we do not know where we are
            # so we're defaulting to the whole worldmap
            # TODO: THIS SHOULD BE REPLACED WITH -> DEFAULTING TO INDOOR MAPS!
            if validationImage.shape < crop.shape:
                validationImage = self._worldmap
                left_corner = (0, 0)

            res = cv2.matchTemplate(validationImage, crop,
                                    cv2.TM_CCOEFF_NORMED)
            w, h = crop.shape[::-1]
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

            # if we don't find something we're confident in, use the last position
            #if max_val < 0.5 and not last_position == (-1, -1):
            #  self.newEntry(timeStamp, date, last_position)
            #  continue

            # retry until we find a good first match
            if max_val < 0.8:
                validationImage = self._worldmap
                left_corner = (0, 0)

                res = cv2.matchTemplate(validationImage, crop,
                                        cv2.TM_CCOEFF_NORMED)
                w, h = crop.shape[::-1]
                min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

                print max_val
                if max_val < 0.7:
                    print 'hit low'
                    continue

            top_left = max_loc
            top_left = (top_left[0] + left_corner[0],
                        top_left[1] + left_corner[1])

            center = (top_left[0] + w / 2, top_left[1] + h / 2)
            bottom_right = (top_left[0] + w, top_left[1] + h)

            last_position = center
            self.newEntry(timeStamp, date, last_position)

            if len(self._timeList) > 20:
                self._timeList = []

    def getTimeValues(self, timeCrop):
        timeValues = []

        for key in self._templatesTime:
            template = self._templatesTime[key]
            w, h = template.shape[::-1]

            res = cv2.matchTemplate(timeCrop, template, cv2.TM_CCOEFF_NORMED)
            threshold = 0.9

            loc = numpy.where(res >= threshold)
            for pt in zip(*loc[::-1]):
                timeValues.append((pt[0], pt[1], key))

        timeValues.sort()
        return timeValues

    def getDateFromTime(self, timeValues):
        date = {}
        tmp = ''

        for timeValue in timeValues:
            key = timeValue[2]

            if key == 'd':
                date['day'] = tmp.zfill(2)
                tmp = ''

            elif key == 'h':
                date['hour'] = tmp.zfill(2)
                tmp = ''

            elif key == 'm':
                date['minute'] = tmp.zfill(2)
                tmp = ''

            elif key == 's':
                date['second'] = tmp.zfill(2)
                tmp = ''

            else:
                tmp = '{}{}'.format(tmp, key)

        return date

    def getRedDirection(self, redCrop):
        currentDirection = 'undefined'
        redCrop = cv2.resize(redCrop, (10, 10))

        for direction in self._templatesRed:
            template = self._templatesRed[direction]
            template = cv2.resize(template, (10, 10))

            res = cv2.matchTemplate(redCrop, template, cv2.TM_CCOEFF_NORMED)
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

            if max_val > 0.55:
                currentDirection = direction
                break

        return currentDirection

    def detectEvents(self, crop):
        eventValues = []

        detectionAreas = {}
        detectionAreas['moonstone'] = crop.copy()  # moonstone
        detectionAreas['dialogue'] = crop[293:435, 0:480]  # dialogue
        detectionAreas['optionsMenu'] = crop[3:388, 240:480]  # optionsMenu
        detectionAreas['naming'] = crop[98:360, 0:480]  # naming

        for key in self._templatesEvent:
            template = self._templatesEvent[key]
            area = detectionAreas[key]

            w, h = template.shape[::-1]
            if area.shape < template.shape:
                break

            res = cv2.matchTemplate(area, template, cv2.TM_CCOEFF_NORMED)
            threshold = 0.95

            loc = numpy.where(res >= threshold)
            for pt in zip(*loc[::-1]):
                _tuple = (pt[0], pt[1], key)
                if not _tuple in eventValues:
                    eventValues.append(_tuple)

            # currently there can only be one event at any given timespace
            if len(eventValues) > 0:
                break

        return eventValues

    def newEntry(self, timeStamp, date, position):
        _tuple = (timeStamp, date, position)

        # we are in a room without outsideworld reference
        # this could only happen, if we start recording inside a building right now
        if position == (-1, -1):
            print 'WHERE ARE WE?\r'
            return

        if not _tuple in self._timeList:
            self._timeList.append(_tuple)
            print '{}\t{},{}\r'.format(str(timeStamp), position[0],
                                       position[1]),

            with open('positionData.csv', 'a') as entryFile:
                line = '{};{};{};{};{};{};{}\n'.format(timeStamp, \
                                              date['day'], date['hour'], date['minute'], date['second'], \
                                              position[0], position[1])
                entryFile.write(line)

            with open('www/currentPosition', 'w') as _file:
                _file.write('{} {}'.format(position[0], position[1]))

            with open('www/currentTime', 'w') as _file:
                _file.write('{} {} {} {}'.format(date['day'], date['hour'],
                                                 date['minute'],
                                                 date['second']))
Exemple #30
0
def play_url():  # this only plays http urls for now, torrents soon.
    global title
    url = request.args.get('url')  # grab url from /play?url=*

    if not url.startswith('http'):  # in case the user forgot it
        log('url missing http/wrong protocol')
        url = 'http://' + url  # let's assume it's http, not https

    log('received url %s' % url)
    log('requesting headers from %s...' % url)
    req = Request(url)
    req.get_method = lambda: 'HEAD'  # only request headers, no content
    response = urlopen(req)
    ctype = response.headers['content-type']
    ctype_split = ctype.split('/')  # split into 2 parts
    log('headers received. content type is %s' % ctype)

    try:
        if ctype_split[0] == 'audio' or ctype_split[0] == 'video':
            log('url was raw media file, playing! :)')
            title = url  # i guess this works? :T
            play_omxplayer(url)
        elif ctype_split[1] == 'x-bittorrent':
            log('loading torrents not implemented.')
            # this isn't implemented yet.
        elif ctype_split[0] == 'text':
            # here we check if it's a livestream, and if so get the RTMP url
            log('checking if url is a livestream...')
            live = Livestreamer()
            try:
                if "youtube" in url:
                    raise RuntimeError(
                        "youtube is f****d up w/ streaming, falling back to youtube-dl"
                    )
                plugin = live.resolve_url(url)
                streams = plugin.get_streams()
                stream = streams.get(
                    "best")  # fingers crossed for best quality

                stream_url_types = ['rtmp', 'url'
                                    ]  # things that livestreamer can have :D
                for stream_type in stream_url_types:
                    if hasattr(stream, stream_type):
                        log('url is livestream!')
                        title = "%s (livestream)" % url
                        play_omxplayer(getattr(stream, stream_type))
                        return '', 204
            except (PluginError, RuntimeError
                    ) as e:  # therefore url is not (supported) livestream
                pass  # continue and let youtube-dl try.

            log('loading youtube-dl for further processing')
            ydl = YoutubeDL({
                'outtmpl': '%(id)s%(ext)s',
                'restrictfilenames': True
            })
            ydl.add_default_info_extractors()
            result = ydl.extract_info(url, download=False)
            if 'entries' in result:  # if video is a playlist
                video = result['entries'][
                    0]  # play the 1st video in the playlist
            else:
                video = result
            play_omxplayer(video['url'])
            title = video['title']
        else:
            raise DownloadError('Invalid filetype: not audio, video, or text.')

        return '', 204  # success w/ no response!
    except (UnicodeDecodeError, DownloadError) as e:
        return _ANSI_ESCAPE_REXP.sub('', str(e)), 400  # send error message
Exemple #31
0
class Main:
    def __init__(self):    
        self.gchoice = -1
        self.cchoice = -1    
        self.exit_now = False
        self.state = 'none'
        self.keybingings = {
            ord('q'):       self.quit,
            ord('f'):       self.get_favorites,
            ord('s'):       self.get_fav_games,
            ord('g'):       self.get_games,
            ord('n'):       self.get_next,
            ord('r'):       self.refresh,
            ord('p'):       self.get_previous            
        }
        
        self.games = []
        self.favs = []
        self.channels = []        
        self.twitch = Twitch(config.get('settings', 'twitchapiurl'), config.get('settings', 'channel'), config.get('settings', 'game'))
        self.livestreamer = Livestreamer()
        
        try:
            self.run()
        except Exception as e:
            print e.message
        
    def run(self):
        
        while True:            
            self.display_message()                                            
            if self.exit_now:
                return
    
    def quit(self, c):
        self.exit_now = True
        
    def display_message(self):
                               
        if self.state == 'none':
            clear_screen()                      
            self.handle_user_input('Choose an option : (F)avorites, (G)ame, (Q)uit')            
        
        if self.state == 'favs':
            clear_screen()            
            print 'Showing online favorites stream :'
            print '-' * 40
            if(len(self.favs) > 0):                            
                self.show_content(self.favs)            
                self.handle_user_input('Choose a channel by number (r to refresh, g to list by games and q to quit', range(len(self.favs) + 1))
                clear_screen()
            else:
                self.handle_user_input('No favorites channel online (r to refresh, g to list by games and q to quit', range(len(self.favs) + 1))
                clear_screen()            
                
        if self.state == 'games':
            clear_screen()            
            print 'Showing top %d games:' % config.getint('settings', 'game')
            print '-' * 40
            if(len(self.games) > 0):                            
                self.show_content(self.games)            
                self.gchoice = self.handle_user_input('Choose a game by number (r to refresh, f to check your favorite channels and q to quit', range(len(self.games) + 1))
                if self.gchoice != -1:
                    self.state = 'channels'
                    clear_screen()                                                 
                    
        if self.state == 'favgames':
            clear_screen()            
            print 'Showing favorites games:'
            print '-' * 40
            if(len(self.games) > 0):                        
                self.show_content(self.games)            
                self.gchoice = self.handle_user_input('Choose a game by number (r to refresh, f to check your favorite channels and q to quit', range(len(self.games) + 1))
                if self.gchoice != -1:
                    self.state = 'channels'
                    clear_screen()
        
        if self.state == 'channels':
            clear_screen()            
            print 'Showing top %d channel for %s:' % (config.getint('settings', 'channel'), self.games[self.gchoice - 1])
            print '-' * 40            
            self.get_channels(self.gchoice)
            if(len(self.channels) > 0):                            
                self.show_content(self.channels)            
                self.cchoice = self.handle_user_input('Choose a channel by number (r to refresh, f to check your favorite channels, g to reload game list and q to quit', range(len(self.channels) + 1))
                if self.cchoice != -1:
                    self.play_stream(self.channels[self.cchoice - 1])
                    self.state = 'channels'
                    clear_screen()
       
    def play_stream(self, channel):
        clear_screen()
        
        try:
            plugin = self.livestreamer.resolve_url(("twitch.tv/{0}").format(channel))
        except Exception as e:
            print e.message                   
        
        try:
            streams = plugin.get_streams()
        except PluginError as err:
            exit("Plugin error: {0}".format(err))
            
        quality = config.get('settings', 'quality')
        if quality not in streams:
            quality = "Source"
            print "Can't open streams with quality requested ({0}), opening best one".format(config.get('settings', 'quality'))
                        
        channel = transform_spaces(channel)
        if os.name == 'nt':
            os.system('livestreamer twitch.tv/%s %s' % (channel, quality))
            #os.system('livestreamer twitch.tv/%s best -p "%s"' % (channel, config.get('settings', 'player')))
        else:
            os.system('livestreamer twitch.tv/%s %s' % (channel, quality))
            #os.system('livestreamer twitch.tv/%s best -np "%s"' % (channel, config.get('settings', 'player')))
            
    def show_content(self, content):
        for i in range(len(content)):
            if i < 9:
                print '',
            if i < 99:
                print '',
            print '%d %s' % (i + 1, content[i])
            
    def handle_user_input(self, message, valid = None):
        self.state = 'none'
        validinput = False
        while not validinput:
            input = raw_input('%s\n ' % message)
            input = input.strip().lower()
            
            if input.isdigit():
                input = int(input)
                if input in valid:
                    validinput = True                    
                    return input
            elif len(input) == 1:
                c = ord(input)                
                f = self.keybingings.get(c, None)
                if f:
                    f(c)
                    validinput = True                    
                    return -1
            
        
    def get_favorites(self, c):
        self.state = 'favs'
        del self.favs[:]
        try:
            response = self.twitch.get_favorites_streams_status(config.get('settings', 'favorites'))
            receivedcount = len(response['streams'])
            
            for i in range(receivedcount):
                self.favs.append('%s playing: %s' % (response['streams'][i]['channel']['name'], response['streams'][i]['game']))
                
        except Exception as e:
            print 'Error getting favs streams!\n'
            print e.message
            return 0
        
    def get_games(self, c):        
        self.state = 'games'
        del self.games[:]
        try:
            response = self.twitch.get_game_list()
            receivedcount = len(response['top'])
            
            for i in range(receivedcount):
                self.games.append(response['top'][i]['game']['name'])
                
        except Exception as e:
            print 'Error getting games !\n'
            print e.message
            return 0
        
    def get_fav_games(self, c):
        self.state = 'favgames'
        del self.games[:]
        
        favgames = config.get('settings', 'favgames')
        if len(favgames) > 0:
            self.games.extend(favgames.split(', '))                        
        
    def get_channels(self, choice):
        self.state = 'channels'
        del self.channels[:]
        try:
            response = self.twitch.get_channel_for_game(transform_spaces(self.games[self.gchoice - 1]))
            receivedcount = len(response['streams'])
            
            for i in range(receivedcount):
                self.channels.append('%s (%s)' % (response['streams'][i]['channel']['name'], response['streams'][i]['viewers']))
                
        except Exception as e:
            print 'Error getting games !\n'
            print e.message
            return 0        
        
    def refresh(self, c):
        print 'tmp'
        
    def get_next(self, c):
        print 'tmp'
        
    def get_previous(self, c):
        print 'tmp'