Skip to content

Commit

Permalink
Merge pull request #3 from nichind/rewrite
Browse files Browse the repository at this point in the history
pybalt rewrite
  • Loading branch information
nichind authored Jan 17, 2025
2 parents 7889955 + 97f7a13 commit ff7d8f7
Show file tree
Hide file tree
Showing 15 changed files with 1,541 additions and 927 deletions.
182 changes: 58 additions & 124 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,168 +1,102 @@
<div align="center" style="display: flex; flex-flow: column wrap;">
<img src='./assets/logo.png' style='border-radius: 8px; width: 124px'></img>
<h3>pybalt</h3>
<h5>CLI tool and python module for downloading media through Cobalt processing instances.</h5>

[![Get on PyPI](https://img.shields.io/pypi/v/pybalt.svg)](https://pypi.org/project/pybalt/)
[![Last commit](https://img.shields.io/github/last-commit/nichind/pybalt.svg)](https://github.com/nichind/pybalt)
[![Pip module installs total downloads](https://img.shields.io/pypi/dm/pybalt.svg)](https://pypi.org/project/pybalt/)
[![GitHub stars](https://img.shields.io/github/stars/nichind/pybalt.svg)](https://github.com/nichind/pybalt)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)

<div align="center" style="display: flex; flex-flow: column wrap;">
<h3>CLI Preview</h3>

https://github.com/user-attachments/assets/cf5fd9a9-520b-4970-b8c2-42baa80d7523
</div>

</div>
<br><br>
<h1>Installation</h1>
<h4>Install pybalt using PowerShell on Windows</h4>

Downloads [install.bat](./install.bat) and executes it.

Powershell should be run as administrator, otherwise aliases (`cobalt`, `pybalt`) in terminal will not work.

```powershell
powershell -Command "Invoke-WebRequest -Uri https://raw.githubusercontent.com/nichind/pybalt/main/install.bat -OutFile install.bat; .\install.bat"
```

<h4>Install using PIP</h4>

```shell
pip install pybalt
```

This should create aliases `pybalt` and `cobalt` in your shell.
# pybalt [![cobalt.tools](https://img.shields.io/badge/wrapper/cli-gray.svg?logo=data:image/jpeg;base64,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)](https://cobalt.tools) [![Get on PyPI](https://img.shields.io/pypi/v/pybalt.svg)](https://pypi.org/project/pybalt/) [![Pip module installs total downloads](https://img.shields.io/pypi/dm/pybalt.svg)](https://pypi.org/project/pybalt/) [![cobalt.tools](https://img.shields.io/badge/made%20by-nichind-white.svg)](https://nichind.dev) [![https://github.com/nichind/pybalt](https://img.shields.io/github/stars/nichind/pybalt)](https://github.com/nichind/pybalt)

Try running `cobalt -h` to see the help message.
<img src="./assets/cli-preview2.gif" align="right" alt="pybalt cli preview gif" height="240">

If for some reason it didn't work, try using it directly from python package:
**pybalt** is a powerful and flexible tool for downloading media files from various platforms, including but not limited to YouTube, X (formerly Twitter), Reddit, Instagram, and TikTok. It works using [cobalt processing instances](https://github.com/imputnet/cobalt) and serves both as a CLI and a Python module.

```shell
python -m pybalt
```
<br><br>
<h1>Usage & Examples</h1>
* Download media files to your desktop effortlessly using pybalt as a **command-line interface**, with support for downloading **playlists** and **links from text files**.
* Integrate pybalt into your Python projects with ease with **just 2 lines of code**.
* **Easily** replace and build custom code extensions to suit your needs.

<img src='./assets/cli-preview.gif' style='border-radius: 8px'></img>
https://github.com/user-attachments/assets/cf5fd9a9-520b-4970-b8c2-42baa80d7523

<h3>Selecting processing instance</h3>
# ⚙️ Installation

You can set **processing instance URL**, **API key**, and **user-agent** as environment variables; pybalt will use them if none are provided.
install pybalt with pip

```sh
pip install pybalt -U
```
COBALT_API_URL=YOUR_INSTANCE_URL
COBALT_API_KEY=YOUR_API_KEY
COBALT_USER_AGENT=YOUR_USER_AGENT
```

> By default, pybalt attempts to use any available instance for you provided by [public list of instances](https://instances.cobalt.best). It is recommended to host your own instance or request an `API key` from someone else's instance.
<br>
<h2>As a CLI</h2>
<details open>
<summary></summary>

Every command here uses the `cobalt` alias; you can also use `pybalt` or `python -m pybalt`.

By default, all downloads are saved in the user's downloads folder `~/Downloads`, or the one specified by the `-f` (`-folder`) flag.

Get a list of all available commands by running:

```shell
cobalt -h
```

<br>
<h3>Download video from URL</h3>

```shell
cobalt -u 'https://youtube.com/watch?v=8ZP5eqm4JqM'
```
or install pybalt on windows with the [bat file](./install.bat) included in the repo (if you dont have python installed)

You can also provide the URL as a positional argument:
1. Open powershell or cmd with the administator rights (to allow pip create aliases `cobalt` and `pybalt` in the terminal)
2. Type this command

```shell
cobalt 'https://youtube.com/watch?v=8ZP5eqm4JqM'
```sh
powershell -Command "Invoke-WebRequest -Uri https://raw.githubusercontent.com/nichind/pybalt/main/install.bat -OutFile install.bat; .\install.bat"
```

<br>
<h3>Download YouTube playlist</h3>
# ⚡️ Quickstart

```shell
cobalt -pl 'https://youtube.com/playlist?list=PL_93TBqf4ymR9GsuI9W4kQ-G3WM7d2Tqj'
```
> [!NOTE]
> pybalt will auto-detect if you are hosting a local cobalt-api instance and will try to use it first instead of instances from [public instance list](https://instances.cobalt.best) and my fallback one.
<br>
<h3>Download from text file</h3>
> [!NOTE]
> if alias `cobalt` isn't working for you in the terminal use `python -m pybalt <command>` instead.
Create a text file with URLs on each line:
> [!CAUTION]
> Remuxing (`-r`) requires for ffmpeg to be installed on your device and being in system path.
```txt
https://youtube.com/watch?v=8ZP...
.....
....
...
The cli part of this project is very intuitive and easy to-use! Let's see a few examples:
1. Download video from YouTube in maximum resolution possible (`-vQ max`) and then [remux](https://cobalt.tools/remux) it (`-r`).
```sh
cobalt "https://youtube.com/watch?v=DG2QqcHwNdE" -r -vQ max
```

Then run:

```shell
cobalt -l 'path/to/file.txt'
2. Remux video on your device
```sh
cobalt "C://Users/nichind/Videos/video.mp4" -r
```

<br>
<h3>More examples</h3>

Download all videos from a YouTube playlist in `720p` to folder `/Music/`, with filename style `classic`, using instance `https://dwnld.nichind.dev` and `API key` authorization:

```shell
cobalt -pl 'https://youtube.com/playlist?list=PL_93TBqf4ymR9GsuI9W4kQ-G3WM7d2Tqj' -q 720 -f './Music/' -fs 'classic' -i 'https://dwnld.nichind.dev' -k 'YOUR_API_KEY'
3. Download videos from the links in the text file
```sh
cobalt "c://Users/nichind/Desktop/very-important.txt"
```
> View all possible arguments using `-h`, pass them accordingly to the [api docs](https://github.com/imputnet/cobalt/blob/main/docs/api.md)
</details>
<br><br>
<h2>As a module</h2>
<details open>
<summary></summary>
# 💻 Integrate to your project

<h3>Download video from URL</h3>
pybalt originally comes as-a python module, integrating pybalt into your project is just **2 lines of code**:

```python
from pybalt import download
from asyncio import run

async def main():
path = await download('https://youtube.com/watch?v=8ZP5eqm4JqM')
print('Downloaded: ', path) # Downloaded: /Users/%USER%/Downloads/8ZP5eqm4JqM.mp4
path = await download("your-video-url", filenameStyle="pretty", remux=True, youtubeHLS=False, videoQuality="1080", status_parent=status)
print(path)

run(main())
```

You can pass arguments inside the Cobalt object:
you can also construct custom `Cobalt` instance.

```python
from pybalt import Cobalt
from asyncio import run

async def main():
cobalt = Cobalt(api_instance='YOUR_INSTANCE_URL', api_key='YOUR_API_KEY', headers={...})
path = await cobalt.download(url='https://youtube.com/watch?v=8ZP5eqm4JqM', quality='1080')
print('Downloaded: ', path) # Downloaded: /Users/%USER%/Downloads/8ZP5eqm4JqM.mp4
cobalt = Cobalt(debug=True, proxy="http://...", user_agent="idk :)")
# then use await cobalt.download(url) to download
```

run(main())
```
run detached download and monitor progress using `StatusParent`

</details>
```python
from pybalt import StatusParent

<br><br>
<h1>Contributing</h1>
status = StatusParent() # You can use default python dict instead of StatusParent!
run_detached(await download(url, status_parent=status)) # run detached with your own logic
while not status.completed:
print(f"Still downloading... size: {status.downloaded_size}, time passed: {status.time_passed}")
print(f"download finished: {status.file_path}")
```

If you have any questions or suggestions, please [open an issue](https://github.com/nichind/pybalt/issues) or [create a pull request](https://github.com/nichind/pybalt/pulls).
disable print info

<h3>Contributors</h3>
```python
await download(url, status_callback=None, done_callback=None) # You can replace callbacks with your custom sync/async funcion!
```

<img src="https://contrib.rocks/image?repo=nichind/pybalt" alt="Contributors" style="max-width: 100%;"/>
# ...

I spent too much time on this project... please consider leaving a :star:
Binary file added assets/cli-preview2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 4 additions & 10 deletions pybalt/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
from .cobalt import (
Cobalt,
Pybalt,
download,
get,
check_updates,
File,
DownloadedFile,
tl,
)
from .core.cobalt import Cobalt, Instance, StatusParent, Tunnel


__all__ = ["Cobalt", "Instance", "Downloader", "Tunnel", "StatusParent"]
Loading

0 comments on commit ff7d8f7

Please sign in to comment.