136 lines
4.2 KiB
Python
136 lines
4.2 KiB
Python
import os
|
|
import subprocess
|
|
from flask import render_template, request, session
|
|
from functools import wraps
|
|
from pathlib import Path
|
|
from openpilot.common.params import Params
|
|
from openpilot.system.hardware import PC
|
|
from openpilot.system.hardware.hw import Paths
|
|
from openpilot.system.loggerd.uploader import listdir_by_creation
|
|
from tools.lib.route import SegmentName
|
|
|
|
|
|
# path to sunnypilot screen recordings and error logs
|
|
if PC:
|
|
SCREENRECORD_PATH = os.path.join(str(Path.home()), ".comma", "media", "0", "videos", "")
|
|
ERROR_LOGS_PATH = os.path.join(str(Path.home()), ".comma", "community", "crashes", "")
|
|
PIN_PATH = os.path.join(str(Path.home()), ".comma", "otp", "")
|
|
else:
|
|
SCREENRECORD_PATH = "/data/media/0/videos/"
|
|
ERROR_LOGS_PATH = "/data/community/crashes/"
|
|
PIN_PATH = "/data/otp/"
|
|
|
|
|
|
def login_required(f):
|
|
@wraps(f)
|
|
def decorated_route(*args, **kwargs):
|
|
if not session.get("logged_in") and Params().get_bool("FleetManagerPin"):
|
|
session["previous_page"] = request.url
|
|
return render_template("login.html")
|
|
return f(*args, **kwargs)
|
|
return decorated_route
|
|
|
|
|
|
def list_files(path, single=False):
|
|
files = os.listdir(path) if single else listdir_by_creation(path)
|
|
return sorted(files, reverse=True)
|
|
|
|
|
|
def is_valid_segment(segment):
|
|
try:
|
|
segment_to_segment_name(Paths.log_root(), segment)
|
|
return True
|
|
except AssertionError:
|
|
return False
|
|
|
|
|
|
def segment_to_segment_name(data_dir, segment):
|
|
fake_dongle = "ffffffffffffffff"
|
|
return SegmentName(str(os.path.join(data_dir, fake_dongle + "|" + segment)))
|
|
|
|
|
|
def all_segment_names():
|
|
segments = []
|
|
for segment in listdir_by_creation(Paths.log_root()):
|
|
try:
|
|
segments.append(segment_to_segment_name(Paths.log_root(), segment))
|
|
except AssertionError:
|
|
pass
|
|
return segments
|
|
|
|
|
|
def all_routes():
|
|
segment_names = all_segment_names()
|
|
route_names = [segment_name.route_name for segment_name in segment_names]
|
|
route_times = [route_name.time_str for route_name in route_names]
|
|
unique_routes = list(dict.fromkeys(route_times))
|
|
return sorted(unique_routes, reverse=True)
|
|
|
|
|
|
def segments_in_route(route):
|
|
segment_names = [segment_name for segment_name in all_segment_names() if segment_name.time_str == route]
|
|
segments = [segment_name.time_str + "--" + str(segment_name.segment_num) for segment_name in segment_names]
|
|
return segments
|
|
|
|
|
|
def ffmpeg_mp4_concat_wrap_process_builder(file_list, cameratype, chunk_size=1024*512):
|
|
command_line = ["ffmpeg"]
|
|
if not cameratype == "qcamera":
|
|
command_line += ["-f", "hevc"]
|
|
command_line += ["-r", "20"]
|
|
command_line += ["-i", "concat:" + file_list]
|
|
command_line += ["-c", "copy"]
|
|
command_line += ["-map", "0"]
|
|
if not cameratype == "qcamera":
|
|
command_line += ["-vtag", "hvc1"]
|
|
command_line += ["-f", "mp4"]
|
|
command_line += ["-movflags", "empty_moov"]
|
|
command_line += ["-"]
|
|
return subprocess.Popen(
|
|
command_line, stdout=subprocess.PIPE,
|
|
bufsize=chunk_size
|
|
)
|
|
|
|
|
|
def ffmpeg_mp4_wrap_process_builder(filename):
|
|
"""Returns a process that will wrap the given filename
|
|
inside a mp4 container, for easier playback by browsers
|
|
and other devices. Primary use case is streaming segment videos
|
|
to the vidserver tool.
|
|
filename is expected to be a pathname to one of the following
|
|
/path/to/a/qcamera.ts
|
|
/path/to/a/dcamera.hevc
|
|
/path/to/a/ecamera.hevc
|
|
/path/to/a/fcamera.hevc
|
|
"""
|
|
basename = filename.rsplit("/")[-1]
|
|
extension = basename.rsplit(".")[-1]
|
|
command_line = ["ffmpeg"]
|
|
if extension == "hevc":
|
|
command_line += ["-f", "hevc"]
|
|
command_line += ["-r", "20"]
|
|
command_line += ["-i", filename]
|
|
command_line += ["-c", "copy"]
|
|
command_line += ["-map", "0"]
|
|
if extension == "hevc":
|
|
command_line += ["-vtag", "hvc1"]
|
|
command_line += ["-f", "mp4"]
|
|
command_line += ["-movflags", "empty_moov"]
|
|
command_line += ["-"]
|
|
return subprocess.Popen(
|
|
command_line, stdout=subprocess.PIPE
|
|
)
|
|
|
|
|
|
def ffplay_mp4_wrap_process_builder(file_name):
|
|
command_line = ["ffmpeg"]
|
|
command_line += ["-i", file_name]
|
|
command_line += ["-c", "copy"]
|
|
command_line += ["-map", "0"]
|
|
command_line += ["-f", "mp4"]
|
|
command_line += ["-movflags", "empty_moov"]
|
|
command_line += ["-"]
|
|
return subprocess.Popen(
|
|
command_line, stdout=subprocess.PIPE
|
|
)
|