;;; Provides functions for streaming chaturbate as the desktop wallpaper (require 'cl-lib) (require 'url-parse) (require 'enlive) (require 'f) (require 'python) (require 'transparency) (defgroup cb nil "Settings for cb." :group 'multimedia) (defcustom cb-streamlink-quality "720p,1080p,best" "Video quality to use in streamlink." :type 'string :group 'cb) (defcustom cb-cons-python-script "/home/oc/git/chaturbate/cons.py" "Location of python script to use in `cb-stream-list' function." :type 'string :group 'cb) (defcustom cb-screenshot-directory "/home/oc/Pictures/screenshots/.cb/" "Directory to store screenshots in. Must have a trailing `/'" :type 'string :group 'cb) ;;; This is a mess. I should separate out the command portion, ;;; making it an argument ;;; there should also be pre and post block evaluation. (defun streamlink (url name) "Opens url with steamlink in the background window after killing previous process. Turns on transparency as well." (interactive) (let* ((inhibit-message t) (process-name "streamlink") (buffer-name (format "*%s*" process-name)) (command (if (string-equal system-type "windows-nt") " mpv --no-config --no-osc --no-border --cache=yes --mute=yes --geometry=--0+0 --fs --screenshot-template=%n --screenshot-directory=" " xwinwrap -g 1920x1080 -ov -- mpv -wid WID --input-ipc-server=/tmp/mpv --no-config --no-osc --cache=yes --mute=yes --geometry=--0+0 --no-input-default-bindings --screenshot-template=%n --screenshot-directory=" )) (command (if (boundp 'cb-player-command) cb-player-command (concat (mapconcat 'identity (split-string command) " ") cb-screenshot-directory name)))) (ignore-errors (delete-process process-name)) (set-process-sentinel (start-process "streamlink" "*streamlink*" "streamlink" url cb-streamlink-quality "--player" command) (lambda (p e) (unless (process-live-p p) (message "Streamlink process finished.") (unless (boundp 'cb-player-command) (when transparency-state (transparency-toggle)))))) (unless (boundp 'cb-player-command) (unless transparency-state (transparency-toggle))) )) (defun cb-kill () "Kills streamlink process." (interactive) (let ((inhibit-message t)) (ignore-errors (delete-process "streamlink")))) (defun cb-mute () "mute/unmute mpv" (interactive) (start-process "mpv-toggle-mute" nil "python3" "/home/oc/git/chaturbate/mpv.py" "mute")) (defun cb-screenshot () "Take a screenshot" (interactive) (start-process "mpv-screenshot" nil "python3" "/home/oc/git/chaturbate/mpv.py" "screenshot")) (defun cb-stream-list-python () "Select stream." (interactive) (let* ((streams (read (shell-command-to-string (format " %s %s" python-shell-interpreter cb-cons-python-script)))) (stream (assoc (completing-read "Select Stream: " streams) streams)) (name (car stream)) (url (cdr stream))) (streamlink url name)) ) ;;; Well, I got the sorting function working, though it depends on `f.el'. ;;; I shouldn't feel averse to using more flexible libraries jsut because ;;; they aren't vanilla, but I still do. If I had a personal package archive ;;; that worked out dependencies, then maybe I would feel better... (defun cb-stream-list-sorter (a b) (let ((default-directory cb-screenshot-directory)) (> (if (f-dir? (car a)) (length (f-entries (car a))) 0) (if (f-dir? (car b)) (length (f-entries (car b))) 0))) ) ;;; It's somewhat bewildering how clear and concise this is compared to it's python equivalent. ;;; The only thing this lacks is priority for streams with screenshots. ;;; All in due time. List sorting should be easier in lisp. ;) ;;; Learning to write sorting functions for sort was a little challenging. (defun cb-stream-list (&optional category) "Select stream. Python free version. Accepts optional category argument." (interactive) (let* ((url (url-generic-parse-url (format "https://chaturbate.com/%s" (or category "female-cams")))) (elements (enlive-query-all (enlive-fetch url) [li.room_list_room > a.no_select])) ) (let* ((streams (mapcar (lambda (e) (setf (url-filename url) (enlive-attr e 'href)) (cons (enlive-attr e 'data-room) (url-recreate-url url)) ) elements)) (streams (sort streams 'cb-stream-list-sorter)) ; sort screencapped streams higher (stream (assoc (completing-read "Select Stream: " streams) streams)) ) (streamlink (cdr stream) (car stream))) ) ) (provide 'cb)