Exemple #1
0
    def variant_m3u8(self, cid=None, r=None, tag=None, **kwargs):
        """ Special endpoint for shaping direct variqnt playlists"""

        seeded_content_id = conf.common.get_seeded_cid(cid)
        fake_master_playlist_url = ""
        fake_master_playlist =  """
        #EXTM3U
        #EXT-X-VERSION:2
        #EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=0,RESOLUTION=0x0
        {0}
        """.format( conf.data.provider.master_m3u8_url(cid, kwargs) )

        varient_playlists = httpls_client.get_variant_playlist_urls(fake_master_playlist, fake_master_playlist_url)
        rules = shaper.parse_hls_rules(r, varient_playlists)

        info = shaper.hls_cache_and_shape(fake_master_playlist, seeded_content_id, rules, fake_master_playlist_url)
        info["url"] = conf.common.get_final_url("playlist.m3u8","p=m_{0}".format(seeded_content_id))

        # if we have a tag, store
        if tag:
            self.store_tag(cid, r, tag, kwargs)

        cached_cid = info['variants'][info['variants'].keys()[0]]

        with open("{0}/playlists/m_{1}.m3u8".format(shaper.shaper_store_path, cached_cid), "r") as pf:
            master_content = pf.read()

        # return the rewritten master  
        cherrypy.response.headers['Content-Type'] = "application/vnd.apple.mpegurl"
        cherrypy.response.headers['Content-Disposition'] = "inline; filename={0}.m3u8".format(cid)
        cherrypy.response.headers['Last-Modified'] = httputil.HTTPDate()

        return master_content
Exemple #2
0
    def test_hls_segment_rule_match_vplaylist(self):
        v_playlists_desc = httpls_client.get_variant_playlist_urls(self.master_playlist)
       
        p4000k = next( v_playlists_desc["4000000"].itervalues())
        self.assertTrue( shaper.hls_segment_rule_match(shaper.parse_hls_rules("4000k~e404"), p4000k, p4000k) != None )
        self.assertTrue( shaper.hls_segment_rule_match(shaper.parse_hls_rules("650k~e404"), p4000k, p4000k) == None )

        master_cdn_playlist = open(self.test_path + "/wt_suite/basic/wt_master_cdn_fallback.m3u8","r").read()
        v_playlists_cdn_desc = httpls_client.get_variant_playlist_urls(master_cdn_playlist)
    
        p4000k_a =  v_playlists_cdn_desc["4000000"]["a"]
        self.assertTrue( shaper.hls_segment_rule_match(shaper.parse_hls_rules("b.4000k~e404"), p4000k_a, p4000k_a) == None )
        self.assertTrue( shaper.hls_segment_rule_match(shaper.parse_hls_rules("a.4000k~e404"), p4000k_a, p4000k_a) != None )
        self.assertTrue( shaper.hls_segment_rule_match(shaper.parse_hls_rules("4000k~e404"), p4000k_a, p4000k_a) != None )
        self.assertTrue( shaper.hls_segment_rule_match(shaper.parse_hls_rules("*~e404"), p4000k_a, p4000k_a) != None )
        
        self.assertTrue( shaper.hls_segment_rule_match(shaper.parse_hls_rules("1000k.s0~e404,1000k~e500"), self.v_playlist_1000k, self.v_playlist_1000k) != None )
    def test_pull_master_playlist(self):
        master_playlist = open(self.test_path + "/wt_suite/wt_dripls/wt.m3u8","r").read()
        v_playlists = httpls_client.get_variant_playlist_urls(master_playlist)

        #test with a master playlist
        c = 0
        for bandwidth in v_playlists.iterkeys():
            for cdn in v_playlists[bandwidth].iterkeys():
                self.assertTrue(v_playlists[bandwidth][cdn]["type"] == "vplaylist")
                self.assertTrue(v_playlists[bandwidth][cdn]["url"] != None)
                c += 1
        self.assertTrue( c > 0)

        # test with a non-master playlist
        not_master_playlist = open(self.test_path + "/wt_suite/wt_dripls/wt_1700k.m3u8","r").read()
        v_playlists = httpls_client.get_variant_playlist_urls(not_master_playlist)
        for bandwidth in v_playlists.iterkeys():
            for cdn in v_playlists[bandwidth].iterkeys():
               self.fail("found a variable playlist inside a vplaylist")    
            
        return 
Exemple #4
0
    def test_hls_segment_rule_match_vplaylist(self):
        v_playlists_desc = httpls_client.get_variant_playlist_urls(
            self.master_playlist)

        p4000k = next(v_playlists_desc["4000000"].itervalues())
        self.assertTrue(
            shaper.hls_segment_rule_match(shaper.parse_hls_rules("4000k~e404"),
                                          p4000k, p4000k) != None)
        self.assertTrue(
            shaper.hls_segment_rule_match(shaper.parse_hls_rules("650k~e404"),
                                          p4000k, p4000k) == None)

        master_cdn_playlist = open(
            self.test_path + "/wt_suite/basic/wt_master_cdn_fallback.m3u8",
            "r").read()
        v_playlists_cdn_desc = httpls_client.get_variant_playlist_urls(
            master_cdn_playlist)

        p4000k_a = v_playlists_cdn_desc["4000000"]["a"]
        self.assertTrue(
            shaper.hls_segment_rule_match(
                shaper.parse_hls_rules("b.4000k~e404"), p4000k_a, p4000k_a) ==
            None)
        self.assertTrue(
            shaper.hls_segment_rule_match(
                shaper.parse_hls_rules("a.4000k~e404"), p4000k_a, p4000k_a) !=
            None)
        self.assertTrue(
            shaper.hls_segment_rule_match(shaper.parse_hls_rules("4000k~e404"),
                                          p4000k_a, p4000k_a) != None)
        self.assertTrue(
            shaper.hls_segment_rule_match(shaper.parse_hls_rules("*~e404"),
                                          p4000k_a, p4000k_a) != None)

        self.assertTrue(
            shaper.hls_segment_rule_match(
                shaper.parse_hls_rules("1000k.s0~e404,1000k~e500"),
                self.v_playlist_1000k, self.v_playlist_1000k) != None)
Exemple #5
0
def hls_cache_and_shape(master_playlist, seeded_content_id, rules, master_playlist_url = ''):
    """Returns shaped m3u8 playlist

    Process and shape a m3u8 playlist based on a set of rules 

    """

    shape_info = {}
    shape_info["id"] = seeded_content_id
    shape_info["variants"] = {}
    shape_port_session = {}

    variant_playlists = httpls_client.get_variant_playlist_urls(master_playlist, master_playlist_url)

    for bitrate in variant_playlists.iterkeys():
        for alt in variant_playlists[bitrate].iterkeys():
            variant_playlist_desc = variant_playlists[bitrate][alt]
            variant_playlist = httpls_client.pull_variant_playlist( variant_playlist_desc["url"])

            # perform rewrite on the variant playlist url to local url or a rule matched url 
            seg_rewrite_url = hls_segment_rule_rewrite(rules, variant_playlist_desc, variant_playlist_desc, shape_port_session)
            local_rewrite_url = conf.common.get_final_url("playlist.m3u8","p=m_{0}_{1}_{2}".format(seeded_content_id, bitrate, alt))
            shape_info["variants"]["{0}_{1}".format(bitrate, alt)] = "{0}_{1}_{2}".format(seeded_content_id, bitrate, alt)
            master_playlist = httpls_client.switch_segment( master_playlist, variant_playlist_desc["original_url"], seg_rewrite_url if seg_rewrite_url else local_rewrite_url )

            # don't process a playlist if it hit a rule (ie has been errored out)
            if seg_rewrite_url:
                shape_info["{0}.{1}".format(bitrate, alt)] = seg_rewrite_url
                continue

            # perform rule rewrite on segments within the variant playlist  
            for s in variant_playlist["segments"].iterkeys():
                seg_rewrite_url = hls_segment_rule_rewrite(rules, variant_playlist_desc, variant_playlist["segments"][s], shape_port_session)

                # rewrite local to full url playlist
                if variant_playlist["segments"][s]["original_url"] != variant_playlist["segments"][s]["url"]:
                    variant_playlist["content"] = httpls_client.switch_segment(variant_playlist["content"], variant_playlist["segments"][s]["original_url"], variant_playlist["segments"][s]["url"])

                # replace segment with shaped url
                if seg_rewrite_url:
                    variant_playlist["content"] = httpls_client.switch_segment(variant_playlist["content"], variant_playlist["segments"][s]["url"], seg_rewrite_url)
                    variant_playlist["segments"][s]["url"] = seg_rewrite_url
                    shape_info["{0}.{1}.s{2}".format( bitrate, alt, s)] = seg_rewrite_url

            httpls_client.store_playlist(variant_playlist["content"], shaper_store_path + "playlists/m_{0}_{1}_{2}.m3u8".format(seeded_content_id, bitrate, alt))


    shape_port_session = {}
    httpls_client.store_playlist(master_playlist, shaper_store_path + "playlists/m_{0}.m3u8".format(seeded_content_id))
    return shape_info
    def test_switch_segment(self):

        # test switch with master playlist
        master_playlist = open(self.test_path + "/wt_suite/wt_dripls/wt.m3u8","r").read()
        v_playlists = httpls_client.get_variant_playlist_urls(master_playlist)
         
        c = 0 
        for bandwidth in v_playlists.iterkeys():
            for cdn in v_playlists[bandwidth].iterkeys():
                c += 1
                replace_segment = "http://testsegment" + str(c)
                master_playlist = httpls_client.switch_segment(master_playlist, v_playlists[bandwidth][cdn]["url"], replace_segment) 
                self.assertTrue( master_playlist.find(v_playlists[bandwidth][cdn]["url"]) == -1 ) 
                self.assertTrue( master_playlist.find( replace_segment) != -1 ) 
        
        variant_playlist = open(self.test_path + "/wt_suite/wt_dripls/wt_1700k.m3u8","r").read()

        return
Exemple #7
0
    def cache_stream(self, cid=None, r=None, tag=None, kwargs=None):
        """ Perform the actual caching and shaping  of the stream """


        seeded_content_id = conf.common.get_seeded_cid(cid)
        master_playlist_url = conf.data.provider.master_m3u8_url(cid, kwargs)
        master_playlist = conf.data.provider.pull_master_m3u8(cid, kwargs)
        varient_playlists = httpls_client.get_variant_playlist_urls(master_playlist, master_playlist_url)

        rules = shaper.parse_hls_rules(r, varient_playlists)

        info = shaper.hls_cache_and_shape(master_playlist, seeded_content_id, rules, master_playlist_url)
        info["url"] = conf.common.get_final_url("playlist.m3u8","p=m_{0}".format(seeded_content_id))

        # if we have a tag, store
        if tag:
            self.store_tag(cid, r, tag, kwargs)

        return info