├── .gitignore ├── LICENSE ├── README.md ├── api.py ├── app.py ├── requirements.txt ├── routes.py └── run.sh /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__/ 2 | *.py[cod] 3 | *$py.class -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Aimadnet 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Yacine Live TV API 2 | 3 | This is an unofficial api wrapper for yacineapp.tv in python. With this api you are able to browse tv categories and get stream links. 4 | 5 | ## API Reference 6 | 7 | #### Get all categories 8 | 9 | ```bash 10 | GET /categories 11 | ``` 12 | 13 | #### Get category channels 14 | 15 | ```bash 16 | GET /categories/${id}/channels 17 | ``` 18 | 19 | | Parameter | Type | Description | 20 | | :-------- | :------- | :-------------------------------- | 21 | | `id` | `string` | **Required**. Id of category | 22 | 23 | #### Get channel 24 | 25 | ```bash 26 | GET /channel/${id} 27 | ``` 28 | 29 | | Parameter | Type | Description | 30 | | :-------- | :------- | :-------------------------------- | 31 | | `id` | `string` | **Required**. Id of channel | 32 | 33 | ## Run Locally 34 | 35 | Clone the project 36 | 37 | ```bash 38 | git clone https://github.com/aimadnet/yacinetv-api 39 | ``` 40 | 41 | Go to the project directory 42 | 43 | ```bash 44 | cd yacinetv-api 45 | ``` 46 | 47 | Install dependencies 48 | 49 | ```bash 50 | pip install -r requirements.txt 51 | ``` 52 | 53 | Start the FastAPI Application Server using: 54 | 55 | ```bash 56 | bash run.sh 57 | ``` 58 | 59 | ## Feedback 60 | 61 | If you have any feedback, contact me on telegram https://t.me/aimadnet 62 | 63 | ## Support Us 64 | 65 | ETH: 0x7c0564bfCFe48ffCdee95ee137e33367C0077429 -------------------------------------------------------------------------------- /api.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import base64 3 | import time 4 | import json 5 | 6 | class YacineTV: 7 | 8 | api_url = "http://ver3.yacinelive.com" 9 | key = "c!xZj+N9&G@Ev@vw" 10 | 11 | def __init__(self): 12 | pass 13 | 14 | def decrypt(self, enc, key=key): 15 | enc = base64.b64decode(enc.encode("ascii")).decode("ascii") 16 | result = "" 17 | for i in range(len(enc)): 18 | result = result + chr(ord(enc[i]) ^ ord(key[i % len(key)])) 19 | return result 20 | 21 | def req(self, path): 22 | r = requests.get(self.api_url + path) 23 | timestamp = str(int(time.time())) 24 | if "t" in r.headers: 25 | timestamp = r.headers["t"] 26 | 27 | try: 28 | return json.loads(self.decrypt(r.text, key=self.key + timestamp)) 29 | 30 | except Exception: 31 | return { 32 | "success": False, 33 | "error": "can't parse json." 34 | } 35 | 36 | def get_categories(self): 37 | return self.req("/api/categories") 38 | 39 | def get_category_channels(self, category_id): 40 | return self.req(f"/api/categories/{str(category_id)}/channels") 41 | 42 | def get_channel(self, channel_id): 43 | return self.req(f"/api/channel/{str(channel_id)}") 44 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | # ▄▄ ▄▄ ▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄ ▄▄ ▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄ ▄▄ ▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄ ▄▄▄ 2 | # █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ █ 3 | # █ █▄█ █ ▄ █ █ █ █▄█ █ ▄▄▄█▄ ▄█ █▄█ █ █ ▄ █ ▄ █ █ 4 | # █ █ █▄█ █ ▄▄█ █ █ █▄▄▄ █ █ █ █ █ █▄█ █ █▄█ █ █ 5 | # █▄ ▄█ █ █ █ █ ▄ █ ▄▄▄█ █ █ █ █ █ █ ▄▄▄█ █ 6 | # █ █ █ ▄ █ █▄▄█ █ █ █ █ █▄▄▄ █ █ █ █ █ ▄ █ █ █ █ 7 | # █▄▄▄█ █▄█ █▄▄█▄▄▄▄▄▄▄█▄▄▄█▄█ █▄▄█▄▄▄▄▄▄▄█ █▄▄▄█ █▄▄▄█ █▄▄█ █▄▄█▄▄▄█ █▄▄▄█ 8 | 9 | # by aimadnet 10 | # contact: t.me/aimadnet 11 | 12 | from fastapi import FastAPI 13 | from authx import ProfilerMiddleware 14 | 15 | import routes 16 | 17 | app = FastAPI( 18 | title="YacineTV", 19 | description="This is an unofficial api wrapper for yacineapp.tv in python", 20 | version="1.0.0", 21 | ) 22 | 23 | app.include_router(routes.router) 24 | app.add_middleware(ProfilerMiddleware) 25 | 26 | 27 | 28 | @app.get("/") 29 | async def index(): 30 | return {"message": "Hello World"} 31 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi 2 | uvicorn 3 | requests 4 | authx -------------------------------------------------------------------------------- /routes.py: -------------------------------------------------------------------------------- 1 | from fastapi import APIRouter 2 | from api import YacineTV 3 | 4 | ytv = YacineTV() 5 | router = APIRouter(tags=["YacineTV"]) 6 | 7 | 8 | @router.get("/categories") 9 | def categories(): 10 | return ytv.get_categories() 11 | 12 | @router.get("/categories/{category_id}/channels") 13 | def channels(category_id: int): 14 | return ytv.get_category_channels(category_id) 15 | 16 | @router.get("/channel/{channel_id}") 17 | def channel(channel_id: int): 18 | return ytv.get_channel(channel_id) 19 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | set -x 5 | 6 | uvicorn app:app --reload --------------------------------------------------------------------------------