Esempio n. 1
0
class SegmentHandler(web.RequestHandler):
    def __init__(self, app, request, **kwargs):
        super(SegmentHandler, self).__init__(app, request, **kwargs)
        self._sch=Schedule()
        self._usecase={"obj_detection":1, "emotion":0, "face_recognition":0}

    def check_origin(self, origin):
        return True

    def _get_usecase_status(self, name, usecase):
        zk_usecase_path=zk_prefix+"/"+name +"/"+usecase
        zk=ZKMData()
        enable=zk.get(zk_usecase_path)
        zk.close()
        if enable == {}:
            return 0
        return enable

    def _set_usecase_status(self, name, usecase, value):
        zk_usecase_path=zk_prefix+"/"+name +"/"+usecase
        zk=ZKMData()
        zk.set(zk_usecase_path,value)
        zk.close()

    @gen.coroutine
    def get(self):
        stream = self.request.uri.replace("/segment/","")
        stream_base = "/".join(stream.split("/")[:-1])
        print("stream: "+stream, flush=True)
        print("stream_base: "+stream_base, flush=True)
        user = self.request.headers.get('X-USER')
        if not user: 
            self.set_status(400, "X-USER missing in headers")
            return

        # Redirect if this is an AD stream.
        if stream.find("/adstream/") != -1:
            start_time=time.time()
            while time.time()-start_time<=60: # wait if AD is not ready
                print("Testing "+ad_storage_path+"/"+stream, flush=True)
                if isfile(ad_storage_path+"/"+stream):
                    if stream.startswith("hls/"):
                        m1=re.search(".*/(.*)_[0-9]+.ts",stream)
                        if m1:
                            testfile=ad_storage_path+"/"+stream_base+"/"+m1.group(1)+".m3u8.complete"
                            print("Testing "+testfile, flush=True)
                            if isfile(testfile): 
                                self.add_header('X-Accel-Redirect','/adinsert/'+stream)
                                self.set_status(200,'OK')
                                return
                    if stream.startswith("dash/"):
                        m1=re.search(".*/(.*)-(chunk|init).*",stream)
                        if m1:
                            testfile=ad_storage_path+"/"+stream_base+"/"+m1.group(1)+".mpd.complete"
                            print("Testing "+testfile, flush=True)
                            if isfile(testfile): 
                                self.add_header('X-Accel-Redirect','/adinsert/'+stream)
                                self.set_status(200,'OK')
                                return
                yield gen.sleep(0.5)

            self.set_status(404, "AD not ready")
            return

        # Forward the media file request to content provider
        print("Redirecting to /intercept/"+stream, flush=True)
        self.set_header('X-Accel-Redirect','/intercept/' + stream)

        # get zk data for additional scheduling instruction
        zk=ZKData()
        seg_info=zk.get(zk_prefix+"/"+stream_base+"/"+user+"/"+stream.split("/")[-1])
        zk.close()
        if not seg_info: return

        # schedule ad
        if "transcode" in seg_info:
            self._sch.transcode(user, seg_info)
            self._sch.flush()

        # schedule analytics
        if "analytics" in seg_info:
            flag=0
            for usecase in ["obj_detection", "emotion", "face_recognition"]:
                self._usecase[usecase]=self._get_usecase_status(user,usecase)
                flag += self._usecase[usecase]
            if flag == 0:
                self._set_usecase_status(user,"obj_detection",1)
                self._usecase["obj_detection"]=1

            if self._usecase["obj_detection"]==1:
                self._sch.analyze(seg_info, "object_detection")
            if self._usecase["emotion"]==1:
                self._sch.analyze(seg_info, "emotion_recognition")
            if self._usecase["face_recognition"] == 1:
                self._sch.analyze(seg_info, "face_recognition")
            self._sch.flush()

            # delay releasing the stream to combat player caching.
            if "seg_duration" in seg_info and seg_info["seg_time"]:
                yield gen.sleep(max(0,seg_info["seg_duration"]-1.5))

    @gen.coroutine
    def post(self):
        name=str(self.get_argument("name"))
        casename=str(self.get_argument("casename"))
        enable=int(self.get_argument("enable"))
        if casename in ["obj_detection", "emotion", "face_recognition"]:
            self._set_usecase_status(name, casename, enable)
        for usecase in ["obj_detection", "emotion", "face_recognition"]:
            self._usecase[usecase]=self._get_usecase_status(name,usecase)
Esempio n. 2
0
class SegmentHandler(web.RequestHandler):
    def __init__(self, app, request, **kwargs):
        super(SegmentHandler, self).__init__(app, request, **kwargs)
        self._sch = Schedule()
        self.executor = ThreadPoolExecutor()
        self._ads = [
            x for x in os.listdir("/var/www" + ad_static)
            if os.path.isdir("/var/www" + ad_static + "/" + x)
        ]
        random.seed()

    def check_origin(self, origin):
        return True

    @run_on_executor
    def _get_segment(self, zk, stream, user, algos):
        stream_base = "/".join(stream.split("/")[:-1])
        segment = stream.split("/")[-1]
        print("stream: " + stream, flush=True)
        print("stream_base: " + stream_base, flush=True)
        print("segment: " + segment, flush=True)

        # Redirect if this is an AD stream
        if stream.find("/adstream/") != -1:
            zk_path = zk_segment_prefix + "/" + stream_base + "/link"
            print("get prefix from " + zk_path, flush=True)
            prefix = zk.get(zk_path)
            print(prefix, flush=True)
            if not prefix:
                zk_path1 = zk_segment_prefix + "/" + stream_base + "/backoff"
                prefix = ad_static
                try:
                    backoff = zk.get(zk_path1)
                    if not backoff: backoff = ad_backoff
                    if int(backoff) > 0:
                        zk.set(zk_path1, str(int(backoff) - 1))
                        return None
                except:
                    print(traceback.format_exc(), flush=True)
            if prefix == ad_static:
                prefix = prefix + "/" + self._ads[random.randint(
                    0,
                    len(self._ads) - 1)]
            return prefix + "/" + segment

        # get zk data for additional scheduling instruction
        seg_info = zk.get(zk_manifest_prefix + "/" + stream_base + "/" + user +
                          "/" + segment)
        if seg_info:
            # schedule ad
            if "transcode" in seg_info:
                self._sch.transcode(user, seg_info)

            # schedule analytics
            if "analytics" in seg_info:
                if algos.find("object") >= 0:
                    self._sch.analyze(user, seg_info, "object_detection")
                if algos.find("emotion") >= 0:
                    self._sch.analyze(user, seg_info, "emotion_recognition")
                if algos.find("face") >= 0:
                    self._sch.analyze(user, seg_info, "face_recognition")

            if "analytics" in seg_info or "transcode" in seg_info:
                self._sch.flush()

        # redirect to get the media stream
        return '/intercept/' + stream

    @gen.coroutine
    def get(self):
        stream = self.request.uri.replace("/segment/", "")
        user = self.request.headers.get('X-USER')
        if not user:
            self.set_status(400, "X-USER missing in headers")
            return
        algos = self.request.headers.get('X-ALGO')
        print("ALGOS: " + algos, flush=True)
        if not algos:
            self.set_status(400, "X-ALGO missing in headers")

        zk = ZKData()
        redirect = yield self._get_segment(zk, stream, user, algos)
        zk.close()

        if redirect is None:
            print("Status: 404, AD not ready", flush=True)
            self.set_status(404, "AD not ready")
        else:
            print("X-Accel-Redirect: " + redirect, flush=True)
            if stream.find("/adstream/") != -1:
                self.add_header('Content-Cache', 'no-cache')
            self.add_header('X-Accel-Redirect', redirect)
            self.set_status(200, 'OK')