Skip to content

Instantly share code, notes, and snippets.

@dunnousername
Created October 5, 2020 20:17
Show Gist options
  • Save dunnousername/dda3017d87d77894ae5acb23c0c28561 to your computer and use it in GitHub Desktop.
Save dunnousername/dda3017d87d77894ae5acb23c0c28561 to your computer and use it in GitHub Desktop.
#!/bin/env python3
import argparse
import os
import shutil
import subprocess
def map_playlist(m3u8: str, folder: str):
counter = 0
for line in m3u8.split('\n'):
if line.startswith('#'):
if not line.startswith('#EXT-X-KEY:'):
yield line + '\n', None
else:
attrs = line[line.index(':')+1:].split(',')
url = None
new_attrs = []
for s in attrs:
if s.startswith('URI='):
if '"' in s:
url = s[s.index('"')+1:s.rindex('"')]
else:
url = s[:4]
new_attrs.append('URI="file:./{}/key.key"'.format(folder))
else:
new_attrs.append(s)
new_line = '#EXT-X-KEY:{}'.format(','.join(new_attrs))
if url:
yield new_line + '\n', '{}\n\tout={}/key.key\n'.format(url, folder)
else:
url = '{}'.format(line)
fn = '{}.ts'.format(counter)
full_fn = './{}/{}'.format(folder, fn)
yield full_fn + '\n', '{}\n\tout={}\n'.format(url, full_fn)
counter += 1
def main(m3u8_fn: str, output_fn: str):
if not output_fn:
output_fn = m3u8_fn[:m3u8_fn.rindex('.')] + '.ts'
folder = os.path.basename(m3u8_fn) + '.tmp'
os.mkdir(folder)
with open(m3u8_fn, 'r') as m3u8_f:
m3u8 = m3u8_f.read()
with open(m3u8_fn + '.tmp.m3u8', 'w+') as new_m3u8_f, open(os.path.join(folder, 'tmp.aria2'), 'w+') as aria2_f:
for (x, y) in map_playlist(m3u8, folder):
if x:
new_m3u8_f.write(x)
if y:
aria2_f.write(y)
subprocess.run(['aria2c', '-i', folder + '/tmp.aria2'])
subprocess.run(['ffmpeg', '-v', 'debug', '-allowed_extensions', 'ALL', '-i', m3u8_fn + '.tmp.m3u8', '-c', 'copy', output_fn])
shutil.rmtree(folder)
parser = argparse.ArgumentParser(description='Download an m3u8 media playlist in parallel using aria2c and ffmpeg')
parser.add_argument('m3u8_input')
parser.add_argument('--output', default='')
args = parser.parse_args()
if __name__ == "__main__":
main(args.m3u8_input, args.output)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment