]> njoseph.me Git - nimcoon.git/commitdiff
update TODO list master
authorJoseph Nuthalapati <njoseph@riseup.net>
Fri, 9 Feb 2024 04:57:42 +0000 (10:27 +0530)
committerJoseph Nuthalapati <njoseph@riseup.net>
Fri, 9 Feb 2024 04:57:42 +0000 (10:27 +0530)
CHANGELOG.md
README.md
TODO.org
nimcoon.el
nimcoon.nimble
src/lib.nim
src/nimcoon.nim
src/peertube.nim

index 301fbdfa17251fa769cb95570c2b3e3ddf73764f..22a8187c53cfbc1da90733ed13d0e87ac0a80a29 100644 (file)
@@ -1,3 +1,9 @@
+# 0.9.0
+
+- Replace youtube-dl with yt-dlp. Though this fixes the problem with YouTube throttling download speeds, it doesn't fix the throttling during streaming since mpv and vlc are still using youtube-dl. mpv has provided an option to provide an alternative youtube-dl implementation. Waiting for VLC to implement the same.
+- Shift to PeerTube's new videoId format. Support for the UUID format is dropped.
+- Dropped Peerflix as a dependency. WebTorrent is faster and better. They also added support for video player arguments on my request. See https://github.com/webtorrent/webtorrent-cli/issues/141
+
 # 0.8.3
 
 - Add fake user-agent
index 2b09f97f4d3353392f522b886303e141a4ce081f..6e88ecf972410eef8e0830bee86a7dc794e14432 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# NimCoon
+# Nimcoon
 
 Play videos from YouTube and PeerTube from the command line using your preferred desktop media player.
 
@@ -28,7 +28,7 @@ I tried all kinds of alternative YouTube players for the desktop. Most are eithe
 
 YouTube's business incentive is to make you watch as many videos as possible. If you open the YouTube website and are logged into it, you will just get distracted by recommendations and forget why you opened it in the first place. You might have wanted to watch a conference talk but end up going down a rabbit hole of other "interesting" videos customized for you. 
 
-NimCoon has a spartan design. It doesn't even show images of the search results. It doesn't let you browse YouTube. You have to explicitly search for something.
+Nimcoon has a spartan design. It doesn't even show images of the search results. It doesn't let you browse YouTube. You have to explicitly search for something.
 
 I have had better success with managing my YouTube consumption after shifting to this tool. Settings inspired by Pinafore's wellness settings.
 
@@ -71,27 +71,27 @@ I made this just for myself. The development is completely based on my needs and
 ## Installation
 
 Nim Coon depends on the following:
-- youtube-dl
+- yt-dlp
 - mpv (recommended) or vlc
-- peerflix and webtorrent (for magnet links)
+- webtorrent (for magnet links)
 
 Install MPV or VLC using your distribution's package manager.
 
-Install YouTube-dl
+Install yt-dlp
 ``` sh
-pip3 install --user youtube-dl
+pip3 install --user yt-dlp
 ```
 
-Install PeerFlix and WebTorrent
+Install WebTorrent
 ```sh
-npm install --global peerflix webtorrent-cli
+npm install --global webtorrent-cli
 ```
 
 (Optional) If you want your YouTube downloads to be faster, install `aria2` download manager.
 
 ### Installing using Nimble
 
-NimCoon can be installed from Nimble repositories:
+Nimcoon can be installed from Nimble repositories:
 
 ``` sh
 nimble install nimcoon
@@ -144,7 +144,7 @@ again.
 
 ### Command line arguments
 
-NimCoon provides both interactive and non-interactive arguments with significant
+Nimcoon provides both interactive and non-interactive arguments with significant
 overlap. But some arguments might only be present in one mode.
 
 Non-interactive arguments are specified to the nimcoon program and apply
@@ -159,7 +159,7 @@ case-by-case basis using the interactive arguments.
 | -d, --download                | Download video or music                    |
 | -a, --auto-play               | Play the next search result (YouTube only) |
 
-Feel free to use these options in any combination. NimCoon will show a helpful
+Feel free to use these options in any combination. Nimcoon will show a helpful
 error message if you pick incompatible options.
 
 Interactive arguments are provided during selection of a search result. These
@@ -178,7 +178,7 @@ options as single characters. i.e
 | -d, --download            | Download video or music                    |
 | -a, --auto-play           | Play the next search result (YouTube only) |
 
-Auto-playing videos leads to binge watching. The default option in NimCoon is to
+Auto-playing videos leads to binge watching. The default option in Nimcoon is to
 support auto-play for music only.
 
 ## Development
index ce4ef86168be4a9981a59099489b063d0f42b796..b6dbf20ba60e09c9eb85c597378ae0049fa10c6b 100644 (file)
--- a/TODO.org
+++ b/TODO.org
@@ -16,3 +16,4 @@
 - [ ] Better CLI using curses - select with arrows and press enter
   - illwill library can be used
   - see nim-mod project as an example
+- [ ] Fix JSON parsing error thrown during search
index 90f15e4b23bdbd138add01c4b9bd569e56f1b27e..5f01750cb2812a002f406a36b7035f3c7a0e75c6 100644 (file)
@@ -7,24 +7,24 @@
 
 ;;; Non-interactive functions to respond to URL clicks
 (defun nimcoon-play-url (url &rest args)
-  "Play given URL in NimCoon."
+  "Play given URL in Nimcoon."
   (start-process "nimcoon" nil "nimcoon" url))
 
-;; Play all YouTube URLs in NimCoon
+;; Play all YouTube URLs in Nimcoon
 (setq browse-url-browser-function
       (quote
        (("youtu\\.?be" . nimcoon-play-url)
         ("." . browse-url-default-browser))))
 
 (defun run-nimcoon(args query)
-  "Search by QUERY and play in NimCoon."
+  "Search by QUERY and play in Nimcoon."
   (call-process "nimcoon" nil 0 nil args query))
 
 (defun nimcoon-search(args query)
   "Search by QUERY with the given ARGS."
-  (with-output-to-temp-buffer "*NimCoon search results*"
-    (call-process "nimcoon" nil "*NimCoon search results*" t args query)
-    (with-current-buffer "*NimCoon search results*"
+  (with-output-to-temp-buffer "*Nimcoon search results*"
+    (call-process "nimcoon" nil "*Nimcoon search results*" t args query)
+    (with-current-buffer "*Nimcoon search results*"
       (org-mode))))
 
 ;;; Interactive functions
@@ -44,9 +44,9 @@
   (interactive "sSearch query: ")
   (run-nimcoon "-dlm" query))
 
-;; Assumes only one process exists. Must capture the pid of the running NimCoon process and only kill it.
+;; Assumes only one process exists. Must capture the pid of the running Nimcoon process and only kill it.
 (defun nimcoon-kill-background-processes()
-  "Kill NimCoon process running in the background. Useful for stopping background music."
+  "Kill Nimcoon process running in the background. Useful for stopping background music."
   (interactive)
   (shell-command "kill `pgrep nimcoon` `pgrep mpv` `pgrep vlc`"))
 
@@ -62,8 +62,8 @@
 
 ;;; Keybindings
 (map! :leader
-      ;;; <leader> N --- NimCoon
-      (:prefix-map ("N" . "NimCoon")
+      ;;; <leader> N --- Nimcoon
+      (:prefix-map ("N" . "Nimcoon")
        (:prefix ("d" . "Download")
         :desc "Video" "v" #'nimcoon-download-video
         :desc "Music" "m" #'nimcoon-download-music)
index e29c44c23e289c345b57b0ef7d0d2ad1ceb15ab1..92fc5295d3df7a6a12f6dcb6d65cd89c7a5f67b0 100644 (file)
@@ -1,8 +1,8 @@
 # Package
 
-version       = "0.8.3"
+version       = "0.9.0"
 author        = "Joseph Nuthalapati"
-description   = "A command-line YouTube player and more"
+description   = "A command-line player for YouTube, PeerTube and more."
 license       = "GPL-3.0"
 srcDir        = "src"
 bin           = @["nimcoon"]
index 4dbbf8be6f74ea687d8b728fcbbd5d460a9fafaa..4064ae43cdbdde02acbf5722317597f4a2d11fa1 100644 (file)
@@ -17,7 +17,7 @@ import
 
 let
   processOptions = {poStdErrToStdOut, poUsePath} # Add poEchoCmd to debug
-  PEERTUBE_REGEX = re"videos\/watch\/[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}"
+  PEERTUBE_REGEX = re"w\/[0-9a-zA-z]{22}"
 
 
 proc isInstalled(program: string): bool =
@@ -82,14 +82,12 @@ proc play*(player: string, options: Table[string, bool], url: string, title: str
 proc directPlay*(url: string, player: string, options: Table[string, bool]) =
   let url =
     if find(url, PEERTUBE_REGEX) != -1 and "webtorrent".isInstalled:
-      getPeerTubeMagnetLink(url)
+      getPeerTubeMagnetLink(url, options["musicOnly"])
     else: url
   if url.startswith("magnet:") or url.endswith(".torrent"):
     if options["musicOnly"]:
-      # TODO Replace with WebTorrent once it supports media player options
-      discard execShellCmd(&"peerflix '{url}' -a --{player} -- --no-video")
+      discard execShellCmd(&"webtorrent '{url}' --{player} --player-args='--no-video'")
     else:
-      # WebTorrent is so much faster!
       discard execProcess("webtorrent", args=[url, &"--{player}"], options=processOptions)
   else:
     play(player, options, url)
@@ -119,24 +117,24 @@ func buildDownloadArgs(url: string, options: Options): seq[string] =
 
 proc download*(args: openArray[string], title: string) =
   printTitle("Downloading", title)
-  discard execShellCmd(&"youtube-dl {args.join(\" \")}")
+  discard execShellCmd(&"yt-dlp {args.join(\" \")}")
 
 
 proc directDownload*(url: string, options: Options) =
   let args = buildDownloadArgs(url, options)
   if "aria2c".isInstalled:
-    discard execShellCmd(&"youtube-dl {args.join(\" \")} --external-downloader aria2c --external-downloader-args '-x 16 -s 16 -k 2M'")
+    discard execShellCmd(&"yt-dlp {args.join(\" \")} --external-downloader aria2c --external-downloader-args '-x 16 -s 16 -k 2M'")
   else:
-    discard execShellCmd(&"youtube-dl {args.join(\" \")}")
+    discard execShellCmd(&"yt-dlp {args.join(\" \")}")
 
 proc luckyDownload*(searchQuery: string, options: Options) =
-  let args = @[&"ytsearch:\"{searchQuery}\""] & buildDownloadArgs("", options)
-  let title = execProcess(&"youtube-dl --get-title {args.join(\" \")}").split("\n")[0]
+  let args = @[&"ytsearch1:\"{searchQuery}\""] & buildDownloadArgs("", options)
+  let title = execProcess(&"yt-dlp --get-title {args.join(\" \")}").split("\n")[0]
   download(args, title)
 
 proc luckyPlay*(searchQuery: string, player: string, options: Options) =
   let args = @[&"ytsearch:\"{searchQuery}\""] & buildDownloadArgs("", options)
-  let output = execProcess(&"youtube-dl --get-url --get-title {args.join(\" \")}").split("\n")
+  let output = execProcess(&"yt-dlp --get-url --get-title {args.join(\" \")}").split("\n")
   let
     title = output[0]
     url = &"\"{output[1]}\""
index 1fd3ba6e3beb037a05f37ff082f0eb9e3ceac443..9b3c6afdb7b8aced4571f5a1a538730fa6203104 100644 (file)
@@ -39,7 +39,7 @@ proc parseArguments(): CommandLineOptions =
     of cmdEnd: discard
 
   if searchQuery == "":
-    stderr.writeLine "NimCoon doesn't permit browsing. You must provide a search query."
+    stderr.writeLine "Nimcoon doesn't permit browsing. You must provide a search query."
     quit(1)
 
   (searchQuery, options)
index 36f1054ab2784091730af7325995478b099c2eab..16b6d238753cc74cfb2f6ecaca2e5301e3b71fcb 100644 (file)
@@ -5,14 +5,20 @@ import
   strformat,
   strutils
 
-let PEERTUBE_REGEX = re"videos\/watch\/[0-9a-f]{8}\b-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-\b[0-9a-f]{12}"
+let PEERTUBE_REGEX = re"w\/[0-9a-zA-z]{22}"
 
-proc getPeerTubeMagnetLink*(url: string): string =
+proc getPeerTubeMagnetLink*(url: string, musicOnly: bool): string =
   ## Gets the magnet link of the best possible resolution from PeerTube
-  let uuid = url.substr(find(url, PEERTUBE_REGEX) + "videos/watch/".len)
+  let uuid = url.substr(find(url, PEERTUBE_REGEX) + "w/".len)
   let domainName = url.substr(8, find(url, '/', start=8) - 1)
   let apiURL = &"https://{domainName}/api/v1/videos/{uuid}"
   let client = newHttpClient()
   let response = get(client, apiURL)
   let jsonNode = parseJson($response.body)
-  jsonNode["files"][0]["magnetUri"].getStr()
+  var files = jsonNode["files"]
+  if len(jsonNode["files"]) == 0:
+    files = jsonNode["streamingPlaylists"][0]["files"]
+  if musicOnly:
+    files[len(files)-1]["magnetUri"].getStr()
+  else:
+    files[0]["magnetUri"].getStr()