diff --git a/README.md b/README.md index 82cec27..5ab8d40 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,8 @@ MediaFlow Proxy is a powerful and flexible solution for proxifying various types - Support for HTTP/HTTPS/SOCKS5 proxy forwarding - Protect against unauthorized access and network bandwidth abuses -## Installation -### Configuration +## Configuration Set the following environment variables: @@ -41,6 +40,7 @@ Set the following environment variables: - `PROXY_URL`: Optional. HTTP/HTTPS/SOCKS5 proxy URL for forwarding network requests. - `MPD_LIVE_STREAM_DELAY`: Optional. Delay in seconds for live DASH streams. This is useful to prevent buffering issues with live streams. Default is `30` seconds. +## Installation ### Option 1: Self-Hosted Deployment @@ -51,7 +51,24 @@ Set the following environment variables: docker run -p 8888:8888 -e API_PASSWORD=your_password mhdzumair/mediaflow-proxy ``` -#### Using Poetry +#### Using pip +1. Install the package: + ``` + pip install mediaflow-proxy + ``` + +2. Set the `API_PASSWORD` and other environment variables in `.env`: + ``` + echo "API_PASSWORD=your_password" > .env + ``` + +3. Run the MediaFlow Proxy server: + ``` + mediaflow-proxy + ``` + + +#### Using git & poetry 1. Clone the repository: ``` diff --git a/mediaflow_proxy/main.py b/mediaflow_proxy/main.py index 44ccb5f..940b86e 100644 --- a/mediaflow_proxy/main.py +++ b/mediaflow_proxy/main.py @@ -1,4 +1,5 @@ import logging +from importlib import resources from fastapi import FastAPI, Depends, Security, HTTPException from fastapi.security import APIKeyQuery, APIKeyHeader @@ -42,10 +43,16 @@ async def get_favicon(): app.include_router(proxy_router, prefix="/proxy", tags=["proxy"], dependencies=[Depends(verify_api_key)]) -app.mount("/", StaticFiles(directory="static", html=True), name="static") + +static_path = resources.files("mediaflow_proxy").joinpath("static") +app.mount("/", StaticFiles(directory=str(static_path), html=True), name="static") -if __name__ == "__main__": +def run(): import uvicorn uvicorn.run(app, host="127.0.0.1", port=8888) + + +if __name__ == "__main__": + run() diff --git a/static/index.html b/mediaflow_proxy/static/index.html similarity index 100% rename from static/index.html rename to mediaflow_proxy/static/index.html diff --git a/static/logo.png b/mediaflow_proxy/static/logo.png similarity index 100% rename from static/logo.png rename to mediaflow_proxy/static/logo.png diff --git a/poetry.lock b/poetry.lock index 16e4b95..34a5c20 100644 --- a/poetry.lock +++ b/poetry.lock @@ -88,13 +88,13 @@ files = [ [[package]] name = "certifi" -version = "2024.7.4" +version = "2024.8.30" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, ] [[package]] @@ -124,13 +124,13 @@ files = [ [[package]] name = "fastapi" -version = "0.112.1" +version = "0.112.2" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false python-versions = ">=3.8" files = [ - {file = "fastapi-0.112.1-py3-none-any.whl", hash = "sha256:bcbd45817fc2a1cd5da09af66815b84ec0d3d634eb173d1ab468ae3103e183e4"}, - {file = "fastapi-0.112.1.tar.gz", hash = "sha256:b2537146f8c23389a7faa8b03d0bd38d4986e6983874557d95eed2acc46448ef"}, + {file = "fastapi-0.112.2-py3-none-any.whl", hash = "sha256:db84b470bd0e2b1075942231e90e3577e12a903c4dc8696f0d206a7904a7af1c"}, + {file = "fastapi-0.112.2.tar.gz", hash = "sha256:3d4729c038414d5193840706907a41839d839523da6ed0c2811f1168cac1798c"}, ] [package.dependencies] @@ -139,8 +139,8 @@ starlette = ">=0.37.2,<0.39.0" typing-extensions = ">=4.8.0" [package.extras] -all = ["email_validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] -standard = ["email_validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"] +all = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] +standard = ["email-validator (>=2.0.0)", "fastapi-cli[standard] (>=0.0.5)", "httpx (>=0.23.0)", "jinja2 (>=2.11.2)", "python-multipart (>=0.0.7)", "uvicorn[standard] (>=0.12.0)"] [[package]] name = "gunicorn" @@ -197,13 +197,13 @@ trio = ["trio (>=0.22.0,<0.26.0)"] [[package]] name = "httpx" -version = "0.27.0" +version = "0.27.2" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, - {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, + {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, + {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, ] [package.dependencies] @@ -219,6 +219,7 @@ brotli = ["brotli", "brotlicffi"] cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +zstd = ["zstandard (>=0.18.0)"] [[package]] name = "idna" @@ -575,4 +576,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "8cfbb5ac5e9e2098578646c06fbc895ae04531d66c9985635f06ee2b787e3c75" +content-hash = "c649fb9bb9f491a8e37b1caabd580211b40aa702b7ab32fa81e1a1f1f6124307" diff --git a/pyproject.toml b/pyproject.toml index 9e5a75c..4443165 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,28 @@ [tool.poetry] -name = "mediaflow proxy" -version = "1.0.0" +name = "mediaflow-proxy" +version = "1.4.0" description = "A high-performance proxy server for streaming media, supporting HTTP(S), HLS, and MPEG-DASH with real-time DRM decryption." authors = ["mhdzumair "] readme = "README.md" +homepage = "https://github.com/mhdzumair/mediaflow-proxy" +repository = "https://github.com/mhdzumair/mediaflow-proxy" +documentation = "https://github.com/mhdzumair/mediaflow-proxy#readme" +keywords = ["proxy", "media", "streaming", "hls", "dash", "drm"] +license = "MIT" +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.12", +] +include = ["LICENSE", "README.md", "mediaflow_proxy/static/*"] + [tool.poetry.dependencies] python = "^3.12" -fastapi = "^0.112.0" -httpx = {extras = ["socks"], version = "^0.27.0"} +fastapi = "^0.112.2" +httpx = {extras = ["socks"], version = "^0.27.2"} tenacity = "^9.0.0" xmltodict = "^0.13.0" cachetools = "^5.4.0" @@ -25,5 +39,8 @@ black = "^24.8.0" requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" +[tool.poetry.scripts] +mediaflow-proxy = "mediaflow_proxy.main:run" + [tool.black] line-length = 120