from base64 import b64encode
from functools import reduce
from pprint import pformat
from time import gmtime, strftime
# parses the output of ffmpeg into a dictionary
def ffmpeg_black_frames_to_json(lines):
lines = [x.split("] ")[1].rstrip() for x in lines if "blackdetect" in x]
lines = [x.split(" ") for x in lines]
lines = [list(map(lambda x: x.split(":"), x)) for x in lines]
lines = [dict(x) for x in lines]
return lines
# parses seconds expressed as floats into a suitable format for a VMAP file
def ffmpeg_time_from_seconds(seconds):
try:
ms = str(seconds).split(".")[1]
except:
ms = "000"
return strftime("%H:%M:%S", gmtime(seconds)) + "." + str(ms)
# additional properties to each element
def hydrate_item(item):
start = float(item["black_start"])
end = float(item["black_end"])
midpoint = (start + end) / 2.0
item["timeOffset"] = ffmpeg_time_from_seconds(midpoint)
item["breakId"] = str(b64encode(str(hash(pformat(item))).encode("utf-8")))
return item
# generates adbreak tag for each item
def make_adbreak_tag(vars):
return """
""".format(
**vars
)
# generates a VMAP file
def make_ad_vmap(ads_list):
begin = """
"""
ads_tags = reduce(lambda a, b: a + b, ads_list, "")
end = "\n"
return begin + ads_tags + end
# packages all together
def build_manifest(ffmpeg_black_frames):
json_body = ffmpeg_black_frames_to_json(ffmpeg_black_frames)
prepared_json = list(map(hydrate_item, json_body))
tags = [make_adbreak_tag(x) for x in prepared_json]
manifest = make_ad_vmap(tags)
return manifest
if __name__ == "__main__":
print("# FFMPEG Utils :: ffmpeg_black_frames_to_json")
with open("../../../assets/ffmpeg-blackdetect-sample.txt", "r") as fp:
lines = fp.readlines()
json_body = ffmpeg_black_frames_to_json(lines)
print(json_body)
print("# FFMPEG Utils :: ffmpeg_time_from_seconds")
durations = [float(x["black_start"]) for x in json_body]
durations = map(ffmpeg_time_from_seconds, durations)
print(list(durations))
prepared_json = list(map(hydrate_item, json_body))
print("# FFMPEG Utils :: ffmpeg_time_from_seconds")
print(prepared_json)
tags = [make_adbreak_tag(x) for x in prepared_json]
manifest = make_ad_vmap(tags)
with open("vmap.xml", "w") as fp:
fp.write(manifest)