Mercurial > hg > config
annotate python/example/m3u.py @ 929:7c4be71a560b default tip
remove old aliases
| author | Jeff Hammel <k0scist@gmail.com> | 
|---|---|
| date | Mon, 20 Oct 2025 15:22:19 -0700 | 
| parents | e6fb1a8fe66b | 
| children | 
| rev | line source | 
|---|---|
| 752 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 1 #!/usr/bin/env python | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 2 # -*- coding: utf-8 -*- | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 3 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 4 """ | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 5 m3u playlist manipulator | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 6 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 7 See: | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 8 - https://pypi.python.org/pypi/m3u8 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 9 - http://gonze.com/playlists/playlist-format-survey.html#M3U | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 10 - http://www.assistanttools.com/articles/m3u_playlist_format.shtml | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 11 - http://en.wikipedia.org/wiki/M3U | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 12 - http://tools.ietf.org/html/draft-pantos-http-live-streaming-08#section-3.3.1 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 13 """ | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 14 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 15 # imports | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 16 import argparse | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 17 import m3u8 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 18 import os | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 19 import subprocess | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 20 import sys | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 21 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 22 # module globals | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 23 __all__ = ['main', 'M3UParser'] | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 24 here = os.path.dirname(os.path.realpath(__file__)) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 25 string = (str, unicode) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 26 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 27 class Playlist(object): | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 28 def __init__(self, playlists=(), base_path=None): | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 29 self.clips = [] | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 30 for playlist in playlists: | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 31 assert os.path.isfile(playlist) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 32 _base_path = os.path.abspath(base_path or os.path.dirname(os.path.abspath(playlist))) # TODO: this doesn't fix URLs | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 33 content = open(playlist).read() | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 34 m3u = m3u8.M3U8(content, base_path=_base_path) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 35 for segment in m3u.segments: | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 36 path = segment.uri | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 37 title = segment.title | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 38 self.clips.append((title, path)) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 39 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 40 def __str__(self): | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 41 retval = [] | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 42 for title, path in self.clips: | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 43 if title: | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 44 line = '{} # {}'.format(os.path.abspath(path), title) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 45 else: | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 46 line = os.path.abspath(path) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 47 retval.append(line) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 48 return '\n'.join(retval) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 49 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 50 class M3UParser(argparse.ArgumentParser): | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 51 """CLI option parser""" | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 52 def __init__(self, **kwargs): | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 53 kwargs.setdefault('description', __doc__) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 54 argparse.ArgumentParser.__init__(self, **kwargs) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 55 self.add_argument('playlists', metavar='playlist', nargs='+', | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 56 help="playlist to parse") | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 57 self.add_argument('-b', '--base', dest='base_path', default=os.getcwd(), | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 58 help="base path [DEFAULT: %(default)s]") | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 59 self.options = None | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 60 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 61 def parse_args(self, *args, **kw): | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 62 options = argparse.ArgumentParser.parse_args(self, *args, **kw) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 63 self.validate(options) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 64 self.options = options | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 65 return options | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 66 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 67 def validate(self, options): | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 68 """validate options""" | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 69 if not os.path.exists(options.base_path): | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 70 self.error("Base path '{}' does not exist".format(options.base_path)) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 71 missing = [i for i in options.playlists | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 72 if not os.path.exists(i)] | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 73 if missing: | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 74 self.error("Playlist not found: {}".format(', '.join(missing))) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 75 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 76 def main(args=sys.argv[1:]): | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 77 """CLI""" | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 78 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 79 # parse command line options | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 80 parser = M3UParser() | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 81 options = parser.parse_args(args) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 82 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 83 # create playlist | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 84 playlist = Playlist(options.playlists, options.base_path) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 85 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 86 # print out some things | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 87 print ('{}'.format(playlist)) | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 88 | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 89 if __name__ == '__main__': | 
| 
e6fb1a8fe66b
add example for m3u playlists [status: unknown]
 Jeff Hammel <k0scist@gmail.com> parents: diff
changeset | 90 main() | 
