Last active 1626880045

b2hlslist.py Raw
1#!/usr/bin/env python3
2# let's say you have a bucket on b2 containing videos which you've converted,
3# using https://github.com/vincentbernat/video2hls, to a HLS file structure
4# in subdirectories named for the sha1 sum of the original file.
5# This script would produce an index of files available via HLS by parsing
6# the output of `b2 ls BUCKET DIRECTORY --json --recursive` (available as
7# data.json), returning json like
8# [
9# ["d5db29cd03a2ed055086cef9c31c252b4587d6d0",
10# "filename.mp4"],
11# ...
12# ]
13# which could then be used to link to an HLS player like
14# https://cdn.alyssadev.xyz/hls/#d5db29cd03a2ed055086cef9c31c252b4587d6d0
15#
16# data.json is loaded separately on each request because it's a fairly costly
17# operation to generate a file listing of a large directory, so generation of
18# that file might be best left to a separate process running infrequently.
19
20from flask import *
21# pip3 install b2
22from b2sdk.v1 import SqliteAccountInfo, AuthInfoCache, B2RawApi, B2Http, B2Api
23from json import load
24import os
25
26BUCKET = "ads-share"
27HLS_PATH = "hls/"
28
29app = Flask(__name__)
30
31def get_api():
32 info = SqliteAccountInfo()
33 cache = AuthInfoCache(info)
34 raw_api = B2RawApi(B2Http(
35 user_agent_append=os.environ.get("B2_USER_AGENT_APPEND")
36 ))
37 return B2Api(info, cache=cache, raw_api=raw_api)
38
39def get_hashes():
40 api = get_api()
41 bucket = api.get_bucket_by_name(BUCKET)
42 generator = bucket.ls(HLS_PATH, recursive=True)
43 for file_version_info, folder_name in generator:
44 info = file_version_info.as_dict()
45 h = info["fileName"].split("/")[1]
46 if len(h) == 40:
47 yield(h)
48
49@app.route("/")
50def index():
51 with open("data.json") as f:
52 data = {i["contentSha1"]: i for i in load(f) if "contentSha1" in i}
53 hashes = set(get_hashes())
54 out = [
55 (data[h]["contentSha1"], data[h]["fileName"].split("/")[-1])
56 for h in hashes]
57 return jsonify(out)
58
59if __name__ == "__main__":
60 app.run(debug=True)