Skip to content

Instantly share code, notes, and snippets.

@darvin
Created February 12, 2012 03:49
Show Gist options
  • Save darvin/1806112 to your computer and use it in GitHub Desktop.
Save darvin/1806112 to your computer and use it in GitHub Desktop.
HTTP Live Stream encoder
__author__ = 'darvin'
import os, errno, tempfile, subprocess
from os.path import join
from optparse import OptionParser
def mkdir_p(path):
try:
os.makedirs(path)
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST:
pass
else: raise
def flat_list(lst):
result = []
for tpl in lst:
for item in tpl:
result.append(item)
return result
#basic constants
ENCRYPTED = True
BITRATES = (
('hi', 320),
('mid', 160),
('low', 48)
)
BASE_URL = 'http://10.0.1.5/~darvin'
OUTPUT_FORMAT = "aac"
#tuning
BASE_DATA_URL = lambda track_name, bitrate_name: '{base_url}/data/{track_name}/{bitrate_name}/'.format(base_url=BASE_URL, track_name=track_name, bitrate_name=bitrate_name)
BASE_KEY_URL = lambda track_name, bitrate_name: '{base_url}/keys/{track_name}/'.format(base_url=BASE_URL, track_name=track_name, bitrate_name=bitrate_name)
BASE_DATA_PATH_WITHOUT_BITRATE = lambda track_name: join('data',track_name)
BASE_DATA_PATH = lambda track_name, bitrate_name: join('data',track_name, bitrate_name)
BASE_KEY_PATH = lambda track_name, bitrate_name: join('keys',track_name)
#commands
FFMPEG_COMMAND = lambda input, output, bitrate: \
["/usr/local/bin/ffmpeg",
"-i", input,
"-b", "{}k".format(bitrate),
output]
VARIANTPLAYLISTCREATOR_COMMAND = lambda output, paths_list :\
[
"variantplaylistcreator",
"-o", output,
] + flat_list(paths_list)
if ENCRYPTED:
MEDIAFILESEGMENTER_COMMAND = lambda input, output, base_data_url, base_key_path, key_url : \
[
"mediafilesegmenter",
input,
"-generate-variant-plist",
"-file-base", output,
"-base-url", base_data_url,
"-k", base_key_path,
"-encrypt-key-url", key_url
]
else:
MEDIAFILESEGMENTER_COMMAND = lambda input, output, base_data_url, base_key_path, key_url :\
[
"mediafilesegmenter",
input,
"-generate-variant-plist",
"-file-base", output,
"-base-url", base_data_url,
]
def process_encoded_file(track_name, filename, bitrate_name, output_dir):
result_output_path = join(output_dir, BASE_DATA_PATH(track_name, bitrate_name))
result_key_path = join(output_dir, BASE_KEY_PATH(track_name, bitrate_name))
mkdir_p(result_output_path)
if ENCRYPTED:
mkdir_p(result_key_path)
subprocess.call(MEDIAFILESEGMENTER_COMMAND(input=filename,
output=result_output_path,
base_data_url=BASE_DATA_URL(track_name, bitrate_name),
base_key_path=result_key_path,
key_url=BASE_KEY_URL(track_name, bitrate_name)))
return BASE_DATA_URL(track_name, bitrate_name)+ "prog_index.m3u8", os.path.splitext( filename)[0]+".plist"
def process_input_file(filename, output_dir):
track_name = os.path.splitext( os.path.basename(filename))[0]
output_paths = []
for bitrate_name, bitrate in BITRATES:
tfilename = tempfile.mktemp(suffix=".{}".format(OUTPUT_FORMAT))
subprocess.call(FFMPEG_COMMAND(bitrate=bitrate, input=filename, output=tfilename))
output_paths.append(process_encoded_file(track_name=track_name, filename=tfilename, bitrate_name=bitrate_name, output_dir=output_dir))
subprocess.call(
VARIANTPLAYLISTCREATOR_COMMAND(
output=join(output_dir, BASE_DATA_PATH_WITHOUT_BITRATE(track_name), "all.m3u8"),
paths_list=output_paths))
if __name__=="__main__":
parser = OptionParser()
parser.add_option("-i", "--input", dest="input",
help="input FILE or DIR", metavar="FILE_OR_DIR")
parser.add_option("-o", "--output", dest="output",
help="output FILE or DIR", metavar="FILE_OR_DIR")
(options, args) = parser.parse_args()
if os.path.isdir(options.input):
for fname in os.listdir(options.input):
process_input_file(os.path.abspath(join(options.input, fname)), output_dir=os.path.abspath(options.output))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment