diff --git a/controller/api/video_clip_blueprint.py b/controller/api/video_clip_blueprint.py new file mode 100644 index 0000000..a90c678 --- /dev/null +++ b/controller/api/video_clip_blueprint.py @@ -0,0 +1,48 @@ +import os + +from flask import Blueprint, jsonify, request + +from util.flask import not_found_json_response, error_json_response +from workflow.video import get_video_real_duration, duration_str_to_float +from model import db +from model.VideoClip import VideoClip + +blueprint = Blueprint("api_video_clip", __name__, url_prefix="/api/video_clip") + + +@blueprint.get("/") +def get_video_clip_info(video_clip_id): + video_clip = VideoClip.get(video_clip_id) + if video_clip is None: + return not_found_json_response(id=video_clip_id) + return jsonify(video_clip.to_json()) + + +@blueprint.put("/") +def modify_video_clip(video_clip_id): + video_clip = VideoClip.get(video_clip_id) + if video_clip is None: + return not_found_json_response(id=video_clip_id) + payload = request.json + if "workflow_id" in payload: + try: + workflow_id = int(payload["workflow_id"]) + video_clip.workflow_id = workflow_id + except ValueError: + return error_json_response("workflow_id is not a int", workflow_id=payload["workflow_id"]) + if "base_path" in payload: + if not os.path.isdir(payload["base_path"]): + return error_json_response("base_path is not a dir", base_path=payload["base_path"]) + video_clip.base_path = payload["base_path"] + if "file" in payload: + if os.path.isabs(payload["file"]): + video_clip.base_path = "" + video_clip.file = payload["file"] + # file exist check + if not os.path.isfile(video_clip.full_path): + return error_json_response("file not exist", full_path=video_clip.full_path) + # update duration + duration = duration_str_to_float(get_video_real_duration(video_clip.full_path)) + video_clip.duration = duration + db.session.commit() + return jsonify(video_clip.to_json()) \ No newline at end of file diff --git a/controller/api/workflow_blueprint.py b/controller/api/workflow_blueprint.py index 8944bdd..517213e 100644 --- a/controller/api/workflow_blueprint.py +++ b/controller/api/workflow_blueprint.py @@ -3,6 +3,7 @@ import threading from flask import Blueprint, jsonify from model.Workflow import Workflow +from util.flask import not_found_json_response from workflow.worker import do_workflow from model import db @@ -18,18 +19,36 @@ def get_workflow_list(): @blueprint.get("/") def get_workflow_info(workflow_id): workflow = Workflow.get(workflow_id) + if workflow is None: + return not_found_json_response(id=workflow_id) return jsonify(workflow) +@blueprint.put("/") +def modify_workflow_info(workflow_id): + workflow = Workflow.get(workflow_id) + if workflow is None: + return not_found_json_response(id=workflow_id) + return jsonify(workflow) + + +@blueprint.delete("/") +def delete_workflow(workflow_id): + workflow = Workflow.get(workflow_id) + if workflow is not None: + db.session.delete(workflow) + db.session.commit() + return jsonify({ + "id": workflow_id, + "old_data": workflow + }) + + @blueprint.post("//edit") def start_editing(workflow_id): workflow = Workflow.get(workflow_id) if workflow is None: - response = jsonify({ - "message": "Not Found" - }) - response.status_code = 404 - return response + return not_found_json_response(id=workflow_id) workflow.editing = True db.session.commit() return jsonify(workflow.to_dict()) @@ -39,11 +58,7 @@ def start_editing(workflow_id): def done_editing(workflow_id): workflow = Workflow.get(workflow_id) if workflow is None: - response = jsonify({ - "message": "Not Found" - }) - response.status_code = 404 - return response + return not_found_json_response(id=workflow_id) workflow.editing = False db.session.commit() return jsonify(workflow.to_dict()) @@ -53,11 +68,7 @@ def done_editing(workflow_id): def do_workflow(workflow_id): workflow = Workflow.get(workflow_id) if workflow is None: - response = jsonify({ - "message": "Not Found" - }) - response.status_code = 404 - return response + return not_found_json_response(id=workflow_id) if len(workflow.video_clips) > 0 and len(workflow.danmaku_clips) > 0: threading.Thread(target=do_workflow, args=( workflow.video_clips[0].full_path, diff --git a/model/VideoClip.py b/model/VideoClip.py index 2983391..2dc5a36 100644 --- a/model/VideoClip.py +++ b/model/VideoClip.py @@ -17,7 +17,10 @@ class VideoClip(db.Model): @property def full_path(self): - return os.path.abspath(os.path.join(self.base_path, self.file)) + if self.base_path is not None and self.base_path != "": + return os.path.abspath(os.path.join(self.base_path, self.file)) + else: + return os.path.abspath(self.file) def to_json(self): return { @@ -26,4 +29,5 @@ class VideoClip(db.Model): "file": self.file, "duration": self.duration, "offset": self.offset, + "workflow_id": self.workflow_id, } diff --git a/util/flask.py b/util/flask.py new file mode 100644 index 0000000..b521fb8 --- /dev/null +++ b/util/flask.py @@ -0,0 +1,19 @@ +from flask import jsonify + + +def not_found_json_response(**kwargs): + response = jsonify({ + "message": "Not Found", + **kwargs + }) + response.status_code = 404 + return response + + +def error_json_response(message="Error", **kwargs): + response = jsonify({ + "message": message, + **kwargs + }) + response.status_code = 403 + return response diff --git a/workflow/video.py b/workflow/video.py index 8715958..5d50eba 100644 --- a/workflow/video.py +++ b/workflow/video.py @@ -52,6 +52,12 @@ def handle_ffmpeg_output(stderr: IO[bytes]) -> None: print("Speed", speed.strip()) + +def duration_str_to_float(duration_str) -> float: + _duration = datetime.strptime(duration_str, "%H:%M:%S.%f") - datetime(1900, 1, 1) + return _duration.total_seconds() + + def quick_split_video(file): if not os.path.isfile(file): raise FileNotFoundError(file) @@ -59,8 +65,7 @@ def quick_split_video(file): _create_dt = os.path.splitext(file_name)[0] create_dt = datetime.strptime(_create_dt, "%Y%m%d_%H%M") _duration_str = get_video_real_duration(file) - _duration = datetime.strptime(_duration_str, "%H:%M:%S.%f") - datetime(1900, 1, 1) - duration = _duration.total_seconds() + duration = duration_str_to_float(_duration_str) current_sec = 0 while current_sec < duration: current_dt = (create_dt + timedelta(seconds=current_sec)).strftime("%Y%m%d_%H%M_")