Since peertube.social is closing down, I need a script for downloading all of my videos. I searched for this for a few minutes. I felt that it exists but I can't find, so I wrote mine in Common Lisp.
It probably works on other Common Lisp implementations too but I only tested on SBCL 2.0.1-5.fc34.
;; How to run
;; sbcl --load download-peertube-videos.lisp
(ql:quickload :jonathan)
(ql:quickload :dexador)
(ql:quickload :alexandria)
(ql:quickload :asdf)
(import 'alexandria:assoc-value)
(defparameter *username* "peertube-user-name")
(defparameter *hostname* "peertube.social")
(defparameter *get-videos-url* (format nil "https://~A/api/v1/accounts/~A/videos" *hostname* *username*))
(defparameter *videos-info* (assoc-value (jonathan:parse (dex:get *get-videos-url*)
:as :alist)
"data"
:test 'equal))
(defparameter *total* (assoc-value (jonathan:parse (dex:get (format nil "https://~A/api/v1/accounts/~A/videos" *hostname* *username*))
:as :alist)
"total"
:test 'equal))
(defparameter *count* 5)
(defun get-video-id (video-info)
(assoc-value video-info "id" :test 'equal))
(defun get-video-json (video-id)
(let ((video-info-url (format nil "https://~A/api/v1/videos/~A" *hostname* video-id)))
(dex:get video-info-url)))
(defun download-video (video-details)
(let* ((files (assoc-value video-details "files" :test 'equal))
(download-url (assoc-value (car files) "fileDownloadUrl" :test 'equal))
(cmd (format nil "wget ~A" download-url)))
(format t "CMD: ~A~%" cmd)
(uiop:run-program cmd :output t)))
(defun save-metadata (video-id video-json)
(with-open-file (f (format nil "~A.json" video-id)
:direction :output
:if-exists :supersede
:if-does-not-exist :create)
(write-string video-json f)))
(defun download-video-with-metadata (video-info)
(let* ((video-id (get-video-id video-info))
(video-json (get-video-json video-id))
(video-details (jonathan:parse video-json
:as :alist)))
(save-metadata video-id video-json)
(download-video video-details)))
(let ((i 0))
(loop while (< i *total*)
do
(let* ((url (format nil "https://~A/api/v1/accounts/~A/videos?start=~A&count=~A" *hostname* *username* i *count*))
(videos-json (dex:get url))
(videos-alist (jonathan:parse videos-json :as :alist))
(videos-info (assoc-value videos-alist "data" :test 'equal)))
(format t "*** i = ~A~%" i)
(loop for video-info in videos-info
do
(download-video-with-metadata video-info)))
(setq i (+ i *count*))))
Top comments (0)