Reads and writes m3u or m3u8 playlist files.
| 24 | |
| 25 | |
| 26 | class M3UFile: |
| 27 | """Reads and writes m3u or m3u8 playlist files.""" |
| 28 | |
| 29 | def __init__(self, path): |
| 30 | """``path`` is the absolute path to the playlist file. |
| 31 | |
| 32 | The playlist file type, m3u or m3u8 is determined by 1) the ending |
| 33 | being m3u8 and 2) the file paths contained in the list being utf-8 |
| 34 | encoded. Since the list is passed from the outside, this is currently |
| 35 | out of control of this class. |
| 36 | """ |
| 37 | self.path = path |
| 38 | self.extm3u = False |
| 39 | self.media_list = [] |
| 40 | |
| 41 | def load(self): |
| 42 | """Reads the m3u file from disk and sets the object's attributes.""" |
| 43 | pl_normpath = normpath(self.path) |
| 44 | try: |
| 45 | with open(syspath(pl_normpath), "rb") as pl_file: |
| 46 | raw_contents = pl_file.readlines() |
| 47 | except OSError as exc: |
| 48 | raise FilesystemError( |
| 49 | exc, "read", (pl_normpath,), traceback.format_exc() |
| 50 | ) |
| 51 | |
| 52 | self.extm3u = True if raw_contents[0].rstrip() == b"#EXTM3U" else False |
| 53 | for line in raw_contents[1:]: |
| 54 | if line.startswith(b"#"): |
| 55 | # Support for specific EXTM3U comments could be added here. |
| 56 | continue |
| 57 | self.media_list.append(normpath(line.rstrip())) |
| 58 | if not self.media_list: |
| 59 | raise EmptyPlaylistError |
| 60 | |
| 61 | def set_contents(self, media_list, extm3u=True): |
| 62 | """Sets self.media_list to a list of media file paths. |
| 63 | |
| 64 | Also sets additional flags, changing the final m3u-file's format. |
| 65 | |
| 66 | ``media_list`` is a list of paths to media files that should be added |
| 67 | to the playlist (relative or absolute paths, that's the responsibility |
| 68 | of the caller). By default the ``extm3u`` flag is set, to ensure a |
| 69 | save-operation writes an m3u-extended playlist (comment "#EXTM3U" at |
| 70 | the top of the file). |
| 71 | """ |
| 72 | self.media_list = media_list |
| 73 | self.extm3u = extm3u |
| 74 | |
| 75 | def write(self): |
| 76 | """Writes the m3u file to disk. |
| 77 | |
| 78 | Handles the creation of potential parent directories. |
| 79 | """ |
| 80 | header = [b"#EXTM3U"] if self.extm3u else [] |
| 81 | if not self.media_list: |
| 82 | raise EmptyPlaylistError |
| 83 | contents = header + self.media_list |
no outgoing calls