Last active
November 14, 2018 04:11
-
-
Save Hattshire/732d0bc19de3d58952f8286b91fc0005 to your computer and use it in GitHub Desktop.
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
# By Oliver Hattshire | |
# Licenced under laws of the realm of the Public domain | |
# Problem? It's your fault | |
# It only works on Windows you say? Yeah, this was a little script for my brobro, he's still into that thing | |
# | |
# Usage: | |
# - Take your youtube URL and dropit to the desktop | |
# - A shortcut will be created, drop the shortcut over this script | |
# - Magically a wav file with the sound of the video will appear on desktop | |
# | |
# Advanced usage: | |
# To use your brobro's computer as a jukebox when he leaves it powered on, just open it and add a video | |
# through "http://{BROBRO'S.COMPUTER.IPADDRESS.ORNAME}:60100/v/add/{YOUTUBE-VIDEO-ID}" using any device!! | |
# | |
# Requirements: | |
# - Youtube-dl.exe on %PATH% (https://youtube-dl.org/downloads/latest/youtube-dl.exe) | |
# - ffmpeg.exe on %PATH (https://ffmpeg.zeranoe.com/builds/) | |
# - ffprobe.exe on %PATH (SAMEASABOVE) | |
# - [Optionally] mpv.exe and friends on %PATH% (https://mpv.srsfckn.biz/) | |
import sys | |
import subprocess | |
# Opens a internet shortcut ini (name.url) and downloads it's link audio as wav | |
# - shortcut: the shortcut path | |
def download_mode(shortcut): | |
import configparser # For parsing the ini | |
with open(sys.argv[1]) as urlfile: | |
file = configparser.ConfigParser() | |
file.read_file(urlfile) | |
url=file["InternetShortcut"]["URL"] | |
subprocess.call(['youtube-dl', '-x', '--audio-format', 'wav', url]) | |
# Creates a simple HTTP server that serves as a playlist and player | |
# to play playable youtube songs on some good BACKGROUND PLAY (Youtube triggered) | |
def daemon_mode(): | |
import http.server | |
from time import sleep | |
from threading import Thread, Lock | |
HOST = "" | |
PORT = 60100 | |
BASE_URL = "https://www.youtube.com/watch?v=" | |
BASE_COMMAND = ["mpv", "--no-video", "--player-operation-mode=cplayer"] | |
PLAYLIST = [] | |
threadLock = Lock() | |
# Thread to play things without stopping the server | |
class player_thread(Thread): | |
def run(self): | |
DELAY = 2 | |
# True 'cuz sleepy and don't wanna think anymore | |
while(True): | |
active = "" | |
# Do not collide with anything | |
threadLock.acquire() | |
if len(PLAYLIST): | |
active = PLAYLIST.pop(0) | |
print("Now playing..." + active) | |
threadLock.release() | |
# If there is nothing then why run this? | |
if not active == "": | |
command = list(BASE_COMMAND) | |
command.append(active) | |
subprocess.call(command) | |
print("Stopped playing..." + active) | |
# CPU time is valuable | |
sleep(DELAY) | |
# Initialize the monster | |
player = player_thread() | |
player.start() | |
# Do the do-able server (ref from here: https://www.simplifiedpython.net/python-simple-http-server/) | |
class req_handler(http.server.BaseHTTPRequestHandler): | |
#TODO: Remove the repetition, its ugly :c | |
def do_GET(self): | |
if self.do_get_path("/v/add/"): | |
self.do_add() | |
self.do_send_message_now(200, "OK") | |
elif self.do_get_path("/v/remove/"): | |
self.do_send_message_now(200, "OK") | |
elif self.do_get_path("/v/play_now/"): | |
self.do_send_message_now(200, "OK") | |
elif self.do_get_path("/v/play_next/"): | |
self.do_send_message_now(200, "OK") | |
else: | |
self.do_send_message_now(404, "Not Found") #'Cuz favicon is deprecated, or it isn't (? | |
#NOTE: it isn't... yet (grinning-devil-face-here) | |
def do_get_path(self, path): | |
if self.path.startswith(path): | |
self.path = self.path.strip(path) | |
return True | |
return False | |
def do_send_message_now(self, code, msg): | |
self.send_response(code) | |
self.end_headers() | |
self.wfile.write(bytes(msg, 'utf-8')) | |
# Unncesary junk for future use? Hey! delete it!! | |
def do_notify(self): | |
print(PLAYLIST) | |
return | |
def do_player_next(self): | |
return | |
# More repetition!! noo, my eyes X( | |
def do_add(self): | |
PLAYLIST.append(BASE_URL + self.path) | |
self.do_notify() | |
def do_remove(self): | |
PLAYLIST.remove(BASE_URL + self.path) | |
self.do_notify() | |
def do_play_next(self): | |
PLAYLIST.insert(0, BASE_URL + self.path) | |
self.do_notify() | |
def do_play_now(self): | |
self.do_play_next() | |
self.do_player_next() | |
# https://docs.python.org/3/library/http.server.html#http.server.BaseHTTPRequestHandler | |
# Hey Python docs, how do I do a handler correctly if you say "do a do_GET" and then omit | |
# the send_response and end_headers thing? :/ | |
httpd = http.server.HTTPServer((HOST, PORT), req_handler) | |
httpd.serve_forever() | |
# Do the drop logic (when drop ocurrs it gets the file path) | |
if len(sys.argv) < 2 or "-d" in sys.argv or "--daemon" in sys.argv: | |
print("Daemon mode!") | |
daemon_mode() | |
else: | |
download_mode(sys.argv[1]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment