예제 #1
0
 def _get_usecase_status(self, name, usecase):
     zk_usecase_path = zk_prefix + "/" + name + "/" + usecase
     zk = ZKData()
     enable = zk.get(zk_usecase_path)
     zk.close()
     if enable == {}:
         return 0
     return enable
예제 #2
0
 def _get_bench_mode(self, name):
     zk_benchmode_path = zk_prefix + "/" + name + "/" + "benchmode"
     zk = ZKData()
     enable = zk.get(zk_benchmode_path)
     zk.close()
     if enable == {}:
         return 0
     return enable
예제 #3
0
    async def get(self):
        stream = self.request.uri.replace("/manifest/", "")
        print("stream : " + stream, 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:
        #    self.set_header('X-Accel-Redirect','/adinsert/' + stream)
        #    self.set_status(200,'OK')
        #    return

        # Retrive the manifest from upstream.
        try:
            manifest = await self._fetch_manifest(content_provider_url + "/" +
                                                  stream)
        except Exception as e:
            print(str(e))
            self.set_status(500, str(e))
            return

        # launch zk
        stream_base = "/".join(stream.split("/")[:-1])
        zk_path = zk_prefix + "/" + stream_base

        # Parse manifest
        minfo = {"segs": {}, "streams": {}, "manifest": ""}
        ad_spec = {
            "prefix": "adstream/" + user,
            "path": ad_storage_root + "/" + stream_base,
            "interval": [4],  # ad interval (#segments)
            "duration": [5],  # ad duration
        }
        if stream.endswith(".m3u8"):
            zk = ZKData()
            minfo = parse_hls(
                stream_cp_url=content_provider_url + "/" + stream,
                m3u8=manifest,
                stream_info=zk.get(zk_path + "/" + stream.split("/")[-1]),
                ad_spec=ad_spec,
            )
            zk.close()
        if stream.endswith(".mpd"):
            minfo = parse_dash(
                stream_cp_url=content_provider_url + "/" + stream,
                mpd=manifest,
                ad_spec=ad_spec,
            )

        # set zk states
        self.executor.submit(self._set_states, minfo, zk_path, stream_base,
                             user)

        # return the manifest
        self.write(minfo["manifest"])
        self.set_header('content-type', minfo["content-type"])
예제 #4
0
 def _set_states(self, minfo, zk_path, stream_base, user):
     zk = ZKData()
     if minfo["streams"]:
         for stream1 in minfo["streams"]:
             zk.set(zk_path + "/" + stream1, minfo["streams"][stream1])
     if minfo["segs"]:
         for seg in minfo["segs"]:
             zk.set(zk_path + "/" + user + "/" + seg, minfo["segs"][seg])
     zk.close()
예제 #5
0
    def _get_manifest(self, stream, user):
        # Retrive the manifest from upstream.
        try:
            r = requests.get(content_provider_url + "/" + stream)
            r.raise_for_status()
            manifest = r.text
        except Exception as e:
            print("Exception: " + str(e), flush=True)
            return str(e)

        # launch zk
        stream_base = "/".join(stream.split("/")[:-1])
        zk_path = zk_manifest_prefix + "/" + stream_base

        # Parse manifest
        minfo = {"segs": {}, "streams": {}, "manifest": ""}
        ad_spec = {
            "prefix": "adstream/" + user,
            "path": ad_storage_root + "/" + stream_base,
            "interval": ad_interval,  # ad interval (#segments)
            "duration": ad_duration,  # ad duration
            "analytic_ahead": ad_analytic_ahead,
            "transcode_ahead": ad_transcode_ahead,
        }

        zk = ZKData()
        if stream.endswith(".m3u8"):
            minfo = parse_hls(
                stream_cp_url=content_provider_url + "/" + stream,
                m3u8=manifest,
                stream_info=zk.get(zk_path + "/" + stream.split("/")[-1]),
                ad_spec=ad_spec,
                ad_segment=ad_segment)
        if stream.endswith(".mpd"):
            minfo = parse_dash(stream_cp_url=content_provider_url + "/" +
                               stream,
                               mpd=manifest,
                               ad_spec=ad_spec,
                               ad_segment=ad_segment)

        # set zk states
        if minfo["streams"]:
            for stream1 in minfo["streams"]:
                zk.set(zk_path + "/" + stream1, minfo["streams"][stream1])
        if minfo["segs"]:
            for seg in minfo["segs"]:
                zk.set(zk_path + "/" + user + "/" + seg, minfo["segs"][seg])

        zk.close()
        return minfo
예제 #6
0
 def post(self):
     name = str(self.get_argument("name"))
     enable = int(self.get_argument("enable"))
     zk_benchmode_path = zk_prefix + "/" + name + "/" + "benchmode"
     zk = ZKData()
     zk.set(zk_benchmode_path, enable)
     zk.close()
예제 #7
0
    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')
예제 #8
0
    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))
예제 #9
0
def set_ad_path(path, value):
    zkd = ZKData()
    zkd.set(path, value)
    print("set " + path + " to " + value, flush=True)
    zkd.close()
예제 #10
0
 def _set_usecase_status(self, name, usecase, value):
     zk_usecase_path = zk_prefix + "/" + name + "/" + usecase
     zk = ZKData()
     zk.set(zk_usecase_path, value)
     zk.close()