import
htmlparser,
httpClient,
+ json,
os,
osproc,
+ re,
sequtils,
- sugar,
- strformat,
std/[terminal],
strformat,
+ strformat,
strtabs,
strutils,
+ sugar,
tables,
uri,
xmltree
# poEchoCmd can be added to options for debugging
let processOptions = {poStdErrToStdOut, poUsePath}
+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}"
+
+proc isInstalled(program: string): bool =
+ execProcess("which " & program).len != 0
proc selectMediaPlayer*(): string =
- let availablePlayers = filterIt(supportedPlayers, execProcess("which " & it).len != 0)
+ let availablePlayers = supportedPlayers.filter(isInstalled)
if len(availablePlayers) == 0:
stderr.writeLine &"Please install one of the supported media players: {supportedPlayers}"
raise newException(OSError, "No supported media player found")
let response = get(client, &"https://www.youtube.com/results?hl=en&search_query={queryParam}")
return $response.body
+proc getPeerTubeMagnetLink(url: string): string =
+ # Gets the magnet link of the best possible resolutino from PeerTube
+ let uuid = url.substr(find(url, PEERTUBE_REGEX) + "videos/watch/".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()
+
func extractTitlesAndUrls*(html: string): SearchResults =
{.noSideEffect.}:
parseHtml(html).findAll("a").
urlLongen(stripZshEscaping(url))
proc directPlay*(url: string, player: string, options: Table[string, bool]) =
+ let url =
+ if find(url, PEERTUBE_REGEX) != -1 and isInstalled("webtorrent"):
+ getPeerTubeMagnetLink(url)
+ else: url
if url.startswith("magnet:") or url.endswith(".torrent"):
if options["musicOnly"]:
# TODO Replace with WebTorrent once it supports media player options