def prepareNGetQuality(req, state): # print(req.getDict()) segId = req.nextChunkId - 1 timeSpent = req.lastChunkFinishTime - req.lastChunkStartTime chunkLen = req.lastChunkSize throughput = 1000 if timeSpent <= 0 else chunkLen * 8 * 1000 / timeSpent sobj = getObj({ "qualityIndex": req.lastquality, "throughput": throughput, "segId": segId, "chunkLen": chunkLen, "timeSpent": timeSpent, }) #need to change so that it can be squeeze state.bufferUpto = segId * state.segmentDuration avaliableBuf = round(req.buffer * 1000, 3) state.playBackTime = (state.bufferUpto - avaliableBuf) if state.segmentDetails is None: state.segmentDetails = {} state.segmentDetails[segId] = sobj nextSegId = req.nextChunkId requests = [ state.segmentDetails[i] for i in range(nextSegId - NUM_HISTORIES, nextSegId) if i >= 0 ] stall = req.rebufferTime agent = getObj( requests=requests, #place last 10 segs bufferUpto=state.bufferUpto / 1000, playBackTime=state.playBackTime / 1000, maxPlayerBufferLen=state.maxBuf / 1000, avaliableBuf=(avaliableBuf) / 1000, startingPlaybackTime=0, segCount=nextSegId, getChunkSize=getChunkSize, agentState=state.agentState, rebufferTime=stall, segDur=state.segmentDuration, stateless=True, ) # print(agent) abr = ABRS[state.abr] if options.abr_log is not None: with open(options.abr_log, "a") as fp: print(nestedObject.getJson([state.vidInfo, agent]), file=fp) retObj = abr.getNextQuality(state.vidInfo, agent, True) state.agentState = retObj.abrState if int(retObj.repId) >= len(state.vidInfo.bitrates): print("Error!!", retObj.errors) if options.log is not None: with open(options.log, "a") as fp: print(segId, req.rebufferTime / 1000, req.lastquality, file=fp) return int(retObj.repId)
def prepareVideoPlayer(loc, vid): global videoPlayer with open(os.path.join(loc, vid + ".json")) as fp: data = json.load(fp) data['vidInfo']['segmentCount'] = min(len(data["sizes"]["video"]), math.ceil(data['vidInfo']['duration']/data['vidInfo']['segmentDuration'])) videoPlayer = getObj(data) pass
def getNextQuality(self, vidInfo, agent, agentState): nextChunkSizes = [agent.getChunkSize(i, agent.segCount) for i, _ in enumerate(vidInfo.bitrates)] lastQuality = agent.requests[-1]["qualityIndex"] lastBitrate = vidInfo.bitrates[lastQuality]/ vidInfo.bitrates[-1] lastThroughput = agent.requests[-1]["throughput"] lastTimeTaken = agent.requests[-1]["timeSpent"] bufferUpto = agent.bufferUpto playBackTime = agent.playBackTime maxPlayerBufferLen = agent.maxPlayerBufferLen bufferLeft = (maxPlayerBufferLen - (bufferUpto - playBackTime)) state = (lastBitrate, bufferLeft, lastThroughput, lastTimeTaken, nextChunkSizes) qualityState = agentState.getattr("qualityState", None) if qualityState is None: qualityState = getObj(s_batch = []) res, error = self.pensieveQualityLearner.getNextAction(qualityState, state) if res is not None: ql, qualityState = res cprint.orange("!!PREDICTED QUALITY!!!", ql) else: retObj = BOLA.getNextQuality(vidInfo, agent) ##proxy ql = retObj.repId return ql, qualityState, error
def handle(self): data = self.request.recv(4, socket.MSG_WAITALL) l = struct.unpack("=I", data)[0] moreData = self.request.recv(l, socket.MSG_WAITALL) vidInfo, agent, agentState = pickle.loads(moreData) retObj = getObj( repId = len(vidInfo.bitrates), abrState = agentState, errors = None ) try: retObj = self.server.abrObject.getNextAction(vidInfo, agent, agentState) except Exception as err: track = tb.format_exc() # print(track) errors = track retObj.setattrs(errors=errors) # tb.print_exception() pass sndData = pickle.dumps(retObj) l = len(sndData) dt = struct.pack("=I", l) self.request.send(dt) self.request.send(sndData)
def getNextQuality(vidInfo, agent, minimalState=False): agentState = agent.agentState if agentState is None or len(agent.requests) == 0: agentState = getObj( lastBitrate=0, lastTotalRebuf=0, s_batch=[np.zeros((S_INFO, S_LEN))], ) return getObj( sleepTime = 0, \ repId = 0, \ abrState = agentState, \ errors = None, \ ) connected = False sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) for x in range(3): try: sock.connect(SOCKET_PATH) connected = True break except FileNotFoundError: pass except ConnectionRefusedError: pass startServerInFork(len(vidInfo.bitrates)) if not connected: return getObj( sleepTime = -1, \ repId = 0, \ abrState = agentState, \ errors = None, \ ) # cprint.green(agentState) ql, state, errors = getNextQualityFromServer(sock, vidInfo, agent, agentState, minimalState) return getObj( sleepTime = -1, \ repId = ql, \ abrState = state, \ errors = errors, \ )
def getNextQuality(vidInfo, agent, minimalState=False): sl, M = 0, -1 errors = None try: sl, M = getNextQualityBola(vidInfo, agent) except Exception as err: track = tb.format_exc() print(track) errors = track return getObj(sleepTime = sl, repId = M, abrState = None, errors = errors)
def getNextQuality(vidInfo, agent, minimalState=False): #assert not minimalState agentState = agent.agentState if agentState is None or len(agent.requests) == 0: agentState = getObj( lastBitrate = 0, lastTotalRebuf = 0, ) return getObj( \ abrState = agentState, repId = 0, errors = None, ) connected = False sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) for x in range(3): try: sock.connect(SOCKET_PATH) connected = True break except FileNotFoundError: pass except ConnectionRefusedError: pass startServerInFork(len(vidInfo.bitrates)) if not connected: return getObj( sleepTime = -1, \ repId = 0, \ abrState = agentState, \ errors = None, \ ) cprint.green("results from EnDash") retObj = getNextQualityFromServer(sock, vidInfo, agent, agentState) return retObj
def prepareState(): return getObj( segmentDetails=None, bufferUpto=0, playBackTime=0, maxBuf=30 * 1000, agentState=None, stall=0, segmentDuration=videoPlayer.vidInfo.segmentDuration * 1000, vidInfo=videoPlayer.vidInfo, abr=options.abr, )
def getNextQuality(vidInfo, agent, minimalState=False): agentState = agent.agentState if agentState is None or len(agent.requests) == 0: agentState = getObj( lastBitrate = 0, lastTotalRebuf = 0, segId = 0, ) return getObj( sleepTime = 0, \ repId = 0, \ abrState = agentState, \ errors = None, \ ) ql, state, errors = getNextQualityUsingFast(vidInfo, agent, agentState, minimalState) return getObj( sleepTime = -1, \ repId = ql, \ abrState = state, \ errors = errors, \ )
def do_POST(self): l = int(self.headers.get("Content-Length", 0)) if l == 0: print("Content len 0, returning") return #send error indata = self.rfile.read(l) req = getObj(json.loads(indata)) data = b"REFRESH" print(req.getDict()) if req.cookie is None: clientIp, clientPort = self.client_address clientIp = self.headers.get("X-Forwarded-For", clientIp) clientIp = clientIp.replace(":", "^") serverKey = "{}_{}_{}".format(time.time(), clientIp, clientPort) req.cookie = serverKey # state = prepareState() if req.cookie not in states: states.setdefault(req.cookie, {})[req.nextChunkId - 1] = prepareState() if req.cookie in states: state = copy.deepcopy(states[req.cookie][req.nextChunkId - 1]) res = prepareNGetQuality(req, state) states.setdefault(req.cookie, {})[req.nextChunkId] = state data = { "quality": res, "cookie": req.cookie, "sizes": getNextSizes(req.nextChunkId), "lastSeg": videoPlayer.vidInfo.segmentCount - 1 == req.nextChunkId, "segmentDuration": state.segmentDuration * 1000 #us } data = json.dumps(data).encode() self.send_response(200) self.send_header("Content-type", "text/plain") self.send_header("Content-Length", len(data)) self.send_header("Access-Control-Allow-Origin", "*") self.send_header("X-Cookie", req.cookie) self.end_headers() self.wfile.write(data)
def getAdjustBuffer(self, vidInfo, agent, agentState, predictedThroughput, maxPlayerBufferLen): nextChunkSizes = [agent.getChunkSize(i, agent.segCount) for i, _ in enumerate(vidInfo.bitrates)] lastQuality = agent.requests[-1]["qualityIndex"] lastBitrate = vidInfo.bitrates[lastQuality]/ vidInfo.bitrates[-1] lastThroughput = agent.requests[-1]["throughput"] lastTimeTaken = agent.requests[-1]["timeSpent"] bufferUpto = agent.bufferUpto playBackTime = agent.playBackTime bufferLeft = (maxPlayerBufferLen - (bufferUpto - playBackTime)) state = (lastBitrate, bufferLeft, lastThroughput, lastTimeTaken, nextChunkSizes, predictedThroughput) bufferState = agentState.getattr("bufferState", None) if bufferState is None: bufferState = getObj(s_batch = []) res, error = self.pensieveBufferLearner.getNextAction(bufferState, state) if res is not None: ba, bufferState = res cprint.orange("!!PREDICTED BUFFER_ACTION!!!", ba) return ba, bufferState, error return 0, bufferState, error
def getNextAction(self, vidInfo, agent, agentState): ql, qualityState, qualityError = self.getNextQuality(vidInfo, agent, agentState) state = getObj( qualityState = qualityState, ) errors = getObj( qualityError = qualityError, ) retObj = getObj( sleepTime = -1, \ repId = ql, \ abrState = state, \ errors = errors, \ ) p = {x[0]:x[1:] for x in agent.cellDatas} currData = None try: currData = pd.DataFrame(p) except Exception as e: cprint.orange("pd", e) return retObj if len(currData) <= 0: return retObj dataOffset = 0 predictedThroughput = -1 ba = 0 bufferStates = [] bufferErrors = [] currData["throughput"] /= 8 nextBuf = agent.maxPlayerBufferLen segDur = agent.segDur #this is another test. might not right but have to to take the risk while dataOffset + 20 <= len(currData): tmpData = currData[dataOffset : dataOffset + 20] cprint.blueS() try: predictedThroughput = self.predict_throughput(tmpData) baTmp, bufferState, bufferError = self.getAdjustBuffer(vidInfo, agent, agentState, predictedThroughput, nextBuf) bufferStates.append(bufferState) bufferErrors.append(bufferError) nextBuf += baTmp * segDur if nextBuf < segDur: nextBuf = segDur if nextBuf > 100*1000: nextBuf = 100*1000 ba += baTmp except Exception as e: track = tb.format_exc() throughputError = track errors.throughputError = throughputError retObj.errors = errors cprint.red(track) cprint.reset() dataOffset += 20 cprint.orange("!!!PREDICTED THROUGHPUT!!!", predictedThroughput) # assert dataOffset <= 20 if predictedThroughput < 0: return retObj state.bufferState = bufferStates errors.bufferError = bufferErrors retObj.adjustBuffer = ba retObj.dataProcessed = dataOffset retObj.abrState = state retObj.errors = errors return retObj