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)
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')