from flask import Flask, render_template, request, jsonify import os import json from mediascan import load_config, save_config, list_media_files, filter_media_files, human_readable_size, get_media_info_with_ffprobe, media_get_from_cache, media_create_cache, media_remove_cache, get_single_media_by_path from urllib.parse import unquote from flask_socketio import SocketIO import shutil from transcodate import transcode_file app = Flask(__name__) socketio = SocketIO(app) # Load configuration CONFIG_FILE = 'config.json' config = load_config(CONFIG_FILE) transcoding_tasks = {} @app.route('/') def index(): return render_template('index.html') @app.route("/single") def single_media(): path = request.args.get("path", "") if not path: return "Path not provided", 400 path_to_mediafile = unquote(path) media_file = get_single_media_by_path(path_to_mediafile) return render_template('single.html', file=media_file) @app.route("/single-json") def single_media_json(): path = request.args.get("path", "") if not path: return "Path not provided", 400 path_to_mediafile = unquote(path) return jsonify(get_single_media_by_path(path_to_mediafile)) @app.route('/media-list/clear-cache') def media_list_clear_cache(): return jsonify({"status": media_remove_cache(config["cache_dir"])}) @app.route('/media-list', methods=['GET']) def media_list(): filtered_files = media_get_from_cache(config["cache_dir"]) if filtered_files == None: media_files = list_media_files(config.get("directories", [])) allowed_formats = config.get("allowed_formats", []) filtered_files = filter_media_files(media_files, allowed_formats) # Add detailed media info for file in filtered_files: file["size"], file["size_unit"], file["size_bytes"] = human_readable_size(file["size"]) file_info = get_media_info_with_ffprobe(file["path"]) if file_info: file["info"] = file_info else: file["info"] = {"error": "Failed to retrieve media info"} media_create_cache(config["cache_dir"], filtered_files) return jsonify(filtered_files) @app.route('/process-media', methods=['POST']) def process_media(): data = request.json file_path = data.get('path') codec = data.get('codec') resolution = data.get('resolution') crf = data.get('crf') preset = data.get('preset-libx') cpu_used = data.get('preset-vp9') if codec == "libaom-av1": cpu_used = data.get('preset-av1') if not file_path or not os.path.exists(file_path): return jsonify({"error": "File path is invalid or file does not exist"}), 400 # Step 1: Copy the file to the transcoded directory dest_dir = config.get('transcoded_directory', 'transcoded_files') os.makedirs(dest_dir, exist_ok=True) dest_path = os.path.join(dest_dir, os.path.basename(file_path)) socketio.emit("progress", { "task": { "file": file_path }, "message": f"Copying the original file to {dest_path}. Waiting" }) shutil.copy(file_path, dest_path) # Step 2: Start transcoding socketio.start_background_task( target=transcode_file, transcoding_tasks=transcoding_tasks, socketio=socketio, file_path=file_path, codec=codec, resolution=resolution, crf=crf, preset=preset, cpu_used=cpu_used ) return jsonify({"status": "processing started", "file": file_path}), 202 @app.route('/stop-transcoding', methods=['GET']) def stop_transcoding(): task_id = request.args.get("task_id") if task_id in transcoding_tasks: task = transcoding_tasks.pop(task_id, None) if task: task["process"].terminate() return jsonify({"status": "stopped", "task_id": task_id}) return jsonify({"status": "error", "message": "Task not found"}), 404 @app.route('/configure', methods=['GET', 'POST']) def configure(): if request.method == 'POST': directories = request.json.get('directories', []) allowed_formats = request.json.get('allowed_formats', []) config['directories'] = directories config['allowed_formats'] = allowed_formats save_config(CONFIG_FILE, config) return jsonify({"status": "success"}) return jsonify(config) if __name__ == '__main__': app.run(debug=True)