Use generator to export playlist and update endpoints

This commit is contained in:
Nick Mowen 2022-12-11 16:36:13 -07:00
parent 98c8a02630
commit 71b42d5293

View File

@ -1,5 +1,4 @@
import base64 import base64
from datetime import datetime, timedelta, timezone
import copy import copy
import glob import glob
import logging import logging
@ -10,7 +9,9 @@ import pytz
import time import time
import traceback import traceback
from datetime import datetime, timedelta, timezone
from functools import reduce from functools import reduce
from m3u8_generator import PlaylistGenerator
from pathlib import Path from pathlib import Path
from tzlocal import get_localzone_name from tzlocal import get_localzone_name
from urllib.parse import unquote from urllib.parse import unquote
@ -976,8 +977,8 @@ def recording_clip(camera_name, start_ts, end_ts):
return response return response
@bp.route("/vod/<camera_name>/start/<int:start_ts>/end/<int:end_ts>") @bp.route("/<camera_name>/start/<int:start_ts>/end/<int:end_ts>/master.m3u8")
@bp.route("/vod/<camera_name>/start/<float:start_ts>/end/<float:end_ts>") @bp.route("/<camera_name>/start/<float:start_ts>/end/<float:end_ts>/master.m3u8")
def vod_ts(camera_name, start_ts, end_ts): def vod_ts(camera_name, start_ts, end_ts):
recordings = ( recordings = (
Recordings.select() Recordings.select()
@ -990,41 +991,28 @@ def vod_ts(camera_name, start_ts, end_ts):
.order_by(Recordings.start_time.asc()) .order_by(Recordings.start_time.asc())
) )
clips = [] playlist_parts = []
durations = []
recording: Recordings recording: Recordings
for recording in recordings: for recording in recordings:
clip = {"type": "source", "path": recording.path} playlist_parts.append({
duration = int(recording.duration * 1000) "name": recording.path,
"duration": recording.duration
})
# Determine if we need to end the last clip early playlist = PlaylistGenerator(playlist_parts).generate()
if recording.end_time > end_ts: logger.error(f"Playlist is {playlist}")
duration -= int((recording.end_time - end_ts) * 1000)
if duration > 0: response = make_response()
clip["keyFrameDurations"] = [duration] #response.headers["Content-Description"] = "File Transfer"
clips.append(clip) response.headers["Cache-Control"] = "no-cache"
durations.append(duration) response.headers["Content-Type"] = "application/vnd.apple.mpegurl"
else: response.data = playlist
logger.warning(f"Recording clip is missing or empty: {recording.path}")
if not clips: return response
logger.error("No recordings found for the requested time range")
return "No recordings found.", 404
hour_ago = datetime.now() - timedelta(hours=1)
return jsonify(
{
"cache": hour_ago.timestamp() > start_ts,
"discontinuity": False,
"durations": durations,
"sequences": [{"clips": clips}],
}
)
@bp.route("/vod/<year_month>/<day>/<hour>/<camera_name>") @bp.route("/<year_month>/<day>/<hour>/<camera_name>/master.m3u8")
def vod_hour_no_timezone(year_month, day, hour, camera_name): def vod_hour_no_timezone(year_month, day, hour, camera_name):
return vod_hour( return vod_hour(
year_month, day, hour, camera_name, get_localzone_name().replace("/", "_") year_month, day, hour, camera_name, get_localzone_name().replace("/", "_")
@ -1032,7 +1020,7 @@ def vod_hour_no_timezone(year_month, day, hour, camera_name):
# TODO make this nicer when vod module is removed # TODO make this nicer when vod module is removed
@bp.route("/vod/<year_month>/<day>/<hour>/<camera_name>/<tz_name>") @bp.route("/<year_month>/<day>/<hour>/<camera_name>/<tz_name>/master.m3u8")
def vod_hour(year_month, day, hour, camera_name, tz_name): def vod_hour(year_month, day, hour, camera_name, tz_name):
tz_name = tz_name.replace("_", "/") tz_name = tz_name.replace("_", "/")
parts = year_month.split("-") parts = year_month.split("-")
@ -1046,7 +1034,7 @@ def vod_hour(year_month, day, hour, camera_name, tz_name):
return vod_ts(camera_name, start_ts, end_ts) return vod_ts(camera_name, start_ts, end_ts)
@bp.route("/vod/event/<id>") @bp.route("/event/<id>/master.m3u8")
def vod_event(id): def vod_event(id):
try: try:
event: Event = Event.get(Event.id == id) event: Event = Event.get(Event.id == id)