Guest User

Untitled

a guest
May 30th, 2013
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.73 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*
  3. import re
  4. from collections import namedtuple
  5.  
  6. ext_x_targetduration = '#EXT-X-TARGETDURATION'
  7. ext_x_media_sequence = '#EXT-X-MEDIA-SEQUENCE'
  8. ext_x_key = '#EXT-X-KEY'
  9. ext_x_stream_inf = '#EXT-X-STREAM-INF'
  10. ext_x_version = '#EXT-X-VERSION'
  11. ext_x_allow_cache = '#EXT-X-ALLOW-CACHE'
  12. ext_x_endlist = '#EXT-X-ENDLIST'
  13. extinf = '#EXTINF'
  14. ATTRIBUTELISTPATTERN = re.compile(r'''((?:[^,"']|"[^"]*"|'[^']*')+)''')
  15.  
  16. def parse(content):
  17.     data = {
  18.         'is_variant': False,
  19.         'is_endlist': False,
  20.         'playlists': [],
  21.         'segments': [],
  22.         }
  23.     state = {
  24.         'expect_segment': False,
  25.         'expect_playlist': False,
  26.         }
  27.     for line in string_to_lines(content):
  28.         line = line.strip()
  29.         if state['expect_segment']:
  30.             _parse_ts_chunk(line, data, state)
  31.             state['expect_segment'] = False
  32.         elif state['expect_playlist']:
  33.             _parse_variant_playlist(line, data, state)
  34.             state['expect_playlist'] = False
  35.         elif line.startswith(ext_x_targetduration):
  36.             _parse_simple_parameter(line, data, float)
  37.         elif line.startswith(ext_x_media_sequence):
  38.             _parse_simple_parameter(line, data, int)
  39.         elif line.startswith(ext_x_version):
  40.             _parse_simple_parameter(line, data)
  41.         elif line.startswith(ext_x_allow_cache):
  42.             _parse_simple_parameter(line, data)
  43.         elif line.startswith(ext_x_key):
  44.             _parse_key(line, data)
  45.         elif line.startswith(extinf):
  46.             _parse_extinf(line, data, state)
  47.             state['expect_segment'] = True
  48.         elif line.startswith(ext_x_stream_inf):
  49.             state['expect_playlist'] = True
  50.             _parse_stream_inf(line, data, state)
  51.         elif line.startswith(ext_x_endlist):
  52.             data['is_endlist'] = True
  53.     return data
  54.  
  55. def _parse_key(line, data):
  56.     params = ATTRIBUTELISTPATTERN.split(line.replace(ext_x_key + ':', ''))[1::2]
  57.     data['key'] = {}
  58.     for param in params:
  59.         name, value = param.split('=', 1)
  60.         data['key'][normalize_attribute(name)] = remove_quotes(value)
  61.  
  62. def _parse_extinf(line, data, state):
  63.     duration, title = line.replace(extinf + ':', '').split(',')
  64.     state['segment'] = {'duration': float(duration), 'title': remove_quotes(title)}
  65.  
  66. def _parse_ts_chunk(line, data, state):
  67.     segment = state.pop('segment')
  68.     segment['uri'] = line
  69.     data['segments'].append(segment)
  70.  
  71. def _parse_stream_inf(line, data, state):
  72.     params = ATTRIBUTELISTPATTERN.split(line.replace(ext_x_stream_inf + ':', ''))[1::2]
  73.     stream_info = {}
  74.     for param in params:
  75.         name, value = param.split('=', 1)
  76.         stream_info[normalize_attribute(name)] = value
  77.  
  78.     if 'codecs' in stream_info:
  79.         stream_info['codecs'] = remove_quotes(stream_info['codecs'])
  80.     data['is_variant'] = True
  81.     state['stream_info'] = stream_info
  82.  
  83. def _parse_variant_playlist(line, data, state):
  84.     playlist = {'uri': line,
  85.                 'stream_info': state.pop('stream_info')}
  86.     data['playlists'].append(playlist)
  87.  
  88. def _parse_simple_parameter(line, data, cast_to=str):
  89.     param, value = line.split(':', 1)
  90.     param = normalize_attribute(param.replace('#EXT-X-', ''))
  91.     value = normalize_attribute(value)
  92.     data[param] = cast_to(value)
  93.  
  94. def string_to_lines(string):
  95.     return string.strip().replace('\r\n', '\n').split('\n')
  96.  
  97. def remove_quotes(string):
  98.     quotes = ('"', "'")
  99.     if string and string[0] in quotes and string[-1] in quotes:
  100.         return string[1:-1]
  101.     return string
  102.  
  103. def normalize_attribute(attribute):
  104.     return attribute.replace('-', '_').lower().strip()
  105.  
  106. def is_url(uri):
  107.     return re.match(r'https?://', uri) is not None
Add Comment
Please, Sign In to add comment