diff --git a/docker-compose.yml b/docker-compose.yml index 8bf2b043..0f5fd87e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,8 @@ # To run, please do either docker compose up -d (for docker's own version) or docker-compose up -d (for your OSes package managers verison) services: - poketube: - image: codeberg.org/korbs/poke:amd64 - # image: codeberg.org/korbs/poke:arm64 # Use this if you're using a Raspberry Pi or an arm architecture + poke: + image: codeberg.org/poketube/poke:amd64 + # image: codeberg.org/poketube/poke:arm64 # Works with ARM64/v8, not ARM64/v7 restart: unless-stopped volumes: - ./config.json:/poketube/config.json diff --git a/html/partials/header.ejs b/html/partials/header.ejs index 3d18e4c6..07e1c9e4 100644 --- a/html/partials/header.ejs +++ b/html/partials/header.ejs @@ -31,10 +31,7 @@
-
- - -
+ <%- include('./search.ejs') %>
@@ -122,4 +119,5 @@ color: white; gap: 6px; } - \ No newline at end of file + + \ No newline at end of file diff --git a/html/partials/search.ejs b/html/partials/search.ejs new file mode 100644 index 00000000..76779672 --- /dev/null +++ b/html/partials/search.ejs @@ -0,0 +1,88 @@ +
+ + +
+
+ + + \ No newline at end of file diff --git a/src/libpoketube/init/pages-api.js b/src/libpoketube/init/pages-api.js index 735de0a6..b7b8ad09 100644 --- a/src/libpoketube/init/pages-api.js +++ b/src/libpoketube/init/pages-api.js @@ -181,17 +181,6 @@ app.use("/sb/i/:v/:imagePath/:img", async function (req, res) { } catch {} }); - app.get("/feeds/videos.xml", async (req, res) => { - const id = req.query.channel_id; - - let url = `https://youtube.com/feeds/videos.xml?channel_id=${id}`; - - let f = await modules.fetch(url, { - method: req.method, - }); - - f.body.pipe(res); - }); app.get("/api/redirect", async (req, res) => { const red_url = atob(req.query.u); diff --git a/videobundler/.env.example b/videobundler/.env.example new file mode 100644 index 00000000..9a377018 --- /dev/null +++ b/videobundler/.env.example @@ -0,0 +1,5 @@ +TIME_BEFORE_DELETE=30 +INACTIVE_TIME_BEFORE_DELETE=3600 +PORT=45872 +# DO NOT PUT A / AT THE END OF THE URL +PROXY_URL=https://eu-proxy.poketube.fun \ No newline at end of file diff --git a/videobundler/README.md b/videobundler/README.md new file mode 100644 index 00000000..54d24caf --- /dev/null +++ b/videobundler/README.md @@ -0,0 +1,26 @@ +# poke-videobundler + +Takes 2 input streams, downloads them, and spits out a combined file. + +## Installation + +1. Make sure `ffmpeg`, `wget`, and Python 3 are all installed. +2. Download the program files to your computer - `main.py` and `.env.example`. +3. Run `python3 -m pip install flask python-dotenv waitress`. + +## Configuration + +1. Run `mv .env.example .env`, **even if you don't want to configure anything**. +2. Edit and fill in the values if needed. + +## Usage + +1. `python3 main.py`. +2. If everything went well, you shouldn't see any output at launch. +3. You will now be able to call the server at the configured port. + +## Endpoints + +- `/`: Will return `{success:true}` if alive. +- `/[ANYTHING]?id=VIDEO_ID&audio_itag=AUDIO_ITAG&video_itag=VIDEO_ITAG`: Starts the merging process. ID is the youtube video ID, and itags are self explanatory. As a response, you will get a job ID that you will be able to use in future requests to query the video or its status. When this process is finished, the inactive autodelete counter will start, which will allow you to fetch the video until the countdown is over. +> Replace `[ANYTHING]` with absolutely anything, however it has to be unique to the request. Preferably use an UUID diff --git a/videobundler/main.py b/videobundler/main.py new file mode 100644 index 00000000..236c1c1b --- /dev/null +++ b/videobundler/main.py @@ -0,0 +1,71 @@ +import asyncio +import aiohttp +from aiohttp import web +import string +import os +import random +import subprocess + +app = web.Application() +app.router._frozen = False + +def get_random_string(length): + # choose from all lowercase letter + letters = string.ascii_lowercase + result_str = "".join(random.choice(letters) for i in range(length)) + return result_str + +async def merge(request): + # register params + try: + job_id = request.rel_url.query["id"] + video_id: str = request.rel_url.query["id"] + audio_itag: str = request.rel_url.query["audio_itag"] + video_itag: str = request.rel_url.query["video_itag"] + except: + # no one gives a fuck + _ = 0 + # validate + if " " in video_id or len(video_id) > 11: + print(f"Video {video_id} flagged as invalid, dropping request") + return + if not audio_itag.isdigit(): + print(f"Audio itag {audio_itag} flagged as invalid, dropping request") + return + if not video_itag.isdigit(): + print(f"Video itag {video_itag} flagged as invalid, dropping request") + return + if os.path.isfile(f"done.{job_id}"): + return web.FileResponse( + path=f"output.{job_id}.mp4" + ) + proc_audio = await asyncio.create_subprocess_shell( + f"wget -O{job_id}.m4a \"https://eu-proxy.poketube.fun/latest_version?id={video_id}&itag={audio_itag}&local=true\"", + ) + proc_video = await asyncio.create_subprocess_shell( + f"wget -O{job_id}.mp4 \"https://eu-proxy.poketube.fun/latest_version?id={video_id}&itag={video_itag}&local=true\"" + ) + await asyncio.gather(proc_audio.wait(), proc_video.wait()) + proc_ffmpeg = await asyncio.create_subprocess_shell( + f"ffmpeg -i {job_id}.m4a -i {job_id}.mp4 -c copy output.{job_id}.mp4" + ) + await proc_ffmpeg.wait() + f = open(f"done.{job_id}", "a") + f.write(":3") + f.close() + return web.FileResponse( + path=f"output.{job_id}.mp4" + ) + +async def ping(request): + return web.Response(body='{"success": true}', content_type="application/json") + +async def init_app(): + app.router.add_get("/{id:.+}", merge) + app.router.add_get("/", ping) + return app + +if __name__ == '__main__': + loop = asyncio.get_event_loop() + app = loop.run_until_complete(init_app()) + web.run_app(app, port=3030) \ No newline at end of file