b2hlslist.py
· 2.0 KiB · Python
Raw
#!/usr/bin/env python3
# let's say you have a bucket on b2 containing videos which you've converted,
# using https://github.com/vincentbernat/video2hls, to a HLS file structure
# in subdirectories named for the sha1 sum of the original file.
# This script would produce an index of files available via HLS by parsing
# the output of `b2 ls BUCKET DIRECTORY --json --recursive` (available as
# data.json), returning json like
# [
# ["d5db29cd03a2ed055086cef9c31c252b4587d6d0",
# "filename.mp4"],
# ...
# ]
# which could then be used to link to an HLS player like
# https://cdn.alyssadev.xyz/hls/#d5db29cd03a2ed055086cef9c31c252b4587d6d0
#
# data.json is loaded separately on each request because it's a fairly costly
# operation to generate a file listing of a large directory, so generation of
# that file might be best left to a separate process running infrequently.
from flask import *
# pip3 install b2
from b2sdk.v1 import SqliteAccountInfo, AuthInfoCache, B2RawApi, B2Http, B2Api
from json import load
import os
BUCKET = "ads-share"
HLS_PATH = "hls/"
app = Flask(__name__)
def get_api():
info = SqliteAccountInfo()
cache = AuthInfoCache(info)
raw_api = B2RawApi(B2Http(
user_agent_append=os.environ.get("B2_USER_AGENT_APPEND")
))
return B2Api(info, cache=cache, raw_api=raw_api)
def get_hashes():
api = get_api()
bucket = api.get_bucket_by_name(BUCKET)
generator = bucket.ls(HLS_PATH, recursive=True)
for file_version_info, folder_name in generator:
info = file_version_info.as_dict()
h = info["fileName"].split("/")[1]
if len(h) == 40:
yield(h)
@app.route("/")
def index():
with open("data.json") as f:
data = {i["contentSha1"]: i for i in load(f) if "contentSha1" in i}
hashes = set(get_hashes())
out = [
(data[h]["contentSha1"], data[h]["fileName"].split("/")[-1])
for h in hashes]
return jsonify(out)
if __name__ == "__main__":
app.run(debug=True)
| 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 | |
| 20 | from flask import * |
| 21 | # pip3 install b2 |
| 22 | from b2sdk.v1 import SqliteAccountInfo, AuthInfoCache, B2RawApi, B2Http, B2Api |
| 23 | from json import load |
| 24 | import os |
| 25 | |
| 26 | BUCKET = "ads-share" |
| 27 | HLS_PATH = "hls/" |
| 28 | |
| 29 | app = Flask(__name__) |
| 30 | |
| 31 | def 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 | |
| 39 | def 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("/") |
| 50 | def 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 | |
| 59 | if __name__ == "__main__": |
| 60 | app.run(debug=True) |