from flask import Flask, request, Response, abort import os import mimetypes app = Flask(__name__) # Base path for your Rclone or RaiDrive mount mount_base_path = "K:\1 Film\Film 02" @app.route('/stream', methods=['GET']) def stream_file(): file_path = request.args.get('path') if not file_path: return "File path is required", 400 # Normalize the path for compatibility normalized_path = file_path.replace("\\", "/") # Construct the full local path local_path = os.path.join(mount_base_path, os.path.relpath(normalized_path, mount_base_path)) if not os.path.exists(local_path): return "File not found", 404 # Handle HTTP Range requests for seeking range_header = request.headers.get('Range', None) file_size = os.path.getsize(local_path) # Determine MIME type mime_type, _ = mimetypes.guess_type(local_path) mime_type = mime_type or "application/octet-stream" # Enforce common direct play MIME types if local_path.endswith(".mkv"): mime_type = "video/x-matroska" elif local_path.endswith(".mp4"): mime_type = "video/mkv" def generate(start, end): with open(local_path, "rb") as file: file.seek(start) while start < end: chunk_size = 65536 # 64 KB chunks for efficient reads chunk = file.read(min(chunk_size, end - start)) if not chunk: break yield chunk start += len(chunk) try: if range_header: # Parse the Range header range_match = range_header.strip().split('=')[-1] range_start, range_end = range_match.split('-') if '-' in range_match else (None, None) start = int(range_start) if range_start else 0 end = int(range_end) if range_end else file_size - 1 if start >= file_size or end >= file_size: abort(416) # Requested Range Not Satisfiable # Create partial content response response = Response(generate(start, end + 1), status=206, mimetype=mime_type) response.headers.add('Content-Range', f'bytes {start}-{end}/{file_size}') else: # Create a full content response response = Response(generate(0, file_size), status=200, mimetype=mime_type) response.headers.add('Content-Length', str(file_size)) response.headers.add('Accept-Ranges', 'bytes') return response except Exception as e: return f"Error while streaming file: {str(e)}", 500 if __name__ == '__main__': # Use this only for development. Use Gunicorn for production. app.run(host='192.168.1.163', port=5000)