annotate python/example/m3u.py @ 914:016d27ca39e4

py3
author Jeff Hammel <k0scist@gmail.com>
date Mon, 27 May 2024 16:02:17 -0700
parents e6fb1a8fe66b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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()