Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ You can then run the `anifetch` command **directly in your terminal**.

Since pipx installs packages in an isolated environment, you won't have to worry about dependency conflicts or polluting your global python environment. `anifetch` will behave just like a native cli tool. You can upgrade your installation with `pipx upgrade anifetch`


---

### ❄️ NixOS installation via flakes
Expand Down Expand Up @@ -166,6 +165,8 @@ Any video file you give to anifetch will be stored in `~/.local/share/anifetch/a
anifetch video.mp4 -r 10 -W 40 -H 20 -c "--symbols wide --fg-only"
```

_Note : by default, the video `example.mp4` can directly be used as an example._

### Optional arguments:

- `-f` / `--file`: path to the video file (the path can be added without the `-f` argument)
Expand All @@ -178,6 +179,20 @@ anifetch video.mp4 -r 10 -W 40 -H 20 -c "--symbols wide --fg-only"
- `-ff` / `--fast-fetch`: uses `fastfetch` instead of `neofetch` if available
- `-fr` / `--force-render`: Forcefully re-renders the animation while not caring about the cache. Useful if the cache is broken.

### Cached files:

Anifetch automatically caches rendered animations to speed up future runs. Each unique combination of video and render options generates a cache stored in `~/.local/share/anifetch/`, organized by hash. This includes frames, output, and audio.

Cache-related commands:

`anifetch --cache-list` — View all cached configurations and orders them.

`anifetch --cache-delete <number>` — Delete a specific cache.

`anifetch --clear` — Delete all cached files.

Note that modifying the content of a video file but keeping the same name makes Anifetch still use the old cache. In that case, use `--force-render` to bypass the cache and generate a new version.

For full help:

```bash
Expand Down Expand Up @@ -239,7 +254,7 @@ Currently only the `symbols` format of chafa is supported, formats like kitty, i

- [ ] Use threading when seperating video into frames and process them with chafa at the same time. This should speed up caching significantly.

- [X] Fix transparent video frame seperation.
- [x] Fix transparent video frame seperation.

- [ ] Figure out a way to display animations faster. Either optimize the bash script or use Python/C.

Expand Down
2 changes: 1 addition & 1 deletion nix/packages/anifetch.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ in
fs.trace sourceFiles
python3Packages.buildPythonApplication {
name = "aniftech-wrapped";
version = "0.1.1";
version = "0.1.2";
pyproject = true;
src = fs.toSource {
root = ../../.;
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "anifetch"
version = "0.1.1"
version = "0.1.2"
description = "Animated terminal fetch with video/audio support."
authors = [{name = "Notenlish"}, {name = "Immelancholy"}, {name = "Gallophostrix", email = "[email protected]"}]
readme = "README.md"
Expand Down
3 changes: 1 addition & 2 deletions src/anifetch/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
def main():
args = parse_args()

if args.filename:
run_anifetch(args)
run_anifetch(args)


if __name__ == "__main__":
Expand Down
31 changes: 16 additions & 15 deletions src/anifetch/anifetch-static-resize2.sh
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
#!/bin/bash

FRAME_DIR="$HOME/.local/share/anifetch/output"
STATIC_TEMPLATE_FILE="$HOME/.local/share/anifetch/template.txt"

# check for num of args
if [[ $# -ne 6 && $# -ne 7 ]]; then
echo "Usage: $0 <framerate> <top> <left> <right> <bottom> <template_actual_width> [soundname]"
if [[ $# -ne 7 && $# -ne 8 ]]; then
echo "Usage: $0 <cache_path> <framerate> <top> <left> <right> <bottom> <template_actual_width> [soundname]"
exit 1
fi

framerate=$1
top=$2
left=$3
right=$4
bottom=$5
template_actual_width=$6
soundname=$7
CACHE_DIR="$1"
framerate=$2
top=$3
left=$4
right=$5
bottom=$6
template_actual_width=$7
soundname=$8

FRAME_DIR="$CACHE_DIR/output"
STATIC_TEMPLATE_FILE="$CACHE_DIR/template.txt"

num_lines=$((bottom - top))
sleep_time=$(echo "scale=4; 1 / $framerate" | bc)
Expand All @@ -34,7 +35,7 @@ cleanup() {
tput cnorm # Show cursor
if [ -t 0 ]; then
stty echo # Restore echo
stty icanon
stty icanon
fi
tput sgr0 # Reset terminal attributes
tput cup $(tput lines) 0 # Move cursor to bottom
Expand Down Expand Up @@ -217,7 +218,7 @@ trap 'on_resize' SIGWINCH
draw_static_template

# Start audio if sound is provided
if [ $# -eq 7 ]; then
if [ $# -eq 8 ]; then
ffplay -nodisp -autoexit -loop 0 -loglevel quiet "$soundname" &
fi

Expand All @@ -226,7 +227,7 @@ wanted_epoch=0
start_time=$(date +%s.%N)
while true; do

for frame in $(ls "$FRAME_DIR" | sort -n); do
for frame in $(ls "$FRAME_DIR" | sort -n); do #### for frame in $(find "$FRAME_DIR" -type f | sort -V); do
lock=true
current_top=$top
while IFS= read -r line; do
Expand Down
221 changes: 120 additions & 101 deletions src/anifetch/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,106 +6,125 @@
from .utils import get_version_of_anifetch


def parse_args():
parser = argparse.ArgumentParser(
prog="Anifetch",
description="Allows you to use neofetch with video in terminal (using chafa).",
)
parser.add_argument(
"-b",
"--benchmark",
default=False,
help="For testing. Runs Anifetch without actually starting the animation and times how long it took. Also does the same for neofetch and fastfetch. Checks anifetch for both cached and not cached version.",
action="store_true",
)
parser.add_argument(
"filename",
help="Video file to use (default: example.mp4)",
type=str,
)
parser.add_argument(
"-w",
"-W",
"--width",
default=40,
help="Width of the chafa animation.",
type=int,
)
parser.add_argument(
"-H",
"--height",
default=20,
help="Height of the chafa animation.",
type=int,
)
parser.add_argument("-v", "--verbose", default=False, action="store_true")
parser.add_argument(
"-r",
"--framerate",
default=10,
help="Sets the framerate when extracting frames from ffmpeg.",
type=int,
)
parser.add_argument(
"-pr",
"--playback-rate",
default=10,
help="Ignored when a sound is playing so that desync doesn't happen. Sets the playback rate of the animation. Not to be confused with the 'framerate' option. This basically sets for how long the script will wait before rendering new frame, while the framerate option affects how many frames are generated via ffmpeg.",
)
parser.add_argument(
"-s",
"--sound",
required=False,
nargs="?",
help="Optional. Will playback a sound file while displaying the animation. If you give only -s without any sound file it will attempt to extract the sound from the video.",
type=str,
)
parser.add_argument(
"-fr",
"--force-render",
default=False,
action="store_true",
help="Disabled by default. Anifetch saves the filename to check if the file has changed, if the name is same, it won't render it again. If enabled, the video will be forcefully rendered, whether it has the same name or not. Please note that it only checks for filename, if you changed the framerate then you'll need to force render.",
)
parser.add_argument(
"-C",
"--center",
default=False,
action="store_true",
help="Disabled by default. Use this argument to center the animation relative to the fetch output. Note that centering may slow down the execution.",
)
parser.add_argument(
"-c",
"--chafa-arguments",
default="--symbols ascii --fg-only",
help="Specify the arguments to give to chafa. For more informations, use 'chafa --help'",
)
parser.add_argument(
"--force",
default=False,
help="Add this argument if you want to use neofetch even if it is deprecated.",
action="store_true",
)
parser.add_argument(
"-ff",
"--fast-fetch",
default=False,
help="Add this argument if you want to use fastfetch instead. Note than fastfetch will be run with '--logo none'.",
action="store_true",
)
parser.add_argument(
"--chroma",
required=False,
nargs="?",
help="Add this argument to chromakey a hexadecimal color from the video using ffmpeg using syntax of '--chroma <hex color>:<similarity>:<blend>' with <hex-color> being 0xRRGGBB with a 0x as opposed to a # e.g. '--chroma 0xc82044:0.1:0.1'",
type=str,
)
parser.add_argument(
"--version",
action="version",
version="%(prog)s {version}".format(version=get_version_of_anifetch()),
)
parser = argparse.ArgumentParser(
prog="Anifetch",
description="Allows you to use neofetch with video in terminal (using chafa).",
)
parser.add_argument(
"-b",
"--benchmark",
default=False,
help="For testing. Runs Anifetch without actually starting the animation and times how long it took. Also does the same for neofetch and fastfetch. Checks anifetch for both cached and not cached version.",
action="store_true",
)
parser.add_argument(
"filename",
nargs="?",
default=None,
help="Video file to use (e.g. video.mp4).",
)
parser.add_argument(
"-w",
"-W",
"--width",
default=40,
help="Width of the chafa animation.",
type=int,
)
parser.add_argument(
"-H",
"--height",
default=20,
help="Height of the chafa animation.",
type=int,
)
parser.add_argument("-v", "--verbose", default=False, action="store_true")
parser.add_argument(
"-r",
"--framerate",
default=10,
help="Sets the framerate when extracting frames from ffmpeg.",
type=int,
)
parser.add_argument(
"-pr",
"--playback-rate",
default=10,
help="Ignored when a sound is playing so that desync doesn't happen. Sets the playback rate of the animation. Not to be confused with the 'framerate' option. This basically sets for how long the script will wait before rendering new frame, while the framerate option affects how many frames are generated via ffmpeg.",
)
parser.add_argument(
"-s",
"--sound",
required=False,
nargs="?",
help="Optional. Will playback a sound file while displaying the animation. If you give only -s without any sound file it will attempt to extract the sound from the video.",
type=str,
)
parser.add_argument(
"-fr",
"--force-render",
default=False,
action="store_true",
help="Disabled by default. Anifetch saves the filename to check if the file has changed, if the name is same, it won't render it again. If enabled, the video will be forcefully rendered, whether it has the same name or not. Please note that it only checks for filename, if you changed the framerate then you'll need to force render.",
)
parser.add_argument(
"-C",
"--center",
default=False,
action="store_true",
help="Disabled by default. Use this argument to center the animation relative to the fetch output. Note that centering may slow down the execution.",
)
parser.add_argument(
"-c",
"--chafa-arguments",
default="--symbols ascii --fg-only",
help="Specify the arguments to give to chafa. For more information, use 'chafa --help'",
)
parser.add_argument(
"--force",
default=False,
help="Add this argument if you want to use neofetch even if it is deprecated.",
action="store_true",
)
parser.add_argument(
"-ff",
"--fast-fetch",
default=False,
help="Add this argument if you want to use fastfetch instead. Note than fastfetch will be run with '--logo none'.",
action="store_true",
)
parser.add_argument(
"--chroma",
required=False,
nargs="?",
help="Add this argument to chromakey a hexadecimal color from the video using ffmpeg using syntax of '--chroma <hex color>:<similarity>:<blend>' with <hex-color> being 0xRRGGBB with a 0x as opposed to a # e.g. '--chroma 0xc82044:0.1:0.1'",
type=str,
)
parser.add_argument(
"--version",
action="version",
version="%(prog)s {version}".format(version=get_version_of_anifetch()),
)
parser.add_argument(
"--cache-list",
required=False,
action="store_true",
help="List all saved cache configurations.",
)
parser.add_argument(
"--delete",
required=False,
type=int,
nargs="+",
help="Delete one or more caches by number(s) (as listed with --cache-list)",
)
parser.add_argument(
"--clear",
required=False,
action="store_true",
help="Clear all saved cache configurations.",
)

args = parser.parse_args()

return args
def parse_args():
return parser.parse_args()
Loading