From 9a6f6745f274b228bd2ca052c7ee2d6b4aac9026 Mon Sep 17 00:00:00 2001 From: coolnsx Date: Sun, 3 May 2026 16:11:35 +0530 Subject: [PATCH 1/9] feat: mp4upload provider, refactor, better mpv android support --- README.md | 12 +++++ ani-cli | 144 ++++++++++++++++++++++++++++++------------------------ 2 files changed, 93 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index fc73608da..bd8e04466 100644 --- a/README.md +++ b/README.md @@ -164,6 +164,18 @@ For players you can use the apk (playstore/fdroid) versions of mpv and vlc. Note pkg install openssl-tool ``` +**Important Note:** To get all providers working with android MPV, Please follow below steps: +- Run this command and allow storage permissions: +```sh +termux-setup-storage +``` +- Go to MPV > Settings > Advanced > mpv.conf +- add this line: +```txt +include="/storage/emulated/0/mpv/mpv.config.mp4" +``` +- Make sure to have storage (photos and videos on newer android) permission allowed to both MPV and termux. + ### Tier 2 Support: Windows, WSL, iOS, Steam Deck, FreeBSD diff --git a/ani-cli b/ani-cli index 1ef06a793..6c100968d 100755 --- a/ani-cli +++ b/ani-cli @@ -1,6 +1,6 @@ #!/bin/sh -version_number="4.14.0" +version_number="4.14.1" # UI @@ -140,9 +140,19 @@ where_mpv() { # extract the video links from response of embed urls, extract mp4 links form m3u8 lists get_links() { - response="$(curl -e "$allanime_refr" -s "https://${allanime_base}$*" -A "$agent")" - episode_link="$(printf '%s' "$response" | sed 's|},{|\ -|g' | sed -nE 's|.*link":"([^"]*)".*"resolutionStr":"([^"]*)".*|\2 >\1|p;s|.*hls","url":"([^"]*)".*"hardsub_lang":"en-US".*|\1|p')" + case "$*" in + *mp4upload*) + episode_link=$(curl -sLk "$*" -A "$agent" -e "$allanime_refr" | sed -nE 's|.*src: "([^"]*)"[[:space:]]*|Mp4Upload >\1|p') + ;; + *tools.fast4speed.rsvp*) + episode_link=$(printf "%s\n" "Yt >$*") + ;; + *) + response="$(curl -e "$allanime_refr" -s "https://${allanime_base}$*" -A "$agent")" + episode_link="$(printf '%s' "$response" | sed 's|},{|\ + |g' | sed -nE 's|.*link":"([^"]*)".*"resolutionStr":"([^"]*)".*|\2 >\1|p;s|.*hls","url":"([^"]*)".*"hardsub_lang":"en-US".*|\1|p')" + ;; + esac case "$episode_link" in *repackager.wixmp.com*) @@ -155,24 +165,20 @@ get_links() { *master.m3u8*) m3u8_refr=$(printf '%s' "$response" | sed -nE 's|.*Referer":"([^"]*)".*|\1|p') && printf '%s\n' "m3u8_refr >$m3u8_refr" >"$cache_dir/m3u8_refr" extract_link=$(printf "%s" "$episode_link" | head -1 | cut -d'>' -f2) - relative_link=$(printf "%s" "$extract_link" | sed 's|[^/]*$||') m3u8_streams="$(curl -e "$m3u8_refr" -s "$extract_link" -A "$agent")" - printf "%s" "$m3u8_streams" | grep -q "EXTM3U" && printf "%s" "$m3u8_streams" | sed 's|^#EXT-X-STREAM.*x||g; s|,.*|p|g; /^#/d; $!N; s|\n| >|;/EXT-X-I-FRAME/d' | - sed "s|>|cc>${relative_link}|g" | sort -nr - printf '%s' "$response" | sed -nE 's|.*"subtitles":\[\{"lang":"en","label":"English","default":"default","src":"([^"]*)".*|subtitle >\1|p' >"$cache_dir/suburl" + printf "%s" "$m3u8_streams" | grep -q "EXTM3U" && printf "%s" "$m3u8_streams" | sed 's|^#EXT-X-STREAM.*x||g; s|,.*|p|g; /^#/d; $!N; s|\n| >|;/EXT-X-I-FRAME/d' | sort -nr ;; *) [ -n "$episode_link" ] && printf "%s\n" "$episode_link" ;; esac - - printf "%s" "$*" | grep -q "tools.fast4speed.rsvp" && printf "%s\n" "Yt >$*" printf "\033[1;32m%s\033[0m Links Fetched\n" "$provider_name" 1>&2 } # initialises provider_name and provider_id. First argument is the provider name, 2nd is the regex that matches that provider's link provider_init() { provider_name=$1 - provider_id=$(printf "%s" "$resp" | sed -n "$2" | head -1 | cut -d':' -f2 | sed 's/../&\ -/g' | sed 's/^79$/A/g;s/^7a$/B/g;s/^7b$/C/g;s/^7c$/D/g;s/^7d$/E/g;s/^7e$/F/g;s/^7f$/G/g;s/^70$/H/g;s/^71$/I/g;s/^72$/J/g;s/^73$/K/g;s/^74$/L/g;s/^75$/M/g;s/^76$/N/g;s/^77$/O/g;s/^68$/P/g;s/^69$/Q/g;s/^6a$/R/g;s/^6b$/S/g;s/^6c$/T/g;s/^6d$/U/g;s/^6e$/V/g;s/^6f$/W/g;s/^60$/X/g;s/^61$/Y/g;s/^62$/Z/g;s/^59$/a/g;s/^5a$/b/g;s/^5b$/c/g;s/^5c$/d/g;s/^5d$/e/g;s/^5e$/f/g;s/^5f$/g/g;s/^50$/h/g;s/^51$/i/g;s/^52$/j/g;s/^53$/k/g;s/^54$/l/g;s/^55$/m/g;s/^56$/n/g;s/^57$/o/g;s/^48$/p/g;s/^49$/q/g;s/^4a$/r/g;s/^4b$/s/g;s/^4c$/t/g;s/^4d$/u/g;s/^4e$/v/g;s/^4f$/w/g;s/^40$/x/g;s/^41$/y/g;s/^42$/z/g;s/^08$/0/g;s/^09$/1/g;s/^0a$/2/g;s/^0b$/3/g;s/^0c$/4/g;s/^0d$/5/g;s/^0e$/6/g;s/^0f$/7/g;s/^00$/8/g;s/^01$/9/g;s/^15$/-/g;s/^16$/./g;s/^67$/_/g;s/^46$/~/g;s/^02$/:/g;s/^17$/\//g;s/^07$/?/g;s/^1b$/#/g;s/^63$/\[/g;s/^65$/\]/g;s/^78$/@/g;s/^19$/!/g;s/^1c$/$/g;s/^1e$/&/g;s/^10$/\(/g;s/^11$/\)/g;s/^12$/*/g;s/^13$/+/g;s/^14$/,/g;s/^03$/;/g;s/^05$/=/g;s/^1d$/%/g' | tr -d '\n' | sed "s/\/clock/\/clock\.json/") + provider_id=$(printf "%s" "$resp" | sed -n "$2" | head -1 | cut -d':' -f2-) + printf '%s' "$provider_id" | grep -qE "^--" && provider_id=$(printf "%s" "$provider_id" | sed 's/../&\ +/g' | sed 's/^--$/\n/g;s/^79$/A/g;s/^7a$/B/g;s/^7b$/C/g;s/^7c$/D/g;s/^7d$/E/g;s/^7e$/F/g;s/^7f$/G/g;s/^70$/H/g;s/^71$/I/g;s/^72$/J/g;s/^73$/K/g;s/^74$/L/g;s/^75$/M/g;s/^76$/N/g;s/^77$/O/g;s/^68$/P/g;s/^69$/Q/g;s/^6a$/R/g;s/^6b$/S/g;s/^6c$/T/g;s/^6d$/U/g;s/^6e$/V/g;s/^6f$/W/g;s/^60$/X/g;s/^61$/Y/g;s/^62$/Z/g;s/^59$/a/g;s/^5a$/b/g;s/^5b$/c/g;s/^5c$/d/g;s/^5d$/e/g;s/^5e$/f/g;s/^5f$/g/g;s/^50$/h/g;s/^51$/i/g;s/^52$/j/g;s/^53$/k/g;s/^54$/l/g;s/^55$/m/g;s/^56$/n/g;s/^57$/o/g;s/^48$/p/g;s/^49$/q/g;s/^4a$/r/g;s/^4b$/s/g;s/^4c$/t/g;s/^4d$/u/g;s/^4e$/v/g;s/^4f$/w/g;s/^40$/x/g;s/^41$/y/g;s/^42$/z/g;s/^08$/0/g;s/^09$/1/g;s/^0a$/2/g;s/^0b$/3/g;s/^0c$/4/g;s/^0d$/5/g;s/^0e$/6/g;s/^0f$/7/g;s/^00$/8/g;s/^01$/9/g;s/^15$/-/g;s/^16$/./g;s/^67$/_/g;s/^46$/~/g;s/^02$/:/g;s/^17$/\//g;s/^07$/?/g;s/^1b$/#/g;s/^63$/\[/g;s/^65$/\]/g;s/^78$/@/g;s/^19$/!/g;s/^1c$/$/g;s/^1e$/&/g;s/^10$/\(/g;s/^11$/\)/g;s/^12$/*/g;s/^13$/+/g;s/^14$/,/g;s/^03$/;/g;s/^05$/=/g;s/^1d$/%/g' | tr -d '\n' | sed "s/\/clock/\/clock\.json/") } # generates links based on given provider @@ -181,20 +187,20 @@ generate_link() { 1) provider_init "wixmp" "/Default :/p" ;; # wixmp(default)(m3u8)(multi) -> (mp4)(multi) 2) provider_init "youtube" "/Yt-mp4 :/p" ;; # youtube(mp4)(single) 3) provider_init "sharepoint" "/S-mp4 :/p" ;; # sharepoint(mp4)(single) - 5) provider_init "filemoon" "/Fm-mp4 :/p" ;; # filemoon(m3u8)(single) - *) provider_init "hianime" "/Luf-Mp4 :/p" ;; # hianime(m3u8)(multi) + 4) provider_init "mp4upload" "/Mp4 :/p" ;; # mp4upload(mp4)(single) + *) + provider_init "Filemoon" "/Fm-Hls :/p" + get_filemoon_links "$provider_id" + return 0 + ;; # filemoon(m3u8)(single) esac - if [ "$1" = "5" ] && [ -n "$provider_id" ]; then - get_filemoon_links "$provider_id" - else - [ -n "$provider_id" ] && get_links "$provider_id" - fi + [ -n "$provider_id" ] && get_links "$provider_id" } select_quality() { - # removing urls which have soft subs to avoid playing on android, iSH and vlc (m3u8 streams don't get correct referrer) - printf '%s' "$player_function" | cut -f1 -d" " | grep -qE '(android|iSH|vlc)' && links=$(printf '%s' "$links" | sed '/cc>/d;/subtitle >/d;/m3u8_refr >/d') - printf '%s' "$player_function" | cut -f1 -d" " | grep -qE '(android|iSH)' && links=$(printf '%s' "$links" | sed '/Yt >/d') + # removing urls which have referrer to avoid playing on iSH and vlc (m3u8 streams don't get correct referrer) + printf '%s' "$player_function" | cut -f1 -d" " | grep -qE '(android_vlc|iSH|vlc)' && links=$(printf '%s' "$links" | sed '/m3u8_refr >/d') + printf '%s' "$player_function" | cut -f1 -d" " | grep -qE '(android_vlc|iSH)' && links=$(printf '%s' "$links" | sed '/Yt >/d') case "$1" in best) result=$(printf "%s" "$links" | head -n1) ;; worst) result=$(printf "%s" "$links" | grep -E '^[0-9]{3,4}' | tail -n1) ;; @@ -202,27 +208,36 @@ select_quality() { esac [ -z "$result" ] && printf "Specified quality not found, defaulting to best\n" 1>&2 && result=$(printf "%s" "$links" | head -n1) - # add refr,sub flags for m3u8 and refr flag for yt - printf '%s' "$result" | grep -q "cc>" && subtitle="$(printf '%s' "$links" | sed -nE 's|subtitle >(.*)|\1|p')" && - [ -n "$subtitle" ] && subs_flag="--sub-file=$subtitle" - printf '%s' "$result" | grep -q "cc>" && m3u8_refr="$(printf '%s' "$links" | sed -nE 's|m3u8_refr >(.*)|\1|p')" && refr_flag="--referrer=$m3u8_refr" - printf "%s" "$result" | grep -q "tools.fast4speed.rsvp" && refr_flag="--referrer=$allanime_refr" + # add refr for m3u8 and refr flag for yt + case "$result" in + *mp4upload*) + refr_flag="--referrer=https://www.mp4upload.com" + ;; + *sharepoint*) + unset refr_flag + ;; + *) + refr_flag="--referrer=$allanime_refr" + ;; + esac - ! (printf '%s' "$result" | grep -qE "(cc>|tools.fast4speed.rsvp)") && unset refr_flag - ! (printf '%s' "$result" | grep -q "cc>") && unset subs_flag episode=$(printf "%s" "$result" | cut -d'>' -f2) } -decode_tobeparsed() { +process_response() { + if ! printf '%s' "$1" | grep -q '"tobeparsed"'; then + printf '%s' "$1" + return 0 + fi + tmp="$(mktemp)" - printf '%s' "$1" | base64 -d >"$tmp" + printf '%s' "$1" | sed -nE 's|.*"tobeparsed":"([^"]*)".*|\1|p' | base64 -d >"$tmp" file_size="$(wc -c <"$tmp")" iv="$(dd if="$tmp" bs=1 skip=1 count=12 2>/dev/null | od -A n -t x1 | tr -d ' \n')" ctr="${iv}00000002" ct_len=$((file_size - 13 - 16)) - plain="$(dd if="$tmp" bs=1 skip=13 count="$ct_len" 2>/dev/null | openssl enc -d -aes-256-ctr -K "$allanime_key" -iv "$ctr" -nosalt -nopad 2>/dev/null)" + dd if="$tmp" bs=1 skip=13 count="$ct_len" 2>/dev/null | openssl enc -d -aes-256-ctr -K "$allanime_key" -iv "$ctr" -nosalt -nopad 2>/dev/null rm -f "$tmp" - printf '%s' "$plain" | tr '{}' '\n' | sed -nE 's|.*"sourceUrl":"--([^"]*)".*"sourceName":"([^"]*)".*|\2 :\1|p' } b64url_to_hex() { @@ -274,23 +289,13 @@ get_episode_url() { query_vars="{\"showId\":\"$id\",\"translationType\":\"$mode\",\"episodeString\":\"$ep_no\"}" query_ext="{\"persistedQuery\":{\"version\":1,\"sha256Hash\":\"$query_hash\"}}" - encoded_vars=$(printf '%s' "$query_vars" | sed 's/"/%22/g; s/:/%3A/g; s/{/%7B/g; s/}/%7D/g; s/,/%2C/g') - encoded_ext=$(printf '%s' "$query_ext" | sed 's/"/%22/g; s/:/%3A/g; s/{/%7B/g; s/}/%7D/g; s/,/%2C/g; s/ /%20/g') - - api_url="${allanime_api}/api?variables=${encoded_vars}&extensions=${encoded_ext}" - - api_resp="$(curl -e "https://youtu-chan.com" -s -A "$agent" -H "Origin: https://youtu-chan.com" "$api_url")" + api_resp="$(curl -e "$allanime_refr" -sG -A "$agent" -H "Origin: ${allanime_refr}" "${allanime_api}/api" --data-urlencode "variables=${query_vars}" --data-urlencode "extensions=${query_ext}")" if [ -z "$api_resp" ] || ! printf "%s" "$api_resp" | grep -q "tobeparsed"; then api_resp="$(curl -e "$allanime_refr" -s -H "Content-Type: application/json" -X POST "${allanime_api}/api" --data "{\"variables\":{\"showId\":\"$id\",\"translationType\":\"$mode\",\"episodeString\":\"$ep_no\"},\"query\":\"$episode_embed_gql\"}" -A "$agent")" fi - if printf "%s" "$api_resp" | grep -q '"tobeparsed"'; then - blob="$(printf "%s" "$api_resp" | sed -nE 's|.*"tobeparsed":"([^"]*)".*|\1|p')" - resp="$(decode_tobeparsed "$blob")" - else - resp="$(printf "%s" "$api_resp" | tr '{}' '\n' | sed 's|\\u002F|\/|g;s|\\||g' | sed -nE 's|.*sourceUrl":"--([^"]*)".*sourceName":"([^"]*)".*|\2 :\1|p')" - fi + resp="$(process_response "$api_resp" | tr '{}' '\n' | sed 's|\\u002F|\/|g;s|\\||g' | sed -nE 's|.*sourceUrl":"([^"]*)".*sourceName":"([^"]*)".*|\2 :\1|p')" # generate links into sequential files cache_dir="$(mktemp -d)" providers="1 2 3 4 5" @@ -362,8 +367,6 @@ update_history() { } download() { - # download subtitle if it's set - [ -n "$subtitle" ] && curl -s "$subtitle" -o "$download_dir/$2.vtt" case $1 in *m3u8*) if command -v "yt-dlp" >/dev/null; then @@ -371,16 +374,32 @@ download() { else ffmpeg -extension_picky 0 -referer "$m3u8_refr" -loglevel error -stats -i "$1" -c copy "$download_dir/$2.mp4" fi - # embed subs into downloads - # [ -e "$download_dir/$2.vtt" ] && ffmpeg -i "$download_dir/$2.mp4" -i "$download_dir/$2.vtt" -c copy -c:s mov_text "$download_dir/$2.bak.mp4" && mv "$download_dir/$2.bak.mp4" "$download_dir/$2.mp4" ;; *) # shellcheck disable=SC2086 - aria2c --referer="$allanime_refr" --enable-rpc=false --check-certificate=false --continue $iSH_DownFix --summary-interval=0 -x 16 -s 16 "$1" --dir="$download_dir" -o "$2.mp4" --download-result=hide + aria2c --referer="${refr_flag#--referrer=}" --enable-rpc=false --check-certificate=false --continue $iSH_DownFix --summary-interval=0 -x 16 -s 16 "$1" --dir="$download_dir" -o "$2.mp4" --download-result=hide ;; esac } +android_mpv() { + dir="/storage/emulated/0/mpv" + file="$dir/mpv.config.mp4" + if [ -w "${dir%*/mpv}" ]; then + [ -d "${dir}" ] || mkdir "${dir}" + printf "%s" "$3" | sed 's| --|\n|g; s|^--||g' >"$file" + else + printf "\n\033[1;31mCannot write\033[0m to %s\n" "$file" + printf "\033[1;36mRun:\033[0m termux-setup-storage\n\n" + printf "\033[1;36mThen:\033[0m\n" + printf "> allow storage permission\n" + printf '> add this line: include="%s"\n' "$file" + printf " to MPV > Settings > Advanced > mpv.conf\n" + fi + am start --user 0 -a android.intent.action.VIEW -d "$1" -n is.xyz.mpv/.MPVActivity -e "title" "$2" >/dev/null 2>&1 + sleep 20 && : > "$file" >/dev/null 2>&1 +} + play_episode() { [ "$log_episode" = 1 ] && [ "$player_function" != "debug" ] && [ "$player_function" != "download" ] && command -v logger >/dev/null && logger -t ani-cli "${allanime_title}${ep_no}" [ "$skip_intro" = 1 ] && skip_flag="$(ani-skip -q "$mal_id" -e "$ep_no")" @@ -393,30 +412,29 @@ play_episode() { ;; mpv*) if [ "$no_detach" = 0 ]; then - nohup $player_function $skip_flag --force-media-title="${allanime_title}Episode ${ep_no}" "$episode" $subs_flag $refr_flag >/dev/null 2>&1 & + nohup $player_function $skip_flag --tls-verify=no --force-media-title="${allanime_title}Episode ${ep_no}" "$episode" $refr_flag >/dev/null 2>&1 & else - $player_function $skip_flag $subs_flag $refr_flag --force-media-title="${allanime_title}Episode ${ep_no}" "$episode" + $player_function $skip_flag $refr_flag --tls-verify=no --force-media-title="${allanime_title}Episode ${ep_no}" "$episode" mpv_exitcode=$? [ "$exit_after_play" = 1 ] && [ -z "$range" ] && exit "$mpv_exitcode" fi ;; - android_mpv) nohup am start --user 0 -a android.intent.action.VIEW -d "$episode" -n is.xyz.mpv/.MPVActivity >/dev/null 2>&1 & ;; + android_mpv) nohup "$player_function" "$episode" "${allanime_title}Episode ${ep_no}" "--tls-verify=no $refr_flag" 2>&1 & ;; android_vlc) nohup am start --user 0 -a android.intent.action.VIEW -d "$episode" -n org.videolan.vlc/org.videolan.vlc.gui.video.VideoPlayerActivity -e "title" "${allanime_title}Episode ${ep_no}" >/dev/null 2>&1 & ;; *iina*) - [ -n "$subs_flag" ] && subs_flag="--mpv-${subs_flag#--}" [ -n "$refr_flag" ] && refr_flag="--mpv-${refr_flag#--}" if pgrep -f "IINA" >/dev/null 2>&1; then # omit --keep-running when an IINA instance exists to prevent hanging - nohup $player_function --no-stdin --mpv-force-media-title="${allanime_title}Episode ${ep_no}" $subs_flag $refr_flag "$episode" >/dev/null 2>&1 & + nohup $player_function --no-stdin --mpv-tls-verify=no --mpv-force-media-title="${allanime_title}Episode ${ep_no}" $refr_flag "$episode" >/dev/null 2>&1 & else - nohup $player_function --no-stdin --keep-running --mpv-force-media-title="${allanime_title}Episode ${ep_no}" $subs_flag $refr_flag "$episode" >/dev/null 2>&1 & + nohup $player_function --no-stdin --mpv-tls-verify=no --keep-running --mpv-force-media-title="${allanime_title}Episode ${ep_no}" $refr_flag "$episode" >/dev/null 2>&1 & fi ;; - flatpak_mpv) flatpak run io.mpv.Mpv --force-media-title="${allanime_title}Episode ${ep_no}" "$episode" $subs_flag $refr_flag >/dev/null 2>&1 & ;; - vlc*) nohup $player_function --http-referrer="${allanime_refr}" --play-and-exit --meta-title="${allanime_title}Episode ${ep_no}" "$episode" >/dev/null 2>&1 & ;; - *yncpla*) nohup $player_function "$episode" -- --force-media-title="${allanime_title}Episode ${ep_no}" $subs_flag $refr_flag >/dev/null 2>&1 & ;; - download) "$player_function" "$episode" "${allanime_title}Episode ${ep_no}" "$subtitle" ;; - catt) nohup catt cast "$episode" -s "$subtitle" >/dev/null 2>&1 & ;; + flatpak_mpv) flatpak run io.mpv.Mpv --tls-verify=no --force-media-title="${allanime_title}Episode ${ep_no}" "$episode" $refr_flag >/dev/null 2>&1 & ;; + vlc*) nohup $player_function --http-referrer="${refr_flag#--referrer=}" --play-and-exit --meta-title="${allanime_title}Episode ${ep_no}" "$episode" >/dev/null 2>&1 & ;; + *yncpla*) nohup $player_function "$episode" -- --tls-verify=no --force-media-title="${allanime_title}Episode ${ep_no}" $refr_flag >/dev/null 2>&1 & ;; + download) "$player_function" "$episode" "${allanime_title}Episode ${ep_no}" ;; + catt) nohup catt cast "$episode" >/dev/null 2>&1 & ;; iSH) printf "\e]8;;vlc://%s\a~~~~~~~~~~~~~~~~~~~~\n~ Tap to open VLC ~\n~~~~~~~~~~~~~~~~~~~~\e]8;;\a\n" "$episode" sleep 5 @@ -459,8 +477,8 @@ play() { # MAIN # setup -agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/121.0" -allanime_refr="https://allmanga.to" +agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:150.0) Gecko/20100101 Firefox/150.0" +allanime_refr="https://youtu-chan.com" allanime_base="allanime.day" allanime_api="https://api.${allanime_base}" allanime_key="$(printf '%s' 'Xot36i3lK3:v1' | openssl dgst -sha256 -binary | od -A n -t x1 | tr -d ' \n')" From 2351d3c1c3df9bbc700377313d8908c131114453 Mon Sep 17 00:00:00 2001 From: coolnsx Date: Sun, 3 May 2026 16:23:51 +0530 Subject: [PATCH 2/9] fix: shfmt and shellcheck --- ani-cli | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ani-cli b/ani-cli index 6c100968d..9d09ccf0a 100755 --- a/ani-cli +++ b/ani-cli @@ -165,8 +165,9 @@ get_links() { *master.m3u8*) m3u8_refr=$(printf '%s' "$response" | sed -nE 's|.*Referer":"([^"]*)".*|\1|p') && printf '%s\n' "m3u8_refr >$m3u8_refr" >"$cache_dir/m3u8_refr" extract_link=$(printf "%s" "$episode_link" | head -1 | cut -d'>' -f2) + relative_link=$(printf "%s" "$extract_link" | sed 's|[^/]*$||') m3u8_streams="$(curl -e "$m3u8_refr" -s "$extract_link" -A "$agent")" - printf "%s" "$m3u8_streams" | grep -q "EXTM3U" && printf "%s" "$m3u8_streams" | sed 's|^#EXT-X-STREAM.*x||g; s|,.*|p|g; /^#/d; $!N; s|\n| >|;/EXT-X-I-FRAME/d' | sort -nr + printf "%s" "$m3u8_streams" | grep -q "EXTM3U" && printf "%s" "$m3u8_streams" | sed 's|^#EXT-X-STREAM.*x||g; s|,.*|p|g; /^#/d; $!N; s|\n| >|;/EXT-X-I-FRAME/d' | sed "s|>|>${relative_link}|g" | sort -nr ;; *) [ -n "$episode_link" ] && printf "%s\n" "$episode_link" ;; esac @@ -397,7 +398,7 @@ android_mpv() { printf " to MPV > Settings > Advanced > mpv.conf\n" fi am start --user 0 -a android.intent.action.VIEW -d "$1" -n is.xyz.mpv/.MPVActivity -e "title" "$2" >/dev/null 2>&1 - sleep 20 && : > "$file" >/dev/null 2>&1 + sleep 20 && : >"$file" >/dev/null 2>&1 } play_episode() { From 3e14d51e9a7b5289b80097208f324dd09e6656c7 Mon Sep 17 00:00:00 2001 From: coolnsx Date: Sun, 3 May 2026 19:23:31 +0530 Subject: [PATCH 3/9] fix: add max time for mp4upload, remove nohup for android_mpv --- ani-cli | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ani-cli b/ani-cli index 9d09ccf0a..8cab3241b 100755 --- a/ani-cli +++ b/ani-cli @@ -142,7 +142,7 @@ where_mpv() { get_links() { case "$*" in *mp4upload*) - episode_link=$(curl -sLk "$*" -A "$agent" -e "$allanime_refr" | sed -nE 's|.*src: "([^"]*)"[[:space:]]*|Mp4Upload >\1|p') + episode_link=$(curl --max-time 15 -sLk "$*" -A "$agent" -e "$allanime_refr" | sed -nE 's|.*src: "([^"]*)"[[:space:]]*|Mp4Upload >\1|p') ;; *tools.fast4speed.rsvp*) episode_link=$(printf "%s\n" "Yt >$*") @@ -420,7 +420,7 @@ play_episode() { [ "$exit_after_play" = 1 ] && [ -z "$range" ] && exit "$mpv_exitcode" fi ;; - android_mpv) nohup "$player_function" "$episode" "${allanime_title}Episode ${ep_no}" "--tls-verify=no $refr_flag" 2>&1 & ;; + android_mpv) "$player_function" "$episode" "${allanime_title}Episode ${ep_no}" "--tls-verify=no $refr_flag" 2>&1 & ;; android_vlc) nohup am start --user 0 -a android.intent.action.VIEW -d "$episode" -n org.videolan.vlc/org.videolan.vlc.gui.video.VideoPlayerActivity -e "title" "${allanime_title}Episode ${ep_no}" >/dev/null 2>&1 & ;; *iina*) [ -n "$refr_flag" ] && refr_flag="--mpv-${refr_flag#--}" From 575c110eb99dc20b8c98a75f0b34160f12e7b6f8 Mon Sep 17 00:00:00 2001 From: coolnsx Date: Wed, 13 May 2026 18:32:42 +0530 Subject: [PATCH 4/9] feat: resolve comments --- README.md | 2 +- ani-cli | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bd8e04466..b2258427b 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ termux-setup-storage ```txt include="/storage/emulated/0/mpv/mpv.config.mp4" ``` -- Make sure to have storage (photos and videos on newer android) permission allowed to both MPV and termux. +- Make sure to have storage (photos and videos on newer android) permission allowed to both MPV and termux. These permissions are asked by mpv if you click on the "file picker (legacy)" option. diff --git a/ani-cli b/ani-cli index 8cab3241b..b5592db35 100755 --- a/ani-cli +++ b/ani-cli @@ -142,7 +142,7 @@ where_mpv() { get_links() { case "$*" in *mp4upload*) - episode_link=$(curl --max-time 15 -sLk "$*" -A "$agent" -e "$allanime_refr" | sed -nE 's|.*src: "([^"]*)"[[:space:]]*|Mp4Upload >\1|p') + episode_link=$(curl --max-time 10 -sLk "$*" -A "$agent" -e "$allanime_refr" | sed -nE 's|.*src: "([^"]*)"[[:space:]]*|Mp4Upload >\1|p') ;; *tools.fast4speed.rsvp*) episode_link=$(printf "%s\n" "Yt >$*") @@ -594,7 +594,7 @@ dep_ch "fzf" || true case "$player_function" in debug) ;; download) dep_ch "ffmpeg" "aria2c" ;; - android*) printf "\33[2K\rChecking of players on Android is disabled\n" ;; + android*) printf "\33[2K\rChecking of players on Android is disabled.\nANI-CLI recommends Android MPV for full compatibility.\nAdd:\n include='/storage/emulated/0/mpv/mpv.config.mp4'\nto:\n MPV > Settings > Advanced > mpv.conf\nfor full functionality.\nIgnore, If Done.\n" ;; *iSH*) printf "\33[2K\rChecking of players on iOS is disabled\n" ;; flatpak_mpv) true ;; # handled out of band in where_mpv *) dep_ch "$player_function" ;; From c518a175cf62d527d3fa4055000229ed4664de95 Mon Sep 17 00:00:00 2001 From: coolnsx Date: Wed, 13 May 2026 18:39:07 +0530 Subject: [PATCH 5/9] feat: disable filemoon provider --- ani-cli | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ani-cli b/ani-cli index b5592db35..a7cf5ed02 100755 --- a/ani-cli +++ b/ani-cli @@ -190,9 +190,9 @@ generate_link() { 3) provider_init "sharepoint" "/S-mp4 :/p" ;; # sharepoint(mp4)(single) 4) provider_init "mp4upload" "/Mp4 :/p" ;; # mp4upload(mp4)(single) *) - provider_init "Filemoon" "/Fm-Hls :/p" - get_filemoon_links "$provider_id" - return 0 + # provider_init "Filemoon" "/Fm-Hls :/p" + # get_filemoon_links "$provider_id" + # return 0 ;; # filemoon(m3u8)(single) esac [ -n "$provider_id" ] && get_links "$provider_id" @@ -299,7 +299,8 @@ get_episode_url() { resp="$(process_response "$api_resp" | tr '{}' '\n' | sed 's|\\u002F|\/|g;s|\\||g' | sed -nE 's|.*sourceUrl":"([^"]*)".*sourceName":"([^"]*)".*|\2 :\1|p')" # generate links into sequential files cache_dir="$(mktemp -d)" - providers="1 2 3 4 5" + #providers="1 2 3 4 5" + providers="1 2 3 4" for provider in $providers; do generate_link "$provider" >"$cache_dir"/"$provider" & done From 6aad03b18199f9dd9fb6465dd71924c735059bf4 Mon Sep 17 00:00:00 2001 From: coolnsx Date: Wed, 13 May 2026 19:19:34 +0530 Subject: [PATCH 6/9] feat: added trap command to clean some things --- ani-cli | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/ani-cli b/ani-cli index a7cf5ed02..ffc140516 100755 --- a/ani-cli +++ b/ani-cli @@ -136,6 +136,12 @@ where_mpv() { printf "%s" "mpv" && return 0 } +cleanup_shit() { + [ "$player_function" = "android_mpv" ] && : >"/storage/emulated/0/mpv/mpv.config.mp4" + printf "\033[0m" # clears colors + rm -f "${histfile}.new" # remove temp logfile +} + # SCRAPING # extract the video links from response of embed urls, extract mp4 links form m3u8 lists @@ -390,16 +396,9 @@ android_mpv() { if [ -w "${dir%*/mpv}" ]; then [ -d "${dir}" ] || mkdir "${dir}" printf "%s" "$3" | sed 's| --|\n|g; s|^--||g' >"$file" - else - printf "\n\033[1;31mCannot write\033[0m to %s\n" "$file" - printf "\033[1;36mRun:\033[0m termux-setup-storage\n\n" - printf "\033[1;36mThen:\033[0m\n" - printf "> allow storage permission\n" - printf '> add this line: include="%s"\n' "$file" - printf " to MPV > Settings > Advanced > mpv.conf\n" fi am start --user 0 -a android.intent.action.VIEW -d "$1" -n is.xyz.mpv/.MPVActivity -e "title" "$2" >/dev/null 2>&1 - sleep 20 && : >"$file" >/dev/null 2>&1 + unset dir file } play_episode() { @@ -601,6 +600,9 @@ case "$player_function" in *) dep_ch "$player_function" ;; esac +# idk where to put this, so I put it here... +trap 'cleanup_shit; exit 1' INT HUP + # searching case "$search" in history) @@ -662,7 +664,10 @@ while cmd=$(printf "next\nreplay\nprevious\nselect\nchange_quality\nquit" | nth new_quality="$(printf "%s" "$links" | launcher | cut -d\> -f1)" select_quality "$new_quality" ;; - *) exit 0 ;; + *) + cleanup_shit + exit 0 + ;; esac [ -z "$ep_no" ] && die "Out of range" play From e42679778041acac3212b3fa23909935ea43b64b Mon Sep 17 00:00:00 2001 From: coolnsx Date: Thu, 14 May 2026 22:37:07 +0530 Subject: [PATCH 7/9] feat: enhanced update_script function to allow for dev branch updates --- ani-cli | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ani-cli b/ani-cli index ffc140516..8a5784d82 100755 --- a/ani-cli +++ b/ani-cli @@ -105,15 +105,15 @@ version_info() { } update_script() { - update="$(curl -s -A "$agent" "https://raw.githubusercontent.com/pystardust/ani-cli/master/ani-cli")" || die "Connection error" + update="$(curl -s -A "$agent" "https://raw.githubusercontent.com/pystardust/ani-cli/$branch/ani-cli")" || die "Connection error" update="$(printf '%s\n' "$update" | diff -u "$0" -)" if [ -z "$update" ]; then - printf "Script is up to date :)\n" + printf "[branch:%s] Script is up to date :)\n" "$branch" else if printf '%s\n' "$update" | patch "$0" -; then - printf "Script has been updated\n" + printf "[branch:%s] Script has been updated\n" "$branch" else - die "Can't update for some reason!" + die "[branch:$branch] Can't update for some reason!" fi fi exit 0 @@ -508,6 +508,7 @@ hist_dir="${ANI_CLI_HIST_DIR:-${XDG_STATE_HOME:-$HOME/.local/state}/ani-cli}" histfile="$hist_dir/ani-hsts" [ ! -f "$histfile" ] && : >"$histfile" search="${ANI_CLI_DEFAULT_SOURCE:-scrape}" +branch="${ANI_CLI_BRANCH:-master}" while [ $# -gt 0 ]; do case "$1" in @@ -575,7 +576,10 @@ while [ $# -gt 0 ]; do shift ;; -N | --nextep-countdown) search=nextep ;; - -U | --update) update_script ;; + -U | --update) + branch="${2:-$branch}" + update_script + ;; *) query="$(printf "%s" "$query $1" | sed "s|^ ||;s| |+|g")" ;; esac shift From d61cc470541f1e047f7adeb99bbceaff81edf034 Mon Sep 17 00:00:00 2001 From: coolnsx Date: Fri, 15 May 2026 15:21:30 +0530 Subject: [PATCH 8/9] fix: prevent self-destruction when updating from invalid branch --- ani-cli | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ani-cli b/ani-cli index 8a5784d82..a2a103a36 100755 --- a/ani-cli +++ b/ani-cli @@ -105,7 +105,9 @@ version_info() { } update_script() { - update="$(curl -s -A "$agent" "https://raw.githubusercontent.com/pystardust/ani-cli/$branch/ani-cli")" || die "Connection error" + printf "[branch:%s] Checking for Update..\n" "$branch" + update="$(curl --fail-with-body -sL -A "$agent" "https://raw.githubusercontent.com/pystardust/ani-cli/$branch/ani-cli")" || die "[branch:$branch] Connection error: $update" + printf '%s' "$update" | grep -q "^version_number" || die "[branch:$branch] Invalid Response." update="$(printf '%s\n' "$update" | diff -u "$0" -)" if [ -z "$update" ]; then printf "[branch:%s] Script is up to date :)\n" "$branch" From 26ce0b1e623c325717a8e70260ce26126670d7a9 Mon Sep 17 00:00:00 2001 From: coolnsx Date: Sat, 23 May 2026 09:39:01 +0530 Subject: [PATCH 9/9] chore: change cleanup function name --- ani-cli | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ani-cli b/ani-cli index a2a103a36..37a18368c 100755 --- a/ani-cli +++ b/ani-cli @@ -138,7 +138,7 @@ where_mpv() { printf "%s" "mpv" && return 0 } -cleanup_shit() { +cleanup() { [ "$player_function" = "android_mpv" ] && : >"/storage/emulated/0/mpv/mpv.config.mp4" printf "\033[0m" # clears colors rm -f "${histfile}.new" # remove temp logfile @@ -607,7 +607,7 @@ case "$player_function" in esac # idk where to put this, so I put it here... -trap 'cleanup_shit; exit 1' INT HUP +trap 'cleanup; exit 1' INT HUP # searching case "$search" in @@ -671,7 +671,7 @@ while cmd=$(printf "next\nreplay\nprevious\nselect\nchange_quality\nquit" | nth select_quality "$new_quality" ;; *) - cleanup_shit + cleanup exit 0 ;; esac