def ft_mpd_parser(retry_srv, retry_num, video_name): error_num = 0 rsts = '' while (not rsts) and (error_num < retry_num): rsts = mpd_parser(retry_srv, video_name) error_num += 1 return rsts
def cqas_dash(cache_agent, server_addrs, candidates, port, videoName, clientID, alpha): # Initialize servers' qoe cache_agent_ip = server_addrs[cache_agent] qoe_vector = query_QoE(cache_agent_ip, port) server_qoes = get_server_QoE(qoe_vector, server_addrs, candidates) # Selecting a server with maximum QoE selected_srv = max(server_qoes.iteritems(), key=itemgetter(1))[0] pre_selected_srv = selected_srv selected_srv_ip = server_addrs[selected_srv] rsts = mpd_parser(selected_srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {}
def ant_dash(cache_agent, server_addrs, candidates, port, videoName, clientID, alpha): # Initialize servers' qoe cache_agent_ip = server_addrs[cache_agent] qoe_vector = query_QoE(cache_agent_ip, port) server_qoes = get_server_QoE(qoe_vector, server_addrs, candidates) print "Server QoE evaluations: ", server_qoes # Selecting a server with maximum QoE selected_srv = select_ant_srv(server_qoes) selected_srv_ip = server_addrs[selected_srv] rsts = mpd_parser(selected_srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) else: audioID = rep audioInit = reps[rep]['initialization'] start = reps[rep]['start'] audioName = reps[rep]['name'] sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) # Start downloading video and audio chunks curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[CQAS-DASH] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp( int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") print "[CQAS-DASH] Selected server for next 5 chunks is :" + selected_srv vchunk_sz = download_chunk(selected_srv_ip, videoName, vidInit) startTS = time.time() print "[CQAS-DASH] Start playing video at " + datetime.datetime.fromtimestamp( int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen ## Traces to write out client_tr = {} srv_qoe_tr = {} while (chunkNext * chunkLen < vidLength): nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time() vchunk_sz = download_chunk(selected_srv_ip, videoName, vidChunk) curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) # Update QoE evaluations on local client server_qoes[selected_srv] = server_qoes[selected_srv] * ( 1 - alpha) + alpha * chunk_QoE print "|---", str(int(curTS)), "---|---", str( chunkNext), "---|---", nextRep, "---|---", str( chunk_QoE), "---|---", str(curBuffer), "---|---", str( freezingTime), "---|---", selected_srv, "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, Freezing=freezingTime, Server=selected_srv, Response=rsp_time) srv_qoe_tr[chunkNext] = server_qoes # Count Previous QoE average if chunkNext % 5 == 0 and chunkNext > 4: mnQoE = averageQoE(client_tr, selected_srv) qoe_vector = update_QoE(cache_agent_ip, port, mnQoE, selected_srv) server_qoes = get_server_QoE(qoe_vector, server_addrs, candidates) print "[ANT-DASH] Received Server QoE is :" + json.dumps( server_qoes) print "[ANT-DASH] Selected server for next 5 chunks is :" + selected_srv # Selecting a server with probability proportional to server QoE selected_srv = select_ant_srv(server_qoes) selected_srv_ip = server_addrs[selected_srv] # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 trFileName = "./data/" + clientID + "_" + videoName + ".json" with open(trFileName, 'w') as outfile: json.dump(client_tr, outfile, sort_keys=True, indent=4, ensure_ascii=False) srv_qoe_tr_filename = "./data/" + clientID + "_" + videoName + "_srvqoe.json" with open(srv_qoe_tr_filename, 'w') as outfile: json.dump(srv_qoe_tr, outfile, sort_keys=True, indent=4, ensure_ascii=False) shutil.rmtree('./tmp') return client_tr
def cqas_dash(cache_agent, server_addrs, candidates, port, videoName, clientID, alpha): # Initialize servers' qoe cache_agent_ip = server_addrs[cache_agent] qoe_vector = query_QoE(cache_agent_ip, port) server_qoes = get_server_QoE(qoe_vector, server_addrs, candidates) # Selecting a server with maximum QoE selected_srv = max(server_qoes.iteritems(), key=itemgetter(1))[0] pre_selected_srv = selected_srv selected_srv_ip = server_addrs[selected_srv] rsts = mpd_parser(selected_srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {} good_chunks = {} for c in candidates: good_chunks[c] = 0 for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) else: audioID = rep audioInit = reps[rep]['initialization'] start = reps[rep]['start'] audioName = reps[rep]['name'] sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) # Start downloading video and audio chunks curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[CQAS-DASH] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp(int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") print "[CQAS-DASH] Selected server for next 5 chunks is :" + selected_srv vchunk_sz = download_chunk(selected_srv_ip, videoName, vidInit) startTS = time.time() print "[CQAS-DASH] Start playing video at " + datetime.datetime.fromtimestamp(int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen ## Traces to write out client_tr = {} srv_qoe_tr = {} while (chunkNext * chunkLen < vidLength) : nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) # Greedily increase the bitrate because server is switched to a better one if (pre_selected_srv != selected_srv): prob = good_chunks[selected_srv] / float(vidLength/chunkLen) rnd = random.random() ## Probabilistic switching if rnd < prob: print "[CQAS-DASH] Stick with the previous server! The probability is : " + str(prob) selected_srv = pre_selected_srv else: print "[CQAS-DASH]Switch server! The probability is : " + str(prob) nextRep = increaseRep(sortedVids, nextRep) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time(); vchunk_sz = download_chunk(selected_srv_ip, videoName, vidChunk) curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 # print "[AGENP] Client freezes for " + str(freezingTime) else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) # print "[AGENP] Current QoE for chunk #" + str(chunkNext) + " is " + str(chunk_QoE) # Update QoE evaluations on local client server_qoes[selected_srv] = server_qoes[selected_srv] * (1 - alpha) + alpha * chunk_QoE print "|---", str(int(curTS)), "---|---", str(chunkNext), "---|---", nextRep, "---|---", str(chunk_QoE), "---|---", str(curBuffer), "---|---", str(freezingTime), "---|---", selected_srv, "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, Freezing=freezingTime, Server=selected_srv, Response=rsp_time) srv_qoe_tr[chunkNext] = server_qoes if chunk_QoE > 4.0: good_chunks[selected_srv] = good_chunks[selected_srv] + 1 # Count Previous QoE average if chunkNext%10 == 0 and chunkNext > 4: # mnQoE = averageQoE(client_tr, selected_srv) ## qoe_vector = update_QoE(cache_agent_ip, mnQoE, selected_srv) qoe_vector = update_srv_QoEs(cache_agent_ip, port, server_qoes) server_qoes = get_server_QoE(qoe_vector, server_addrs, candidates) print "[CQAS-DASH] Received Server QoE is :" + json.dumps(server_qoes) print "[CQAS-DASH] Selected server for next 10 chunks is :" + selected_srv # Selecting a server with maximum QoE if chunkNext > 4: # Selecting a server with maximum QoE pre_selected_srv = selected_srv selected_srv = max(server_qoes.iteritems(), key=itemgetter(1))[0] selected_srv_ip = server_addrs[selected_srv] print "[CQAS-DASH] Update Server QoEs ar :" + json.dumps(server_qoes) # print "[AGENP] Selected server for next 10 chunks is :" + selected_srv # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 # trFileName = "./data/" + clientID + "_" + videoName + "_" + str(time.time()) + ".json" ## Writer out traces files and upload to google cloud trFileName = "./data/" + clientID + "_" + videoName + ".json" with open(trFileName, 'w') as outfile: json.dump(client_tr, outfile, sort_keys = True, indent = 4, ensure_ascii=False) srv_qoe_tr_filename = "./data/" + clientID + "_" + videoName + "_srvqoe.json" with open(srv_qoe_tr_filename, 'w') as outfile: json.dump(srv_qoe_tr, outfile, sort_keys = True, indent = 4, ensure_ascii = False) shutil.rmtree('./tmp')
def qas_dash(cache_agent, server_addrs, candidates, port, videoName, clientID, alpha): # Initialize servers' qoe cache_agent_ip = server_addrs[cache_agent] server_qoes = {} for key in candidates: if key is cache_agent: server_qoes[key] = 5 else: server_qoes[key] = 4 # Selecting a server with maximum QoE selected_srv = max(server_qoes.iteritems(), key=itemgetter(1))[0] pre_selected_srv = selected_srv selected_srv_ip = server_addrs[selected_srv] rsts = mpd_parser(selected_srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) else: audioID = rep audioInit = reps[rep]['initialization'] start = reps[rep]['start'] audioName = reps[rep]['name'] sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) # Start downloading video and audio chunks curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[AGENP] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp(int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") # print "[AGENP] Selected server for next 5 chunks is :" + selected_srv # achunk_sz = download_chunk(selected_srv_ip, videoName, audioInit) vchunk_sz = download_chunk(selected_srv_ip, videoName, vidInit) startTS = time.time() print "[QAS-DASH] Start playing video at " + datetime.datetime.fromtimestamp(int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) # print "[AGENP] Estimated bandwidth is : " + str(est_bw) + " at chunk #init" print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen # Traces to write out. client_tr = {} srv_qoe_tr = {} while (chunkNext * chunkLen < vidLength) : # Compute the representation for the next chunk to be downloaded nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) # Greedily increase the bitrate because server is switched to a better one if (pre_selected_srv != selected_srv): nextRep = increaseRep(sortedVids, nextRep) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time(); vchunk_sz = download_chunk(selected_srv_ip, videoName, vidChunk) curTS = time.time() est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS # print "[AGENP] Time Elapsed when downloading :" + str(time_elapsed) if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 # print "[AGENP] Client freezes for " + str(freezingTime) else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) # Update QoE evaluations on local client server_qoes[selected_srv] = server_qoes[selected_srv] * (1 - alpha) + alpha * chunk_QoE # print "[AGENP] Current QoE for chunk #" + str(chunkNext) + " is " + str(chunk_QoE) print "|---", str(int(curTS)), "---|---", str(chunkNext), "---|---", nextRep, "---|---", str(chunk_QoE), "---|---", str(curBuffer), "---|---", str(freezingTime), "---|---", selected_srv, "---|" # Write out traces client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, Freezing=freezingTime, Server=selected_srv) # Assign values but not dictionary pointer new_srv_qoes = {} for c in candidates: new_srv_qoes[c] = server_qoes[c] srv_qoe_tr[chunkNext] = new_srv_qoes # srv_qoe_tr[chunkNext] = server_qoes # Switching servers only after two chunks if chunkNext > 4: # Selecting a server with maximum QoE pre_selected_srv = selected_srv selected_srv = max(server_qoes.iteritems(), key=itemgetter(1))[0] selected_srv_ip = server_addrs[selected_srv] print "[QAS-DASH] Update Server QoEs ar :" + json.dumps(server_qoes) # print "[AGENP] Selected server for next 5 chunks is :" + selected_srv # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 ## Write trace files out and upload to google cloud storage trFileName = "./data/" + clientID + "_" + videoName + ".json" with open(trFileName, 'w') as outfile: json.dump(client_tr, outfile, sort_keys = True, indent = 4, ensure_ascii=False) srv_qoe_tr_filename = "./data/" + clientID + "_" + videoName + "_srvqoe.json" with open(srv_qoe_tr_filename, 'w') as outfile: json.dump(srv_qoe_tr, outfile, sort_keys=True, indent=4, ensure_ascii=False) shutil.rmtree('./tmp')
def dash(cache_agent, server_addrs, selected_srv, port, videoName, clientID): # Initialize server addresses srv_ip = server_addrs[selected_srv] # Read MPD file rsts = mpd_parser(srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) else: audioID = rep audioInit = reps[rep]['initialization'] start = reps[rep]['start'] audioName = reps[rep]['name'] sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) # Start downloading video and audio chunks curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[DASH] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp(int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") vchunk_sz = download_chunk(srv_ip, videoName, vidInit) startTS = time.time() print "[DASH] Start playing video at " + datetime.datetime.fromtimestamp(int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS -- |-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Server --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen # Traces to write to google cloud client_tr = {} while (chunkNext * chunkLen < vidLength) : nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time(); vchunk_sz = download_chunk(srv_ip, videoName, vidChunk) curTS = time.time() est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS # print "[AGENP] Time Elapsed when downloading :" + str(time_elapsed) if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 # print "[AGENP] Client freezes for " + str(freezingTime) else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) # print "[AGENP] Current QoE for chunk #" + str(chunkNext) + " is " + str(chunk_QoE) print "|---", str(int(curTS)), "---|---", str(chunkNext), "---|---", nextRep, "---|---", str(chunk_QoE), "---|---", str(curBuffer), "---|---", str(freezingTime), "---|---", selected_srv, "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, Freezing=freezingTime, Server=selected_srv) # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 trFileName = "./data/" + clientID + "_" + videoName + ".json" with open(trFileName, 'w') as outfile: json.dump(client_tr, outfile, sort_keys = True, indent = 4, ensure_ascii=False) shutil.rmtree('./tmp')
def switching_progressive_downloader(candidates, videoName, clientID, repIdx): # Initialize the selection of server selected_srv = candidates.keys()[0] srv_ip = candidates[selected_srv] candidates_num = len(candidates.keys()) # Read MPD file rsts = mpd_parser(srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) else: audioID = rep audioInit = reps[rep]['initialization'] start = reps[rep]['start'] audioName = reps[rep]['name'] sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) # print sortedVids repID = sortedVids[repIdx][0] vidInit = reps[repID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[repID]['timescale']) chunkLen = int(reps[repID]['length']) / timescale chunkNext = int(reps[repID]['start']) # Start downloading video and audio chunks curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[DASH] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp(int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") vchunk_sz = download_chunk(srv_ip, videoName, vidInit) startTS = time.time() print "[DASH] Start playing video at " + datetime.datetime.fromtimestamp(int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS -- |-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Server --|-- Response Time --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen # Traces to write to google cloud client_tr = {} while (chunkNext * chunkLen < vidLength): # Get the selected server for this chunk selected_srv_id = chunkNext % candidates_num selected_srv = candidates.keys()[selected_srv_id] srv_ip = candidates[selected_srv] vidChunk = reps[repID]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time(); vchunk_sz = download_chunk(srv_ip, videoName, vidChunk) curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[repID]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) print "|---", str(int(curTS)), "---|---", str(chunkNext), "---|---", repID, "---|---", str(chunk_QoE), "---|---", str(curBuffer), "---|---", str(freezingTime), "---|---", selected_srv, "---|---", str(rsp_time), "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=repID, QoE=chunk_QoE, Buffer=curBuffer, Freezing=freezingTime, Server=selected_srv, Response=rsp_time) # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 trFileName = "./data/" + clientID + "_" + videoName + ".json" with open(trFileName, 'w') as outfile: json.dump(client_tr, outfile, sort_keys = True, indent = 4, ensure_ascii=False) shutil.rmtree('./tmp') return client_tr
def client_agent(cache_agent_obj, video_id, method, expID=None): ## Read info from cache_agent_obj cache_agent_ip = cache_agent_obj['ip'] cache_agent = cache_agent_obj['name'] ## ================================================================================================== ## Client name and info ## ================================================================================================== client = str(socket.gethostname()) if expID: client_ID = client + "_" + expID + "_" + method else: cur_ts = time.strftime("%m%d%H%M") client_ID = client + "_" + cur_ts + "_" + method videoName = 'st' ## ================================================================================================== ## Get the initial streaming server ## ================================================================================================== srv_info = get_srv(cache_agent_ip, video_id, method) ## ================================================================================================== ## Cache agent failure handler ## ================================================================================================== if not srv_info: srv_info = srv_failover(client_ID, video_id, method, cache_agent_ip) ## If the failover has taken action but still not get the srv_info, it says the cache agent is done. if (not srv_info) and (method is 'qoe'): logging.info("[" + client_ID + "]Agens client fails to get the server for video " + str(video_id) + " 10 times. Trying to reconnect to a new cache agent!!!") # Attache to a new cache agent. cache_agent_obj = attach_cache_agent() if cache_agent_obj: cache_agent_ip = cache_agent_obj['ip'] cache_agent = cache_agent_obj['name'] srv_info = srv_failover(client_ID, video_id, method, cache_agent_ip) ## If the srv_info is stil not got yet if not srv_info: reportErrorQoE(client_ID, cache_agent_obj['name']) return ## ================================================================================================== ## ================================================================================================== ## Parse the mpd file for the streaming video ## ================================================================================================== rsts = mpd_parser(srv_info['ip'], videoName) ### =========================================================================================================== ## Add mpd_parser failure handler ### =========================================================================================================== if not rsts: logging.info("[" + client_ID + "]Agens client can not download mpd file for video " + videoName + " from server " + srv_info['srv'] + \ "Stop and exit the streaming for methods other than QoE. For qoe methods, get new srv_info!!!") if method == "qoe": trial_time = 0 while (not rsts) and (trial_time < 10): update_qoe(cache_agent_ip, srv_info['srv'], 0, 0.9) srv_info = srv_failover(client_ID, video_id, method, cache_agent_ip) if srv_info: rsts = mpd_parser(srv_info['ip'], videoName) else: rsts = '' # Attache to a new cache agent. cache_agent_obj = attach_cache_agent() if cache_agent_obj: cache_agent_ip = cache_agent_obj['ip'] cache_agent = cache_agent_obj['name'] trial_time = trial_time + 1 if not rsts: reportErrorQoE(client_ID, srv_info['srv']) return else: update_qoe(cache_agent_ip, srv_info['srv'], 0, 0.9) reportErrorQoE(client_ID, srv_info['srv']) return ### =========================================================================================================== ### Connecting to the qoe.db full_path = os.path.realpath(__file__) path, fn = os.path.split(full_path) db_name = path + "/qoe.db" con = lite.connect(db_name) cur = con.cursor() ### =========================================================================================================== vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] # Get video bitrates in each representations vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) # Start streaming from the minimum bitrate minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) ## ================================================================================================== # Start downloading the initial video chunk ## ================================================================================================== curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[" + client_ID + "] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp(int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") print "[" + client_ID + "] Selected server for next 12 chunks is :" + srv_info['srv'] vchunk_sz = download_chunk(srv_info['ip'], videoName, vidInit) startTS = time.time() print "[" + client_ID + "] Start playing video at " + datetime.datetime.fromtimestamp(int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|-- Chunk Response Time --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen ## Traces to write out client_tr = {} srv_qoe_tr = {} alpha = 0.1 ## ================================================================================================== # Start streaming the video ## ================================================================================================== while (chunkNext * chunkLen < vidLength) : nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time(); vchunk_sz = download_chunk(srv_info['ip'], videoName, vidChunk) ## Try 10 times to download the chunk error_num = 0 while (vchunk_sz == 0) and (error_num < 10): # Try to download again the chunk vchunk_sz = download_chunk(srv_info['ip'], videoName, vidChunk) error_num = error_num + 1 ### =========================================================================================================== ## Failover control for the timeout of chunk request ### =========================================================================================================== if vchunk_sz == 0: logging.info("[" + client_ID + "]Agens client can not download chunks video " + videoName + " from server " + srv_info['srv'] + \ " 3 times. Stop and exit the streaming!!!") ## Retry to download the chunk if method == "qoe": trial_time = 0 while (vchunk_sz == 0) and (trial_time < 10): update_qoe(cache_agent_ip, srv_info['srv'], 0, 0.9) logging.info("[" + client_ID + "]Agens client failed to download chunk from " + srv_info['srv'] + ". Update bad QoE and rechoose server from cache agent " + cache_agent + "!!!") srv_info = srv_failover(client_ID, video_id, method, cache_agent_ip) if srv_info: logging.info("[" + client_ID + "]Agens choose a new server " + srv_info['srv'] + " for video " + str(video_id) + " from cache agent " + cache_agent + "!!!") vchunk_sz = download_chunk(srv_info['ip'], videoName, vidChunk) else: vchunk_sz = 0 # Attache to a new cache agent. cache_agent_obj = attach_cache_agent() if cache_agent_obj: cache_agent_ip = cache_agent_obj['ip'] cache_agent = cache_agent_obj['name'] logging.info("[" + client_ID + "]Agens client can not contact cache agent and reconnects to cache agent " + cache_agent + "!!") trial_time = trial_time + 1 if vchunk_sz == 0: reportErrorQoE(client_ID, srv_info['srv'], trace=client_tr) return ## Write out 0 QoE traces for clients. else: update_qoe(cache_agent_ip, srv_info['srv'], 0, 0.9) reportErrorQoE(client_ID, srv_info['srv'], trace=client_tr) return else: error_num = 0 ### =========================================================================================================== curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS # Compute freezing time if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 # print "[AGENP] Client freezes for " + str(freezingTime) else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) print "|---", str(int(curTS)), "---|---", str(chunkNext), "---|---", nextRep, "---|---", str(chunk_QoE), "---|---", \ str(curBuffer), "---|---", str(freezingTime), "---|---", srv_info['srv'], "---|---", str(rsp_time), "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, \ Freezing=freezingTime, Server=srv_info['srv'], Response=rsp_time) srv_qoe_tr[chunkNext] = chunk_QoE # Select server for next 12 chunks if chunkNext%6 == 0 and chunkNext > 3: mnQoE = averageQoE(srv_qoe_tr) update_qoe(cache_agent_ip, srv_info['srv'], mnQoE, alpha) #========================================================================================================= ## Update the average QoE for 6 chunks to the qoe.db cur.execute("INSERT INTO QoE(vidID, srvName, srvIP, QoE, TS) values (?, ?, ?, ?, ?)", (video_id, srv_info['srv'], srv_info['ip'], mnQoE, datetime.datetime.now())) con.commit() #========================================================================================================= if method == "qoe": new_srv_info = get_srv(cache_agent_ip, video_id, method) if 'ip' in new_srv_info.keys(): print "[" + client_ID + "] Selected server for next 6 chunks is :" + srv_info['srv'] srv_info = new_srv_info else: logging.info("[" + client_ID + "]Agens client failed to choose server for video " + str(video_id) + " from cache agent " + cache_agent + "!!!") # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 ## Write out traces after finishing the streaming writeTrace(client_ID, client_tr) ## If tmp path exists, deletes it. if os.path.exists('./tmp'): shutil.rmtree('./tmp') ## Close the connection to database. con.close() return
def coop_ft_srv_mpd(cache_agent_ip, srv_info, video_id, v_peers, p_peers): ## Excluding the video server issue vclient = get_rnd_peer(v_peers) vclient_latest = get_peer_latest(vclient['ip']) client_name = socket.gethostname() ## =================================================================== # Check if the server is running to serve other clients # Resolve the fault type and log to both local logger and cfds-logger cur_v_peers = v_peers while (not vclient_latest) and cur_v_peers: cur_v_peers.pop(vclient['name']) vclient = get_rnd_peer(v_peers) vclient_latest = get_peer_latest(vclient['ip']) vpeer_qoe = float(vclient_latest['qoe']) fault_msg_obj = {} if vpeer_qoe > 0: msg_type = 6 msg = "The redirector directs video request to a server that does not cache the video." else: msg_type = 4 msg = "The video server is not running." fault_msg_obj['client'] = client_name fault_msg_obj['node'] = srv_info['ip'] fault_msg_obj['video'] = video_id fault_msg_obj['qoe'] = -1 fault_msg_obj['msg'] = msg fault_msg_obj['msg_type'] = msg_type local_fault_msg_logger(fault_msg_obj) fault_msg_logger(fault_msg_obj) ## =================================================================== ## Tolerate the fault by finding another video server serving video_id start_time = time.time() cur_p_peers = p_peers rsts = '' while (not rsts) and cur_p_peers: new_srv_info = {} selected_p_peer = get_rnd_peer(cur_p_peers) pclient_vid = get_peer_info_by_vid(selected_p_peer['ip'], video_id) while (not pclient_vid) and cur_p_peers: print "Cannot get video info for video id = ", str(video_id) + " from p_peer: " + \ selected_p_peer['name'] + " Removing it from list!" cur_p_peers.pop(selected_p_peer['name']) selected_p_peer = get_rnd_peer(cur_p_peers) pclient_vid = get_peer_info_by_vid(selected_p_peer['ip'], video_id) if pclient_vid: print "New server name is: " + pclient_vid["srvName"] new_srv_info['srv'] = pclient_vid["srvName"] new_srv_info['ip'] = pclient_vid["srv"] new_srv_info['vidName'] = srv_info['vidName'] rsts = mpd_parser(new_srv_info['ip'], new_srv_info['vidName']) recovery_time = time.time() - start_time if not rsts: fault_msg_obj = {} fault_msg_obj['client'] = client_name fault_msg_obj['node'] = srv_info['ip'] fault_msg_obj['video'] = video_id fault_msg_obj['qoe'] = -1 fault_msg_obj['msg'] = "Tried all closeby peer clients and cannot fix the fault in downloading \ mpd file for video: " + srv_info['vidName'] + "\n" + "\n".join(p_peers.keys()) fault_msg_obj['msg_type'] = 1 local_fault_msg_logger(fault_msg_obj) fault_msg_logger(fault_msg_obj) sys.exit() # client, fault_node, recovery_node, qoe, recovery_qoe, recovery_time, vidID, msg, fault_type recovery_msg_obj = {} recovery_msg_obj['client'] = client_name recovery_msg_obj['faulty_node'] = srv_info['ip'] recovery_msg_obj['recovery_node'] = new_srv_info['ip'] recovery_msg_obj['recovery_peer'] = selected_p_peer['name'] recovery_msg_obj['qoe'] = -1 recovery_msg_obj['recovery_qoe'] = -1 recovery_msg_obj['recovery_time'] = recovery_time recovery_msg_obj['video'] = video_id recovery_msg_obj['msg'] = "Recovery fault type " + str(msg_type) + " on server " + \ srv_info['ip'] + " with time period : " + "{:10.4f}".format(recovery_time) + " seconds!" recovery_msg_obj['msg_type'] = msg_type local_recovery_msg_logger(recovery_msg_obj) recovery_msg_logger(recovery_msg_obj) return (new_srv_info, rsts)
def cqas_dash(cache_agent, server_addrs, candidates, port, videoName, clientID, alpha): # Initialize servers' qoe cache_agent_ip = server_addrs[cache_agent] qoe_vector = query_QoE(cache_agent_ip, port) server_qoes = get_server_QoE(qoe_vector, server_addrs, candidates) # Selecting a server with maximum QoE selected_srv = max(server_qoes.iteritems(), key=itemgetter(1))[0] pre_selected_srv = selected_srv selected_srv_ip = server_addrs[selected_srv] rsts = mpd_parser(selected_srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {} good_chunks = {} for c in candidates: good_chunks[c] = 0 for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) else: audioID = rep audioInit = reps[rep]['initialization'] start = reps[rep]['start'] audioName = reps[rep]['name'] sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) # Start downloading video and audio chunks curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[CQAS-DASH] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp( int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") print "[CQAS-DASH] Selected server for next 5 chunks is :" + selected_srv vchunk_sz = download_chunk(selected_srv_ip, videoName, vidInit) startTS = time.time() print "[CQAS-DASH] Start playing video at " + datetime.datetime.fromtimestamp( int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen ## Traces to write out client_tr = {} srv_qoe_tr = {} while (chunkNext * chunkLen < vidLength): nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) # Greedily increase the bitrate because server is switched to a better one if (pre_selected_srv != selected_srv): # nextRep = increaseRep(sortedVids, nextRep) prob = good_chunks[selected_srv] / float(vidLength / chunkLen) rnd = random.random() ## Probabilistic switching if rnd < prob: print "[CQAS-DASH] Stick with the previous server! The probability is : " + str( prob) selected_srv = pre_selected_srv else: print "[CQAS-DASH]Switch server! The probability is : " + str( prob) nextRep = increaseRep(sortedVids, nextRep) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time() vchunk_sz = download_chunk(selected_srv_ip, videoName, vidChunk) curTS = time.time() est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 # print "[AGENP] Client freezes for " + str(freezingTime) else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) # print "[AGENP] Current QoE for chunk #" + str(chunkNext) + " is " + str(chunk_QoE) # Update QoE evaluations on local client server_qoes[selected_srv] = server_qoes[selected_srv] * ( 1 - alpha) + alpha * chunk_QoE print "|---", str(int(curTS)), "---|---", str( chunkNext), "---|---", nextRep, "---|---", str( chunk_QoE), "---|---", str(curBuffer), "---|---", str( freezingTime), "---|---", selected_srv, "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, Freezing=freezingTime, Server=selected_srv) srv_qoe_tr[chunkNext] = server_qoes if chunk_QoE > 4.0: good_chunks[selected_srv] = good_chunks[selected_srv] + 1 # Count Previous QoE average if chunkNext % 10 == 0 and chunkNext > 4: # mnQoE = averageQoE(client_tr, selected_srv) ## qoe_vector = update_QoE(cache_agent_ip, mnQoE, selected_srv) qoe_vector = update_srv_QoEs(cache_agent_ip, port, server_qoes) server_qoes = get_server_QoE(qoe_vector, server_addrs, candidates) print "[CQAS-DASH] Received Server QoE is :" + json.dumps( server_qoes) print "[CQAS-DASH] Selected server for next 10 chunks is :" + selected_srv # Selecting a server with maximum QoE if chunkNext > 4: # Selecting a server with maximum QoE pre_selected_srv = selected_srv selected_srv = max(server_qoes.iteritems(), key=itemgetter(1))[0] selected_srv_ip = server_addrs[selected_srv] print "[CQAS-DASH] Update Server QoEs ar :" + json.dumps( server_qoes) # print "[AGENP] Selected server for next 10 chunks is :" + selected_srv # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 # trFileName = "./data/" + clientID + "_" + videoName + "_" + str(time.time()) + ".json" ## Writer out traces files and upload to google cloud trFileName = "./data/" + clientID + "_" + videoName + ".json" with open(trFileName, 'w') as outfile: json.dump(client_tr, outfile, sort_keys=True, indent=4, ensure_ascii=False) srv_qoe_tr_filename = "./data/" + clientID + "_" + videoName + "_srvqoe.json" with open(srv_qoe_tr_filename, 'w') as outfile: json.dump(srv_qoe_tr, outfile, sort_keys=True, indent=4, ensure_ascii=False) shutil.rmtree('./tmp')
def dash(cache_agent, server_addrs, selected_srv, port, videoName, clientID): # Initialize server addresses srv_ip = server_addrs[selected_srv] # Read MPD file rsts = mpd_parser(srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) else: audioID = rep audioInit = reps[rep]['initialization'] start = reps[rep]['start'] audioName = reps[rep]['name'] sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) # Start downloading video and audio chunks curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[DASH] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp( int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") vchunk_sz = download_chunk(srv_ip, videoName, vidInit) startTS = time.time() print "[DASH] Start playing video at " + datetime.datetime.fromtimestamp( int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS -- |-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Server --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen # Traces to write to google cloud client_tr = {} while (chunkNext * chunkLen < vidLength): nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time() vchunk_sz = download_chunk(srv_ip, videoName, vidChunk) curTS = time.time() est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS # print "[AGENP] Time Elapsed when downloading :" + str(time_elapsed) if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 # print "[AGENP] Client freezes for " + str(freezingTime) else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) # print "[AGENP] Current QoE for chunk #" + str(chunkNext) + " is " + str(chunk_QoE) print "|---", str(int(curTS)), "---|---", str( chunkNext), "---|---", nextRep, "---|---", str( chunk_QoE), "---|---", str(curBuffer), "---|---", str( freezingTime), "---|---", selected_srv, "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, Freezing=freezingTime, Server=selected_srv) # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 trFileName = "./data/" + clientID + "_" + videoName + ".json" with open(trFileName, 'w') as outfile: json.dump(client_tr, outfile, sort_keys=True, indent=4, ensure_ascii=False) shutil.rmtree('./tmp')
def coop_client(cache_agent_obj, video_id, method, expID=None, COOP_PERIOD=6): ## ================================================================================================== ## Client name and info client = str(socket.gethostname()) if expID: client_ID = "coop_" + client + "_" + expID + "_" + method else: cur_ts = time.strftime("%m%d%H%M") client_ID = "coop_" + client + "_" + cur_ts + "_" + method ## ================================================================================================== ## Get the initial streaming server srv_info = get_srv(cache_agent_obj['ip'], video_id, "rtt") ## The cache agent does not give a server for streaming ## Try to change the cache agent by cooperating with closeby peers. if not srv_info: cache_agent_obj, srv_info = ft_cache_agent(cache_agent_obj, video_id) ## ================================================================================================== ## Get closeby clients from the closest cache agent. ## We by default assume the p_peers list will be obtained if cache agent is on. p_peers = get_peers(cache_agent_obj['ip'], "pclient") if not p_peers: p_peers = ft_pv_peers(cache_agent_obj['ip'], "pclient") ## Get peer client from the streaming server. We by default assume the v_peers list will be obtained # if the cache agent on this streaming server is on. # If our agent is not running, we report the error directly as redirector fault. v_peers = get_peers(srv_info['ip'], "vclient") if not v_peers: v_peers = ft_pv_peers(srv_info['ip'], "vclient") ## ================================================================================================== ## Parse the mpd file for the streaming video videoName = srv_info['vidName'] ## Debugging the bw issue #srv_info['vidName'] = 'BBB' #videoName = 'BBB' rsts = mpd_parser(srv_info['ip'], videoName) ## Add mpd_parser failure handler if not rsts: ## If the client can not download the mpd file for the video, the server is probably down or there # might be byzantine faults where [srv_info, rsts] = coop_ft_srv_mpd(cache_agent_obj['ip'], srv_info, video_id, v_peers, p_peers) ### =========================================================================================================== vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] # Get video bitrates in each representations vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) # Start streaming from the minimum bitrate minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) ## ================================================================================================== # Start downloading the initial video chunk ## ================================================================================================== curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[" + client_ID + "] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp(int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") print "[" + client_ID + "] Selected server for next 12 chunks is :" + srv_info['srv'] vchunk_sz = download_chunk(srv_info['ip'], videoName, vidInit) startTS = time.time() print "[" + client_ID + "] Start playing video at " + datetime.datetime.fromtimestamp(int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|-- Chunk Response Time --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen ## Traces to write out client_tr = {} srv_qoe_tr = {} alpha = 0.1 ## ================================================================================================== # Start streaming the video ## ================================================================================================== while (chunkNext * chunkLen < vidLength) : nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time(); vchunk_sz = download_chunk(srv_info['ip'], videoName, vidChunk) ## Try 10 times to download the chunk error_num = 0 while (vchunk_sz == 0) and (error_num < 2): # Try to download again the chunk vchunk_sz = download_chunk(srv_info['ip'], videoName, vidChunk) error_num = error_num + 1 ### =========================================================================================================== ## Client Cooperation based Fault Tolerance the timeout of chunk request ### =========================================================================================================== if vchunk_sz == 0: logging.info("[" + client_ID + "]Agens client can not download chunks video " + videoName + " from server " + srv_info['srv'] + \ " 3 times. Stop and exit the streaming!!!") (srv_info, vchunk_sz) = coop_ft_srv_chunk(srv_info, video_id, vidChunk, v_peers, p_peers) else: error_num = 0 ### =========================================================================================================== curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS # Compute freezing time if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 # print "[AGENP] Client freezes for " + str(freezingTime) else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) print "|---", str(int(curTS)), "---|---", str(chunkNext), "---|---", nextRep, "---|---", str(chunk_QoE), "---|---", \ str(curBuffer), "---|---", str(freezingTime), "---|---", srv_info['srv'], "---|---", str(rsp_time), "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, \ Freezing=freezingTime, Server=srv_info['srv'], Response=rsp_time) srv_qoe_tr[chunkNext] = chunk_QoE # Select server for next 12 chunks if chunkNext%COOP_PERIOD == 0 and chunkNext > (COOP_PERIOD - 1): mnQoE = averageQoE(srv_qoe_tr) update_qoe(cache_agent_obj['ip'], srv_info['srv'], mnQoE, alpha) #========================================================================================================= ## Update the average QoE for 6 chunks to the qoe.db insert_qoe(video_id, srv_info['srv'], srv_info['ip'], mnQoE) #========================================================================================================= ## Client Cooperation based Adaptive Server Selection srv_info = coop_qoe_srv_selection(mnQoE, srv_info, video_id, p_peers, v_peers) # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 ## Write out traces after finishing the streaming writeTrace(client_ID, client_tr) return
def client_agent(cache_agent_obj, video_id, method, expID=None): ## Read info from cache_agent_obj cache_agent_ip = cache_agent_obj['ip'] cache_agent = cache_agent_obj['name'] ## ================================================================================================== ## Client name and info ## ================================================================================================== client = str(socket.gethostname()) if expID: client_ID = client + "_" + expID + "_" + method else: cur_ts = time.strftime("%m%d%H%M") client_ID = client + "_" + cur_ts + "_" + method videoName = 'st' ## ================================================================================================== ## Get the initial streaming server ## ================================================================================================== srv_info = get_srv(cache_agent_ip, video_id, method) ## ================================================================================================== ## Cache agent failure handler ## ================================================================================================== if not srv_info: srv_info = srv_failover(client_ID, video_id, method, cache_agent_ip) ## If the failover has taken action but still not get the srv_info, it says the cache agent is done. if (not srv_info) and (method is 'qoe'): logging.info("[" + client_ID + "]Agens client fails to get the server for video " + str(video_id) + " 10 times. Trying to reconnect to a new cache agent!!!") # Attache to a new cache agent. cache_agent_obj = attach_cache_agent() if cache_agent_obj: cache_agent_ip = cache_agent_obj['ip'] cache_agent = cache_agent_obj['name'] srv_info = srv_failover(client_ID, video_id, method, cache_agent_ip) ## If the srv_info is stil not got yet if not srv_info: reportErrorQoE(client_ID, cache_agent_obj['name']) return ## ================================================================================================== ## ================================================================================================== ## Parse the mpd file for the streaming video ## ================================================================================================== rsts = mpd_parser(srv_info['ip'], videoName) ### =========================================================================================================== ## Add mpd_parser failure handler ### =========================================================================================================== if not rsts: logging.info("[" + client_ID + "]Agens client can not download mpd file for video " + videoName + " from server " + srv_info['srv'] + \ "Stop and exit the streaming for methods other than QoE. For qoe methods, get new srv_info!!!") if method == "qoe": trial_time = 0 while (not rsts) and (trial_time < 10): update_qoe(cache_agent_ip, srv_info['srv'], 0, 0.9) srv_info = srv_failover(client_ID, video_id, method, cache_agent_ip) if srv_info: rsts = mpd_parser(srv_info['ip'], videoName) else: rsts = '' # Attache to a new cache agent. cache_agent_obj = attach_cache_agent() if cache_agent_obj: cache_agent_ip = cache_agent_obj['ip'] cache_agent = cache_agent_obj['name'] trial_time = trial_time + 1 if not rsts: reportErrorQoE(client_ID, srv_info['srv']) return else: update_qoe(cache_agent_ip, srv_info['srv'], 0, 0.9) reportErrorQoE(client_ID, srv_info['srv']) return ### =========================================================================================================== ### Connecting to the qoe.db full_path = os.path.realpath(__file__) path, fn = os.path.split(full_path) db_name = path + "/qoe.db" con = lite.connect(db_name) cur = con.cursor() ### =========================================================================================================== vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] # Get video bitrates in each representations vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) # Start streaming from the minimum bitrate minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) ## ================================================================================================== # Start downloading the initial video chunk ## ================================================================================================== curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[" + client_ID + "] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp( int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") print "[" + client_ID + "] Selected server for next 12 chunks is :" + srv_info[ 'srv'] vchunk_sz = download_chunk(srv_info['ip'], videoName, vidInit) startTS = time.time() print "[" + client_ID + "] Start playing video at " + datetime.datetime.fromtimestamp( int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|-- Chunk Response Time --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen ## Traces to write out client_tr = {} srv_qoe_tr = {} alpha = 0.1 ## ================================================================================================== # Start streaming the video ## ================================================================================================== while (chunkNext * chunkLen < vidLength): nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time() vchunk_sz = download_chunk(srv_info['ip'], videoName, vidChunk) ## Try 10 times to download the chunk error_num = 0 while (vchunk_sz == 0) and (error_num < 10): # Try to download again the chunk vchunk_sz = download_chunk(srv_info['ip'], videoName, vidChunk) error_num = error_num + 1 ### =========================================================================================================== ## Failover control for the timeout of chunk request ### =========================================================================================================== if vchunk_sz == 0: logging.info("[" + client_ID + "]Agens client can not download chunks video " + videoName + " from server " + srv_info['srv'] + \ " 3 times. Stop and exit the streaming!!!") ## Retry to download the chunk if method == "qoe": trial_time = 0 while (vchunk_sz == 0) and (trial_time < 10): update_qoe(cache_agent_ip, srv_info['srv'], 0, 0.9) logging.info( "[" + client_ID + "]Agens client failed to download chunk from " + srv_info['srv'] + ". Update bad QoE and rechoose server from cache agent " + cache_agent + "!!!") srv_info = srv_failover(client_ID, video_id, method, cache_agent_ip) if srv_info: logging.info("[" + client_ID + "]Agens choose a new server " + srv_info['srv'] + " for video " + str(video_id) + " from cache agent " + cache_agent + "!!!") vchunk_sz = download_chunk(srv_info['ip'], videoName, vidChunk) else: vchunk_sz = 0 # Attache to a new cache agent. cache_agent_obj = attach_cache_agent() if cache_agent_obj: cache_agent_ip = cache_agent_obj['ip'] cache_agent = cache_agent_obj['name'] logging.info( "[" + client_ID + "]Agens client can not contact cache agent and reconnects to cache agent " + cache_agent + "!!") trial_time = trial_time + 1 if vchunk_sz == 0: reportErrorQoE(client_ID, srv_info['srv'], trace=client_tr) return ## Write out 0 QoE traces for clients. else: update_qoe(cache_agent_ip, srv_info['srv'], 0, 0.9) reportErrorQoE(client_ID, srv_info['srv'], trace=client_tr) return else: error_num = 0 ### =========================================================================================================== curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS # Compute freezing time if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 # print "[AGENP] Client freezes for " + str(freezingTime) else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) print "|---", str(int(curTS)), "---|---", str(chunkNext), "---|---", nextRep, "---|---", str(chunk_QoE), "---|---", \ str(curBuffer), "---|---", str(freezingTime), "---|---", srv_info['srv'], "---|---", str(rsp_time), "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, \ Freezing=freezingTime, Server=srv_info['srv'], Response=rsp_time) srv_qoe_tr[chunkNext] = chunk_QoE # Select server for next 12 chunks if chunkNext % 6 == 0 and chunkNext > 3: mnQoE = averageQoE(srv_qoe_tr) update_qoe(cache_agent_ip, srv_info['srv'], mnQoE, alpha) #========================================================================================================= ## Update the average QoE for 6 chunks to the qoe.db cur.execute( "INSERT INTO QoE(vidID, srvName, srvIP, QoE, TS) values (?, ?, ?, ?, ?)", (video_id, srv_info['srv'], srv_info['ip'], mnQoE, datetime.datetime.now())) con.commit() #========================================================================================================= if method == "qoe": new_srv_info = get_srv(cache_agent_ip, video_id, method) if 'ip' in new_srv_info.keys(): print "[" + client_ID + "] Selected server for next 6 chunks is :" + srv_info[ 'srv'] srv_info = new_srv_info else: logging.info( "[" + client_ID + "]Agens client failed to choose server for video " + str(video_id) + " from cache agent " + cache_agent + "!!!") # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 ## Write out traces after finishing the streaming writeTrace(client_ID, client_tr) ## If tmp path exists, deletes it. if os.path.exists('./tmp'): shutil.rmtree('./tmp') ## Close the connection to database. con.close() return
def switching_progressive_downloader(candidates, videoName, clientID, repIdx): # Initialize the selection of server selected_srv = candidates.keys()[0] srv_ip = candidates[selected_srv] candidates_num = len(candidates.keys()) # Read MPD file rsts = mpd_parser(srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) else: audioID = rep audioInit = reps[rep]['initialization'] start = reps[rep]['start'] audioName = reps[rep]['name'] sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) # print sortedVids repID = sortedVids[repIdx][0] vidInit = reps[repID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[repID]['timescale']) chunkLen = int(reps[repID]['length']) / timescale chunkNext = int(reps[repID]['start']) # Start downloading video and audio chunks curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[DASH] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp( int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") vchunk_sz = download_chunk(srv_ip, videoName, vidInit) startTS = time.time() print "[DASH] Start playing video at " + datetime.datetime.fromtimestamp( int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS -- |-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Server --|-- Response Time --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen # Traces to write to google cloud client_tr = {} while (chunkNext * chunkLen < vidLength): # Get the selected server for this chunk selected_srv_id = chunkNext % candidates_num selected_srv = candidates.keys()[selected_srv_id] srv_ip = candidates[selected_srv] vidChunk = reps[repID]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time() vchunk_sz = download_chunk(srv_ip, videoName, vidChunk) curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[repID]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) print "|---", str(int(curTS)), "---|---", str( chunkNext), "---|---", repID, "---|---", str( chunk_QoE), "---|---", str(curBuffer), "---|---", str( freezingTime), "---|---", selected_srv, "---|---", str( rsp_time), "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=repID, QoE=chunk_QoE, Buffer=curBuffer, Freezing=freezingTime, Server=selected_srv, Response=rsp_time) # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 trFileName = "./data/" + clientID + "_" + videoName + ".json" with open(trFileName, 'w') as outfile: json.dump(client_tr, outfile, sort_keys=True, indent=4, ensure_ascii=False) shutil.rmtree('./tmp') return client_tr
def http_client(cache_agent_ip, srv_info, video_name, bitrate_lvl, period=30): ## ================================================================================================== ## Client name and info client = str(socket.gethostname()) cur_ts = time.strftime("%m%d%H%M") client_ID = client + "_" + cur_ts + "_simple" ## ================================================================================================== ## Parse the mpd file for the streaming video ## ================================================================================================== rsts = mpd_parser(srv_info['ip'], video_name) ### =========================================================================================================== ## Add mpd_parser failure handler ### =========================================================================================================== trial_time = 0 while (not rsts) and (trial_time < 10): rsts = mpd_parser(srv_info['ip'], video_name) trial_time = trial_time + 1 if not rsts: update_qoe(cache_agent_ip, srv_info['ip'], 0, 0.9) return ### =========================================================================================================== vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] # Get video bitrates in each representations vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) # Start streaming from the denoted bitrate lvl vidInit = reps[str(bitrate_lvl)]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[str(bitrate_lvl)]['timescale']) chunkLen = int(reps[str(bitrate_lvl)]['length']) / timescale chunkNext = int(reps[str(bitrate_lvl)]['start']) ## ================================================================================================== # Start downloading the initial video chunk ## ================================================================================================== curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[" + client_ID + "] Start downloading video " + video_name + " at " + datetime.datetime.fromtimestamp(int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") print "[" + client_ID + "] Selected server for next 12 chunks is :" + srv_info['srv'] vchunk_sz = download_chunk(srv_info['ip'], video_name, vidInit) startTS = time.time() print "[" + client_ID + "] Start playing video at " + datetime.datetime.fromtimestamp(int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|-- Chunk Response Time --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen ## Traces to write out client_tr = {} srv_qoe_tr = {} alpha = 0.1 ## ================================================================================================== # Start streaming the video ## ================================================================================================== while (chunkNext * chunkLen < vidLength) : vidChunk = reps[str(bitrate_lvl)]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time(); vchunk_sz = download_chunk(srv_info['ip'], video_name, vidChunk) ## Try 10 times to download the chunk error_num = 0 while (vchunk_sz == 0) and (error_num < 10): # Try to download again the chunk vchunk_sz = download_chunk(srv_info['ip'], video_name, vidChunk) error_num = error_num + 1 ### =========================================================================================================== ## Failover control for the timeout of chunk request ### =========================================================================================================== if vchunk_sz == 0: update_qoe(cache_agent_ip, srv_info['srv'], 0, 0.9) return else: error_num = 0 ### =========================================================================================================== curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS # Compute freezing time if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 # print "[AGENP] Client freezes for " + str(freezingTime) else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[str(bitrate_lvl)]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) print "|---", str(int(curTS)), "---|---", str(chunkNext), "---|---", str(bitrate_lvl), "---|---", str(chunk_QoE), "---|---", \ str(curBuffer), "---|---", str(freezingTime), "---|---", srv_info['srv'], "---|---", str(rsp_time), "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=str(bitrate_lvl), QoE=chunk_QoE, Buffer=curBuffer, \ Freezing=freezingTime, Server=srv_info['srv'], Response=rsp_time) srv_qoe_tr[chunkNext] = chunk_QoE # Report QoE every chunk or 30 seconds. if chunkLen > period: update_qoe(cache_agent_ip, srv_info['srv'], chunk_QoE, alpha) else: intvl = int(period/chunkLen) if chunkNext%intvl == 0: mnQoE = averageQoE(srv_qoe_tr, intvl) update_qoe(cache_agent_ip, srv_info['srv'], mnQoE, alpha) # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 ## Write out traces after finishing the streaming writeTrace(client_ID, client_tr) ## If tmp path exists, deletes it. if os.path.exists('./tmp'): shutil.rmtree('./tmp') return
def rnd_qas_dash(candidates, videoName, clientID, alpha): # Initialize servers' qoe server_qoes = {} for key in candidates: server_qoes[key] = 4 # Selecting a server randomly selected_srv = random.choice(candidates.keys()) pre_selected_srv = selected_srv selected_srv_ip = candidates[selected_srv] rsts = mpd_parser(selected_srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) else: audioID = rep audioInit = reps[rep]['initialization'] start = reps[rep]['start'] audioName = reps[rep]['name'] sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) # Start downloading video and audio chunks curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[AGENP] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp( int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") vchunk_sz = download_chunk(selected_srv_ip, videoName, vidInit) startTS = time.time() print "[QAS-DASH] Start playing video at " + datetime.datetime.fromtimestamp( int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen # Traces to write out. client_tr = {} srv_qoe_tr = {} while (chunkNext * chunkLen < vidLength): # Compute the representation for the next chunk to be downloaded nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) # Greedily increase the bitrate because server is switched to a better one if (pre_selected_srv != selected_srv): nextRep = increaseRep(sortedVids, nextRep) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time() vchunk_sz = download_chunk(selected_srv_ip, videoName, vidChunk) curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) # Update QoE evaluations on local client server_qoes[selected_srv] = server_qoes[selected_srv] * ( 1 - alpha) + alpha * chunk_QoE print "|---", str(int(curTS)), "---|---", str( chunkNext), "---|---", nextRep, "---|---", str( chunk_QoE), "---|---", str(curBuffer), "---|---", str( freezingTime), "---|---", selected_srv, "---|" # Write out traces client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, Freezing=freezingTime, Server=selected_srv, Reponse=rsp_time) # Assign values but not dictionary pointer new_srv_qoes = {} for c in candidates: new_srv_qoes[c] = server_qoes[c] srv_qoe_tr[chunkNext] = new_srv_qoes # Switching servers only after two chunks if chunkNext > 4: # Selecting a server with maximum QoE pre_selected_srv = selected_srv selected_srv = max(server_qoes.iteritems(), key=itemgetter(1))[0] selected_srv_ip = server_addrs[selected_srv] print "[QAS-DASH] Update Server QoEs ar :" + json.dumps( server_qoes) # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 ## Write trace files out and upload to google cloud storage trFileName = "./data/" + clientID + "_" + videoName + ".json" with open(trFileName, 'w') as outfile: json.dump(client_tr, outfile, sort_keys=True, indent=4, ensure_ascii=False) srv_qoe_tr_filename = "./data/" + clientID + "_" + videoName + "_srvqoe.json" with open(srv_qoe_tr_filename, 'w') as outfile: json.dump(srv_qoe_tr, outfile, sort_keys=True, indent=4, ensure_ascii=False) shutil.rmtree('./tmp')
from mpd_parser import * # Server Name server_address = 'ec2-54-76-42-64.eu-west-1.compute.amazonaws.com' videoName = 'st' reps = mpd_parser(server_address, videoName) for item in reps: print item
def dash_client(cache_agent_obj, video_id, method, expID=None, DASH_PERIOD=6): ## ================================================================================================== ## Client name and info client = str(socket.gethostname()) if expID: client_ID = client + "_" + expID + "_" + method else: cur_ts = time.strftime("%m%d%H%M") client_ID = client + "_" + cur_ts + "_" + method ## ================================================================================================== ## Get the initial streaming server srv_info = get_srv(cache_agent_obj['ip'], video_id, method) ## The cache agent does not give a server for streaming ## Try to change the cache agent by cooperating with closeby peers. #if not srv_info: # cache_agent_obj, srv_info = ft_cache_agent(cache_agent_obj, video_id) ## ================================================================================================== ## Get closeby clients from the closest cache agent. ## We by default assume the p_peers list will be obtained if cache agent is on. #p_peers = get_peers(cache_agent_obj['ip'], "pclient") #if not p_peers: # p_peers = ft_pv_peers(cache_agent_obj['ip'], "pclient") ## Get peer client from the streaming server. We by default assume the v_peers list will be obtained # if the cache agent on this streaming server is on. # If our agent is not running, we report the error directly as redirector fault. #v_peers = get_peers(srv_info['ip'], "vclient") #if not v_peers: # v_peers = ft_pv_peers(srv_info['ip'], "vclient") ## ================================================================================================== ## Parse the mpd file for the streaming video videoName = srv_info['vidName'] ## Debugging the bw issue #srv_info['vidName'] = 'BBB' #videoName = 'BBB' rsts = mpd_parser(srv_info['ip'], videoName) ## Add mpd_parser failure handler #if not rsts: ## If the client can not download the mpd file for the video, the server is probably down or there # might be byzantine faults where # [srv_info, rsts] = coop_ft_srv_mpd(cache_agent_obj['ip'], srv_info, video_id, v_peers, p_peers) ### =========================================================================================================== vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] # Get video bitrates in each representations vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) # Start streaming from the minimum bitrate minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) ## ================================================================================================== # Start downloading the initial video chunk ## ================================================================================================== curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[" + client_ID + "] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp(int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") print "[" + client_ID + "] Selected server for next 12 chunks is :" + srv_info['srv'] vchunk_sz = download_chunk(srv_info['ip'], videoName, vidInit) startTS = time.time() print "[" + client_ID + "] Start playing video at " + datetime.datetime.fromtimestamp(int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|-- Chunk Response Time --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen ## Traces to write out client_tr = {} srv_qoe_tr = {} alpha = 0.1 ## ================================================================================================== # Start streaming the video ## ================================================================================================== while (chunkNext * chunkLen < vidLength) : nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time(); vchunk_sz = download_chunk(srv_info['ip'], videoName, vidChunk) ## Try 10 times to download the chunk error_num = 0 while (vchunk_sz == 0) and (error_num < 2): # Try to download again the chunk vchunk_sz = download_chunk(srv_info['ip'], videoName, vidChunk) error_num = error_num + 1 ### =========================================================================================================== ## Client Cooperation based Fault Tolerance the timeout of chunk request ### =========================================================================================================== #if vchunk_sz == 0: # logging.info("[" + client_ID + "]Agens client can not download chunks video " + videoName + " from server " + srv_info['srv'] + \ # " 3 times. Stop and exit the streaming!!!") # # (srv_info, vchunk_sz) = coop_ft_srv_chunk(srv_info, video_id, vidChunk, v_peers, p_peers) #else: # error_num = 0 ### =========================================================================================================== curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS # Compute freezing time if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 # print "[AGENP] Client freezes for " + str(freezingTime) else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) print "|---", str(int(curTS)), "---|---", str(chunkNext), "---|---", nextRep, "---|---", str(chunk_QoE), "---|---", \ str(curBuffer), "---|---", str(freezingTime), "---|---", srv_info['srv'], "---|---", str(rsp_time), "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, \ Freezing=freezingTime, Server=srv_info['srv'], Response=rsp_time) srv_qoe_tr[chunkNext] = chunk_QoE # Select server for next 12 chunks if chunkNext%DASH_PERIOD == 0 and chunkNext > (DASH_PERIOD - 1): mnQoE = averageQoE(srv_qoe_tr) update_qoe(cache_agent_obj['ip'], srv_info['srv'], mnQoE, alpha) #========================================================================================================= ## Update the average QoE for 6 chunks to the qoe.db insert_qoe(video_id, srv_info['srv'], srv_info['ip'], mnQoE) #========================================================================================================= ## Client Cooperation based Adaptive Server Selection # srv_info = coop_qoe_srv_selection(mnQoE, srv_info, video_id, p_peers, v_peers) # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 ## Write out traces after finishing the streaming writeTrace(client_ID, client_tr) return
def ant_dash(cache_agent, server_addrs, candidates, port, videoName, clientID, alpha): # Initialize servers' qoe cache_agent_ip = server_addrs[cache_agent] qoe_vector = query_QoE(cache_agent_ip, port) server_qoes = get_server_QoE(qoe_vector, server_addrs, candidates) print "Server QoE evaluations: ", server_qoes # Selecting a server with maximum QoE selected_srv = select_ant_srv(server_qoes) selected_srv_ip = server_addrs[selected_srv] rsts = mpd_parser(selected_srv_ip, videoName) vidLength = int(rsts['mediaDuration']) minBuffer = num(rsts['minBufferTime']) reps = rsts['representations'] vidBWs = {} for rep in reps: if not 'audio' in rep: vidBWs[rep] = int(reps[rep]['bw']) else: audioID = rep audioInit = reps[rep]['initialization'] start = reps[rep]['start'] audioName = reps[rep]['name'] sortedVids = sorted(vidBWs.items(), key=itemgetter(1)) minID = sortedVids[0][0] vidInit = reps[minID]['initialization'] maxBW = sortedVids[-1][1] # Read common parameters for all chunks timescale = int(reps[minID]['timescale']) chunkLen = int(reps[minID]['length']) / timescale chunkNext = int(reps[minID]['start']) # Start downloading video and audio chunks curBuffer = 0 chunk_download = 0 loadTS = time.time() print "[CQAS-DASH] Start downloading video " + videoName + " at " + datetime.datetime.fromtimestamp(int(loadTS)).strftime("%Y-%m-%d %H:%M:%S") print "[CQAS-DASH] Selected server for next 5 chunks is :" + selected_srv vchunk_sz = download_chunk(selected_srv_ip, videoName, vidInit) startTS = time.time() print "[CQAS-DASH] Start playing video at " + datetime.datetime.fromtimestamp(int(startTS)).strftime("%Y-%m-%d %H:%M:%S") est_bw = vchunk_sz * 8 / (startTS - loadTS) print "|-- TS --|-- Chunk # --|- Representation -|-- QoE --|-- Buffer --|-- Freezing --|-- Selected Server --|" preTS = startTS chunk_download += 1 curBuffer += chunkLen ## Traces to write out client_tr = {} srv_qoe_tr = {} while (chunkNext * chunkLen < vidLength): nextRep = findRep(sortedVids, est_bw, curBuffer, minBuffer) vidChunk = reps[nextRep]['name'].replace('$Number$', str(chunkNext)) loadTS = time.time() vchunk_sz = download_chunk(selected_srv_ip, videoName, vidChunk) curTS = time.time() rsp_time = curTS - loadTS est_bw = vchunk_sz * 8 / (curTS - loadTS) time_elapsed = curTS - preTS if time_elapsed > curBuffer: freezingTime = time_elapsed - curBuffer curBuffer = 0 else: freezingTime = 0 curBuffer = curBuffer - time_elapsed # Compute QoE of a chunk here curBW = num(reps[nextRep]['bw']) chunk_QoE = computeQoE(freezingTime, curBW, maxBW) # Update QoE evaluations on local client server_qoes[selected_srv] = server_qoes[selected_srv] * (1 - alpha) + alpha * chunk_QoE print "|---", str(int(curTS)), "---|---", str(chunkNext), "---|---", nextRep, "---|---", str(chunk_QoE), "---|---", str(curBuffer), "---|---", str(freezingTime), "---|---", selected_srv, "---|" client_tr[chunkNext] = dict(TS=int(curTS), Representation=nextRep, QoE=chunk_QoE, Buffer=curBuffer, Freezing=freezingTime, Server=selected_srv, Response=rsp_time) srv_qoe_tr[chunkNext] = server_qoes # Count Previous QoE average if chunkNext%5 == 0 and chunkNext > 4: mnQoE = averageQoE(client_tr, selected_srv) qoe_vector = update_QoE(cache_agent_ip, port, mnQoE, selected_srv) server_qoes = get_server_QoE(qoe_vector, server_addrs, candidates) print "[ANT-DASH] Received Server QoE is :" + json.dumps(server_qoes) print "[ANT-DASH] Selected server for next 5 chunks is :" + selected_srv # Selecting a server with probability proportional to server QoE selected_srv = select_ant_srv(server_qoes) selected_srv_ip = server_addrs[selected_srv] # Update iteration information curBuffer = curBuffer + chunkLen if curBuffer > 30: time.sleep(chunkLen) preTS = curTS chunk_download += 1 chunkNext += 1 trFileName = "./data/" + clientID + "_" + videoName + ".json" with open(trFileName, 'w') as outfile: json.dump(client_tr, outfile, sort_keys = True, indent = 4, ensure_ascii=False) srv_qoe_tr_filename = "./data/" + clientID + "_" + videoName + "_srvqoe.json" with open(srv_qoe_tr_filename, 'w') as outfile: json.dump(srv_qoe_tr, outfile, sort_keys = True, indent = 4, ensure_ascii = False) shutil.rmtree('./tmp') return client_tr