-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a031ce2
commit 6d83096
Showing
6 changed files
with
434 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import requests | ||
import json | ||
import re | ||
from termcolor import colored | ||
import functions | ||
|
||
def searchAlbums(): | ||
album = input(colored("Add albums to the Queue ", 'cyan', attrs=['bold']) + colored("(P)lay, (S)how Queue, (B)ack, (Q)uit: ", 'red')) | ||
|
||
if re.match(functions.URL_REGEX, album): | ||
return functions.albumLink(), searchAlbums() | ||
|
||
elif re.match(functions.PLAYLIST_REGEX, album): | ||
return functions.playlistLink(), searchAlbums() | ||
|
||
if album.isnumeric() == True and album != "q" and album != "Q" and album != "p" and album != "P": | ||
return functions.invalidString(), searchAlbums() | ||
|
||
elif album == "q" or album == "Q": | ||
return functions.exitProgram() | ||
|
||
elif album == "b" or album == "B" or album == "back" or album == "Back": | ||
return functions.emptyQueue(), functions.chooseOption() | ||
|
||
elif album == "p" or album == "P": | ||
return functions.playTracks(functions.item_list, functions.queue_list), functions.emptyQueue(), searchAlbums() | ||
|
||
elif album == "s" or album == "S": | ||
return functions.showQueue(functions.item_list), searchAlbums() | ||
|
||
return listAlbums(album) | ||
|
||
def listAlbums(album): | ||
search_results = functions.getAlbums(album) | ||
|
||
if re.match(functions.URL_REGEX, album): | ||
return functions.albumLink(), searchPlaylists() | ||
|
||
if len(search_results['items']) == 0: | ||
return functions.noResults(album), searchAlbums() | ||
|
||
return functions.showResultsAlbumsPlaylists(album, search_results), pickAlbum(search_results, album) | ||
|
||
def pickAlbum(json, album): | ||
option = input(colored("\nPick an option", 'cyan', attrs=['bold']) + colored(f" [0:19, (B)ack]: ", 'red')) | ||
|
||
if option.isnumeric() == False and option != "b" and option != "B": | ||
return functions.invalidInteger(), pickAlbum(json, album) | ||
|
||
elif option == "b" or option == "B": | ||
return print("\n"), searchAlbums() | ||
|
||
if int(option) >= 19: | ||
return functions.invalidRange(), pickAlbum(json, album) | ||
|
||
videoid = json['items'][int(option)]['url'] | ||
title = colored(json['items'][int(option)]['name'], 'red') | ||
author = colored(json['items'][int(option)]['uploaderName'], 'cyan') | ||
return functions.addItems(videoid, title, author), searchAlbums() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
import os | ||
from termcolor import colored | ||
import time | ||
import requests | ||
import json | ||
import songs | ||
import videos | ||
import albums | ||
import playlists | ||
|
||
queue_list = [] | ||
|
||
item_list = [] | ||
|
||
headers = { | ||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0' | ||
} | ||
|
||
YOUTUBE_REGEX = r"http(?:s?):\/\/(?:www\.)?youtu(?:be\.com\/watch\?v=|\.be\/)([\w\-\_]*)(&(amp;)?[\w\?=]*)?" | ||
|
||
URL_REGEX = r"(http|ftp|https):\/\/([\w\-_]+(?:(?:\.[\w\-_]+)+))([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?" | ||
|
||
PLAYLIST_REGEX = r" /^.*(youtu.be\/|list=)([^#\&\?]*).*/" | ||
|
||
def emptyQueue(): | ||
item_list.clear() | ||
queue_list.clear() | ||
|
||
def youtubeLink(): | ||
info = print(colored("\nYoutube URL detected, directly playing the link.", color='cyan', attrs=['bold']) + colored(' (q to quit)\n', 'red')) | ||
return info | ||
|
||
def urlLink(): | ||
info = print(colored("\nURL detected, trying to directly play the link.", color='cyan', attrs=['bold']) + colored(' (q to quit)\n', 'red')) | ||
return info | ||
|
||
def playlistLink(): | ||
info = print(colored("\nLinks are not supported. Use --playlist to search for playlists.", color='red', attrs=['bold']) + colored(' (q to quit)\n', 'red')) | ||
return info | ||
|
||
def albumLink(): | ||
info = print(colored("\nLinks are not supported. Use --album to search for albums.", color='red', attrs=['bold']) + colored(' (q to quit)\n', 'red')) | ||
return info | ||
|
||
def invalidString(): | ||
exitmsg = print(colored("\nPlease enter a valid string!\n", 'red', attrs=['bold'])) | ||
return exitmsg | ||
|
||
def invalidInteger(): | ||
exitmsg = print(colored("\nPlease enter a valid integer!", 'red', attrs=['bold'])) | ||
return exitmsg | ||
|
||
def exitProgram(): | ||
exitmsg = print(colored("\nExited.\n", 'red', attrs=['bold'])) | ||
return os.system("exit"), exitmsg | ||
|
||
def noResults(result): | ||
info = print(colored(f"Unable to find any results for {colored(result, 'cyan')}! \n", 'red', attrs=['bold'])) | ||
return info | ||
|
||
def invalidRange(): | ||
exitmsg = print(colored("\nInteger out of range!", 'red', attrs=['bold'])) | ||
return exitmsg | ||
|
||
def showQueue(item_list): | ||
if len(item_list) == 0: | ||
empty = print(colored("\nThe queue is empty!\n",'red', attrs=['bold'])) | ||
return empty | ||
else: | ||
show_queue = print(f"\n".join([f"{colored(i, 'green')}. {track} \n" for i, track in enumerate((item_list))])) | ||
return show_queue | ||
|
||
def showResults(query, result): | ||
info = print(colored("Results for", 'red') + colored(f" {query}\n", 'cyan', attrs=['bold'])) | ||
lists = print(f"\n".join([f"{colored(i, 'green')}. {item['title']} - {item['uploaderName']} ({time.strftime('%M:%S',time.gmtime(item['duration']))})" for i, item in enumerate((result['items']))])) | ||
return info, lists | ||
|
||
def showResultsAlbumsPlaylists(query, result): | ||
info = print(colored("Results for", 'red') + colored(f" {query}\n", 'cyan', attrs=['bold'])) | ||
lists = print(f"\n".join([f"{colored(i, 'green')}. {item['name']} - {item['uploaderName']}" for i, item in enumerate((result['items']))])) | ||
return info, lists | ||
|
||
def getSongs(query): | ||
print(colored("\nSearching for songs... \n", 'cyan', attrs=['bold'])) | ||
searchurl = requests.request("GET", f"https://pipedapi.kavin.rocks/search?q={query}&filter=music_songs", headers=headers).text | ||
searchjson = json.loads(searchurl) | ||
return searchjson | ||
|
||
def getVideos(query): | ||
print(colored("\nSearching for videos... \n", 'cyan', attrs=['bold'])) | ||
searchurl = requests.request("GET", f"https://pipedapi.kavin.rocks/search?q={query}&filter=videos", headers=headers).text | ||
searchjson = json.loads(searchurl) | ||
return searchjson | ||
|
||
def getAlbums(query): | ||
print(colored("\nSearching for albums... \n", 'cyan', attrs=['bold'])) | ||
searchurl = requests.request("GET", f"https://pipedapi.kavin.rocks/search?q={query}&filter=music_albums", headers=headers).text | ||
searchjson = json.loads(searchurl) | ||
return searchjson | ||
|
||
def getPlaylists(query): | ||
print(colored("\nSearching for playlists... \n", 'cyan', attrs=['bold'])) | ||
searchurl = requests.request("GET", f"https://pipedapi.kavin.rocks/search?q={query}&filter=playlists", headers=headers).text | ||
searchjson = json.loads(searchurl) | ||
return searchjson | ||
|
||
def playTracks(item_list, queue_list): | ||
if len(item_list) == 0: | ||
empty = print(colored("\nThe queue is empty!\n",'red', attrs=['bold'])) | ||
return empty | ||
queuemsg = print(colored("\nPlaying items in the queue", 'cyan', attrs=['bold']) + colored(' (q to quit)\n', 'red')) | ||
show_queue = print(f"\n".join([f"{colored(i, 'green')}. {track} \n" for i, track in enumerate((item_list))])) | ||
play_tracks = os.system(f"mpv --vo=null --cache=yes --video=no --no-video --term-osd-bar --no-resume-playback {' '.join(queue_list)} ") | ||
return queuemsg, show_queue, play_tracks | ||
|
||
def playVideos(item_list, queue_list): | ||
if len(item_list) == 0: | ||
empty = print(colored("\nThe queue is empty!\n",'red', attrs=['bold'])) | ||
return empty | ||
queuemsg = print(colored("\nPlaying items in the queue", 'cyan', attrs=['bold']) + colored(' (q to quit)\n', 'red')) | ||
show_queue = print(f"\n".join([f"{colored(i, 'green')}. {track} \n" for i, track in enumerate((item_list))])) | ||
play_videos = os.system(f"mpv --cache=yes --term-osd-bar --no-resume-playback {' '.join(queue_list)} ") | ||
return queuemsg, show_queue, play_videos | ||
|
||
def playVideosURL(url): | ||
play_videos = os.system(f"mpv --cache=yes --term-osd-bar --no-resume-playback {url} ") | ||
return play_videos | ||
|
||
def playTracksURL(url): | ||
play_videos = os.system(f"mpv --vo=null --cache=yes --video=no --no-video --term-osd-bar --no-resume-playback {url} ") | ||
return play_videos | ||
|
||
def addItems(videoid, title, author): | ||
stream_url = "https://piped.kavin.rocks" + f"{videoid}" | ||
queue_list.append(stream_url) | ||
item_list.append(f"{title} - {author}") | ||
added = print(colored(f"\n{title} - ", 'cyan') + colored(f'{author}', 'red') + colored(" has been added to the queue.\n", 'green')) | ||
return added | ||
|
||
def chooseOption(): | ||
option = input(colored("\nSelect an option ", 'cyan', attrs=['bold']) + colored("(S)ongs, (V)ideos, (P)laylists, (A)lbums, Q(uit): ", 'red')) | ||
if option == "S" or option == "s": | ||
return print("\n"), songs.searchSongs() | ||
elif option == "V" or option == "v": | ||
return print("\n"), videos.searchVideos() | ||
elif option == "P" or option == "p": | ||
return print("\n"), playlists.searchPlaylists() | ||
elif option == "A" or option == "a": | ||
return print("\n"), albums.searchAlbums() | ||
elif option == "Q" or option == "q" or option == "B" or option == "b": | ||
return exitProgram() | ||
else: | ||
info = print(colored("\nInvalid option entered!", 'red', attrs=['bold'])) | ||
return info, chooseOption() | ||
return |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import argparse | ||
import songs | ||
import videos | ||
import albums | ||
import playlists | ||
import functions | ||
|
||
parser = argparse.ArgumentParser(description="An open souce video/music streamer based on MPV and piped.") | ||
|
||
group = parser.add_mutually_exclusive_group() | ||
|
||
group.add_argument('--song', '-s', '--s', action='store_true', help="""Searches for songs based on query. Example: harmony --song "Never gonna give you up" """) | ||
|
||
group.add_argument('--video', '-v', '--v', action='store_true', help="""Searches for videos based on the query. Example: harmony --video "Never gonna give you up" """) | ||
|
||
group.add_argument('--album', '-a', '--a', action='store_true', help="""Searches for albums based on the query. Example: harmony --album "All Over The Place" """) | ||
|
||
group.add_argument('--playlist', '-p', '--p', action='store_true', help="""Searches for playlists based on the query. Example: harmony --playlist "All Over The Place" """) | ||
|
||
parser.add_argument('query', type=str) | ||
|
||
args = parser.parse_args() | ||
|
||
if args.song: | ||
songs.listTracks(args.query) | ||
|
||
elif args.video: | ||
videos.listVideos(args.query) | ||
|
||
elif args.album: | ||
albums.listAlbums(args.query) | ||
|
||
elif args.playlist: | ||
playlists.listPlaylists(args.query) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import requests | ||
import json | ||
import re | ||
from termcolor import colored | ||
import functions | ||
|
||
def searchPlaylists(): | ||
playlist = input(colored("Add playlists to the Queue ", 'cyan', attrs=['bold']) + colored("(P)lay, (S)how Queue, (B)ack, (Q)uit: ", 'red')) | ||
|
||
if re.match(functions.URL_REGEX, playlist): | ||
return functions.playlistLink(), searchPlaylists() | ||
|
||
if playlist.isnumeric() == True and playlist != "q" and playlist != "Q" and playlist != "p" and playlist != "P": | ||
return functions.invalidString(), searchPlaylists() | ||
|
||
elif playlist == "q" or playlist == "Q": | ||
return functions.exitProgram() | ||
|
||
elif playlist == "b" or playlist == "B": | ||
return functions.emptyQueue(), functions.chooseOption() | ||
|
||
elif playlist == "p" or playlist == "P": | ||
return functions.playTracks(functions.item_list, functions.queue_list), functions.emptyQueue(), searchPlaylists() | ||
|
||
elif playlist == "s" or playlist == "S": | ||
return functions.showQueue(functions.item_list), searchPlaylists() | ||
|
||
return listPlaylists(playlist) | ||
|
||
def listPlaylists(playlist): | ||
search_results = functions.getPlaylists(playlist) | ||
|
||
if re.match(functions.URL_REGEX, playlist): | ||
return functions.playlistLink(), searchPlaylists() | ||
|
||
if len(search_results['items']) == 0: | ||
return functions.noResults(playlist), searchPlaylists() | ||
|
||
return functions.showResultsAlbumsPlaylists(playlist, search_results), pickPlaylist(search_results, playlist) | ||
|
||
def pickPlaylist(json, playlist): | ||
option = input(colored("\nPick an option", 'cyan', attrs=['bold']) + colored(f" [0:19, (B)ack]: ", 'red')) | ||
|
||
if option.isnumeric() == False and option != "b" and option != "B": | ||
return functions.invalidInteger(), pickPlaylist(json, playlist) | ||
|
||
elif option == "b" or option == "B": | ||
return print("\n"), searchPlaylists() | ||
|
||
if int(option) >= 19: | ||
return functions.invalidRange(), pickPlaylist(json, playlist) | ||
|
||
videoid = json['items'][int(option)]['url'] | ||
title = colored(json['items'][int(option)]['name'], 'red') | ||
author = colored(json['items'][int(option)]['uploaderName'], 'cyan') | ||
return functions.addItems(videoid, title, author), searchPlaylists() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import requests | ||
import json | ||
import re | ||
from termcolor import colored | ||
import functions | ||
|
||
def searchSongs(): | ||
song = input(colored("Add songs to the Queue ", 'cyan', attrs=['bold']) + colored("(P)lay, (S)how Queue, (B)ack, (Q)uit: ", 'red')) | ||
|
||
if re.match(functions.YOUTUBE_REGEX, song): | ||
return functions.youtubeLink(), functions.playTracksURL(song), searchSongs() | ||
|
||
elif re.match(functions.URL_REGEX, song): | ||
return functions.urlLink(), functions.playTracksURL(song), searchSongs() | ||
|
||
elif re.match(functions.PLAYLIST_REGEX, song): | ||
return functions.playlistLink(), searchSongs() | ||
|
||
if song.isnumeric() == True and song != "e" and song != "E" and song != "p" and song != "P": | ||
return functions.invalidString(), searchSongs() | ||
|
||
elif song == "q" or song == "Q": | ||
return functions.exitProgram() | ||
|
||
elif song == "b" or song == "B": | ||
return functions.emptyQueue(), functions.chooseOption() | ||
|
||
elif song == "p" or song == "P": | ||
return functions.playTracks(functions.item_list, functions.queue_list), functions.emptyQueue(), searchSongs() | ||
|
||
elif song == "s" or song == "S": | ||
return functions.showQueue(functions.item_list), searchSongs() | ||
|
||
return listTracks(song) | ||
|
||
def listTracks(song): | ||
search_results = functions.getSongs(song) | ||
|
||
if re.match(functions.YOUTUBE_REGEX, song): | ||
return functions.youtubeLink(), functions.playTracksURL(song), searchSongs() | ||
|
||
elif re.match(functions.URL_REGEX, song): | ||
return functions.urlLink(), functions.playTracksURL(song), searchSongs() | ||
|
||
if len(search_results['items']) == 0: | ||
return functions.noResults(song), searchSongs() | ||
|
||
return functions.showResults(song, search_results), pickTrack(search_results, song) | ||
|
||
def pickTrack(json, song): | ||
option = input(colored("\nPick an option", 'cyan', attrs=['bold']) + colored(f" [0:19, (B)ack]: ", 'red')) | ||
|
||
if option.isnumeric() == False and option != "b" and option != "B": | ||
return functions.invalidInteger(), pickTrack(json, song) | ||
|
||
elif option == "b" or option == "B": | ||
return print("\n"), searchSongs() | ||
|
||
if int(option) >= 19: | ||
return functions.invalidRange(), pickTrack(json, song) | ||
|
||
videoid = json['items'][int(option)]['url'] | ||
title = colored(json['items'][int(option)]['title'], 'red') | ||
author = colored(json['items'][int(option)]['uploaderName'], 'cyan') | ||
return functions.addItems(videoid, title, author), searchSongs() |
Oops, something went wrong.